]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
include/sysfs: add SCSI host:channel:target:lun support
authorKarel Zak <kzak@redhat.com>
Tue, 23 Oct 2012 08:57:59 +0000 (10:57 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 23 Oct 2012 10:15:58 +0000 (12:15 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
include/sysfs.h
lib/sysfs.c
misc-utils/lsblk.c

index 9e47a5571fdd94b4df48d0aa4c52893354ecbe3b..10875d4214d3eccfa54fed307ddcaa7483e5af6d 100644 (file)
@@ -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 */
index 1384acda6110cb08618e7d9ce17677b5151fa88e..4cb6284ca53fbc8aeadee5bea483f7f9e5838466 100644 (file)
@@ -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>
index 547723c68081d8872e53a888dac38d036caa1672..c3803d826a936f891cf534b4d24f278454624a9a 100644 (file)
@@ -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));
                }