summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sysfs.h11
-rw-r--r--lib/sysfs.c42
-rw-r--r--misc-utils/lsblk.c25
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/<name> */
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 <errno.h>
#include <err.h>
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));
}