From d0f7e5b4a0a1b83e515c9fd894d74ed36d7da5c1 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 23 Oct 2012 10:57:59 +0200 Subject: [PATCH] include/sysfs: add SCSI host:channel:target:lun support Signed-off-by: Karel Zak --- include/sysfs.h | 11 +++++++++++ lib/sysfs.c | 42 +++++++++++++++++++++++++++++++++++++++--- misc-utils/lsblk.c | 25 ++----------------------- 3 files changed, 52 insertions(+), 26 deletions(-) diff --git a/include/sysfs.h b/include/sysfs.h index 9e47a5571..10875d421 100644 --- a/include/sysfs.h +++ b/include/sysfs.h @@ -21,6 +21,13 @@ struct sysfs_cxt { int dir_fd; /* /sys/block/ */ char *dir_path; struct sysfs_cxt *parent; + + unsigned int scsi_host, + scsi_channel, + scsi_target, + scsi_lun; + + unsigned int has_hctl : 1; }; #define UL_SYSFSCXT_EMPTY { 0, -1, NULL, NULL } @@ -65,4 +72,8 @@ extern int sysfs_is_partition_dirent(DIR *dir, struct dirent *d, extern int sysfs_devno_to_wholedisk(dev_t dev, char *diskname, size_t len, dev_t *diskdevno); + +extern int sysfs_scsi_get_hctl(struct sysfs_cxt *cxt, int *h, + int *c, int *t, int *l); + #endif /* UTIL_LINUX_SYSFS_H */ diff --git a/lib/sysfs.c b/lib/sysfs.c index 1384acda6..4cb6284ca 100644 --- a/lib/sysfs.c +++ b/lib/sysfs.c @@ -173,10 +173,9 @@ void sysfs_deinit(struct sysfs_cxt *cxt) close(cxt->dir_fd); free(cxt->dir_path); - cxt->devno = 0; + memset(cxt, 0, sizeof(*cxt)); + cxt->dir_fd = -1; - cxt->parent = NULL; - cxt->dir_path = NULL; } int sysfs_stat(struct sysfs_cxt *cxt, const char *attr, struct stat *st) @@ -636,6 +635,43 @@ err: return -1; } + +int sysfs_scsi_get_hctl(struct sysfs_cxt *cxt, int *h, int *c, int *t, int *l) +{ + char buf[PATH_MAX], *hctl; + ssize_t len; + + if (!cxt) + return -EINVAL; + if (cxt->has_hctl) + goto done; + + len = sysfs_readlink(cxt, "device", buf, sizeof(buf)); + if (len < 0) + return len; + + buf[len] = '\0'; + hctl = strrchr(buf, '/') + 1; + if (!hctl) + return -1; + + if (sscanf(hctl, "%d:%d:%d:%d", &cxt->scsi_host, &cxt->scsi_channel, + &cxt->scsi_target, &cxt->scsi_lun) != 4) + return -1; + + cxt->has_hctl = 1; +done: + if (h) + *h = cxt->scsi_host; + if (c) + *c = cxt->scsi_channel; + if (t) + *t = cxt->scsi_target; + if (l) + *l = cxt->scsi_lun; + return 0; +} + #ifdef TEST_PROGRAM_SYSFS #include #include diff --git a/misc-utils/lsblk.c b/misc-utils/lsblk.c index 547723c68..c3803d826 100644 --- a/misc-utils/lsblk.c +++ b/misc-utils/lsblk.c @@ -577,27 +577,6 @@ static char *get_type(struct blkdev_cxt *cxt) return res; } -/* H:C:T:L - Host:Channel:Target:LUN */ -static int get_hctl(struct blkdev_cxt *cxt, int *h, int *c, int *t, int *l) -{ - char buf[PATH_MAX], *hctl; - ssize_t len; - - len = sysfs_readlink(&cxt->sysfs, "device", buf, sizeof(buf)); - if (len < 0) - return 0; - - buf[len] = '\0'; - hctl = strrchr(buf, '/') + 1; - if (!hctl) - return 0; - - if (sscanf(hctl, "%d:%d:%d:%d", h, c, t, l) != 4) - return 0; - - return 1; -} - static char *_sysfs_host_string(const char *type, int host, const char *attr) { char path[PATH_MAX], tmp[64] = {0}; @@ -671,7 +650,7 @@ static char *get_transport(struct blkdev_cxt *cxt) int host, channel, target, lun; char *attr; - if (!get_hctl(cxt, &host, &channel, &target, &lun)) + if (sysfs_scsi_get_hctl(&cxt->sysfs, &host, &channel, &target, &lun) != 0) return NULL; /* SPI - Serial Peripheral Interface */ @@ -923,7 +902,7 @@ static void set_tt_data(struct blkdev_cxt *cxt, int col, int id, struct tt_line case COL_HCTL: { int h, c, t, l; - if (get_hctl(cxt, &h, &c, &t, &l)) { + if (sysfs_scsi_get_hctl(&cxt->sysfs, &h, &c, &t, &l) == 0) { snprintf(buf, sizeof(buf), "%d:%d:%d:%d", h, c, t, l); tt_line_set_data(ln, col, xstrdup(buf)); }