]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/sysfs: add functions for SCSI host attributes
authorKarel Zak <kzak@redhat.com>
Tue, 23 Oct 2012 09:32:55 +0000 (11:32 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 23 Oct 2012 10:18:57 +0000 (12:18 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
include/sysfs.h
lib/sysfs.c
misc-utils/lsblk.c

index 10875d4214d3eccfa54fed307ddcaa7483e5af6d..f0d33611ec9fac0b980a72095aace624dfc05bcd 100644 (file)
@@ -75,5 +75,8 @@ extern int sysfs_devno_to_wholedisk(dev_t dev, char *diskname,
 
 extern int sysfs_scsi_get_hctl(struct sysfs_cxt *cxt, int *h,
                               int *c, int *t, int *l);
+extern char *sysfs_scsi_host_strdup_attribute(struct sysfs_cxt *cxt,
+                const char *type, const char *attr);
+extern int sysfs_scsi_host_is(struct sysfs_cxt *cxt, const char *type);
 
 #endif /* UTIL_LINUX_SYSFS_H */
index 4cb6284ca53fbc8aeadee5bea483f7f9e5838466..d0c6c8944e7accc8c791a86933333d8a000bca36 100644 (file)
@@ -672,6 +672,58 @@ done:
        return 0;
 }
 
+
+static char *sysfs_scsi_host_attribute_path(struct sysfs_cxt *cxt,
+               const char *type, char *buf, size_t bufsz, const char *attr)
+{
+       int len;
+       int host;
+
+       if (sysfs_scsi_get_hctl(cxt, &host, NULL, NULL, NULL))
+               return NULL;
+
+       if (attr)
+               len = snprintf(buf, bufsz, "/sys/class/%s_host/host%d/%s",
+                               type, host, attr);
+       else
+               len = snprintf(buf, bufsz, "/sys/class/%s_host/host%d",
+                               type, host);
+
+       return (len < 0 || (size_t) len + 1 > bufsz) ? NULL : buf;
+}
+
+char *sysfs_scsi_host_strdup_attribute(struct sysfs_cxt *cxt,
+               const char *type, const char *attr)
+{
+       char buf[1024];
+       int rc;
+       FILE *f;
+
+       if (!attr || !type ||
+           !sysfs_scsi_host_attribute_path(cxt, type, buf, sizeof(buf), attr))
+               return NULL;
+
+       if (!(f = fopen(buf, "r")))
+                return NULL;
+
+       rc = fscanf(f, "%1023[^\n]", buf);
+       fclose(f);
+
+       return rc == 1 ? strdup(buf) : NULL;
+}
+
+int sysfs_scsi_host_is(struct sysfs_cxt *cxt, const char *type)
+{
+       char buf[PATH_MAX];
+       struct stat st;
+
+       if (!type || !sysfs_scsi_host_attribute_path(cxt, type,
+                               buf, sizeof(buf), NULL))
+               return 0;
+
+       return stat(buf, &st) == 0 && S_ISDIR(st.st_mode);
+}
+
 #ifdef TEST_PROGRAM_SYSFS
 #include <errno.h>
 #include <err.h>
index c3803d826a936f891cf534b4d24f278454624a9a..1042704186cb0cd8b3ec933e36af97fa91c4e01b 100644 (file)
@@ -577,40 +577,6 @@ static char *get_type(struct blkdev_cxt *cxt)
        return res;
 }
 
-static char *_sysfs_host_string(const char *type, int host, const char *attr)
-{
-       char path[PATH_MAX], tmp[64] = {0};
-       int fd, r;
-
-       if (snprintf(path, sizeof(path), "/sys/class/%s_host/host%d/%s",
-                       type, host, attr) < 0)
-               return NULL;
-       if ((fd = open(path, O_RDONLY)) < 0)
-                return NULL;
-       r = read(fd, tmp, sizeof(tmp));
-       close(fd);
-
-       if (r <= 0)
-               return NULL;
-
-       return xstrdup(tmp);
-}
-
-static int _sysfs_host_exists(const char *type, int host)
-{
-       char buf[PATH_MAX];
-       struct stat st;
-
-       if (snprintf(buf, sizeof(buf), "/sys/class/%s_host/host%d",
-                    type, host) < 0)
-               return 0;
-
-       if (!stat(buf, &st) && S_ISDIR(st.st_mode))
-               return 1;
-
-       return 0;
-}
-
 static int _sysfs_scsi_attr_exists(const char *attr, int h, int c, int t, int l)
 {
        char buf[PATH_MAX];
@@ -647,19 +613,21 @@ static int _sysfs_scsi_path_contains(const char *pattern, int h, int c, int t, i
 /* Thanks to lsscsi code for idea of detection logic used here */
 static char *get_transport(struct blkdev_cxt *cxt)
 {
+       struct sysfs_cxt *sysfs = &cxt->sysfs;
        int host, channel, target, lun;
        char *attr;
 
-       if (sysfs_scsi_get_hctl(&cxt->sysfs, &host, &channel, &target, &lun) != 0)
+       if (sysfs_scsi_get_hctl(sysfs, &host, &channel, &target, &lun) != 0)
                return NULL;
 
        /* SPI - Serial Peripheral Interface */
-       if (_sysfs_host_exists("spi", host))
+       if (sysfs_scsi_host_is(sysfs, "spi"))
                return xstrdup("spi");
 
        /* FC/FCoE - Fibre Channel / Fibre Channel over Ethernet */
-       if (_sysfs_host_exists("fc", host)) {
-               if (!(attr = _sysfs_host_string("fc", host, "symbolic_name")))
+       if (sysfs_scsi_host_is(sysfs, "fc")) {
+               attr = sysfs_scsi_host_strdup_attribute(sysfs, "fc", "symbolic_name");
+               if (!attr)
                        return NULL;
                if (strstr(attr, " over "))
                        return xstrdup("fcoe");
@@ -667,7 +635,7 @@ static char *get_transport(struct blkdev_cxt *cxt)
        }
 
        /* SAS - Serial Attached SCSI */
-       if (_sysfs_host_exists("sas", host))
+       if (sysfs_scsi_host_is(sysfs, "sas"))
                return xstrdup("sas");
 
        if (_sysfs_scsi_attr_exists("sas_device", host, channel, target, lun))
@@ -678,7 +646,7 @@ static char *get_transport(struct blkdev_cxt *cxt)
                return xstrdup("sbp");
 
        /* iSCSI */
-       if (_sysfs_host_exists("iscsi", host))
+       if (sysfs_scsi_host_is(sysfs, "iscsi"))
                return xstrdup("iscsi");
 
        /* USB - Universal Serial Bus */
@@ -686,8 +654,9 @@ static char *get_transport(struct blkdev_cxt *cxt)
                return xstrdup("usb");
 
        /* ATA, SATA */
-       if (_sysfs_host_exists("scsi", host)) {
-               if (!(attr = _sysfs_host_string("scsi", host, "proc_name")))
+       if (sysfs_scsi_host_is(sysfs, "scsi")) {
+               attr = sysfs_scsi_host_strdup_attribute(sysfs, "scsi", "proc_name");
+               if (!attr)
                        return NULL;
                if (!strncmp(attr, "ahci", 4) ||
                    !strncmp(attr, "sata", 4))