]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/sysfs: add SCSI link functions
authorKarel Zak <kzak@redhat.com>
Tue, 23 Oct 2012 10:12:07 +0000 (12:12 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 23 Oct 2012 10:21:23 +0000 (12:21 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
include/pathnames.h
include/sysfs.h
lib/sysfs.c

index d0ed7a1584506211c17e4960a7e53997c4fc075a..58bba519a37fecc28954285b9f7206926ee08833 100644 (file)
@@ -86,6 +86,8 @@
 
 #define _PATH_SYS_BLOCK                "/sys/block"
 #define _PATH_SYS_DEVBLOCK     "/sys/dev/block"
+#define _PATH_SYS_CLASS                "/sys/class"
+#define _PATH_SYS_SCSI         "/sys/bus/scsi"
 
 #ifndef _PATH_MOUNTED
 # ifdef MOUNTED                                        /* deprecated */
index f0d33611ec9fac0b980a72095aace624dfc05bcd..4f9c46bb373649b75d2c679c7067e802824e1ce8 100644 (file)
@@ -78,5 +78,7 @@ extern int sysfs_scsi_get_hctl(struct sysfs_cxt *cxt, int *h,
 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);
+extern int sysfs_scsi_has_attribute(struct sysfs_cxt *cxt, const char *attr);
+extern int sysfs_scsi_path_contains(struct sysfs_cxt *cxt, const char *pattern);
 
 #endif /* UTIL_LINUX_SYSFS_H */
index d0c6c8944e7accc8c791a86933333d8a000bca36..29bde82d0a02a50f798f552bae18a4b8b825ca0c 100644 (file)
@@ -683,10 +683,10 @@ static char *sysfs_scsi_host_attribute_path(struct sysfs_cxt *cxt,
                return NULL;
 
        if (attr)
-               len = snprintf(buf, bufsz, "/sys/class/%s_host/host%d/%s",
+               len = snprintf(buf, bufsz, _PATH_SYS_CLASS "/%s_host/host%d/%s",
                                type, host, attr);
        else
-               len = snprintf(buf, bufsz, "/sys/class/%s_host/host%d",
+               len = snprintf(buf, bufsz, _PATH_SYS_CLASS "/%s_host/host%d",
                                type, host);
 
        return (len < 0 || (size_t) len + 1 > bufsz) ? NULL : buf;
@@ -724,6 +724,54 @@ int sysfs_scsi_host_is(struct sysfs_cxt *cxt, const char *type)
        return stat(buf, &st) == 0 && S_ISDIR(st.st_mode);
 }
 
+static char *sysfs_scsi_attribute_path(struct sysfs_cxt *cxt,
+               char *buf, size_t bufsz, const char *attr)
+{
+       int len, h, c, t, l;
+
+       if (sysfs_scsi_get_hctl(cxt, &h, &c, &t, &l) != 0)
+               return NULL;
+
+       if (attr)
+               len = snprintf(buf, bufsz, _PATH_SYS_SCSI "/devices/%d:%d:%d:%d/%s",
+                               h,c,t,l, attr);
+       else
+               len = snprintf(buf, bufsz, _PATH_SYS_SCSI "/devices/%d:%d:%d:%d",
+                               h,c,t,l);
+       return (len < 0 || (size_t) len + 1 > bufsz) ? NULL : buf;
+}
+
+int sysfs_scsi_has_attribute(struct sysfs_cxt *cxt, const char *attr)
+{
+       char path[PATH_MAX];
+       struct stat st;
+
+       if (!sysfs_scsi_attribute_path(cxt, path, sizeof(path), attr))
+               return 0;
+
+       return stat(path, &st) == 0;
+}
+
+int sysfs_scsi_path_contains(struct sysfs_cxt *cxt, const char *pattern)
+{
+       char path[PATH_MAX], linkc[PATH_MAX];
+       struct stat st;
+       ssize_t len;
+
+       if (!sysfs_scsi_attribute_path(cxt, path, sizeof(path), NULL))
+               return 0;
+
+       if (stat(path, &st) != 0)
+               return 0;
+
+       len = readlink(path, linkc, sizeof(linkc) - 1);
+       if (len < 0)
+               return 0;
+
+       linkc[len] = '\0';
+       return strstr(linkc, pattern) != NULL;
+}
+
 #ifdef TEST_PROGRAM_SYSFS
 #include <errno.h>
 #include <err.h>