[libvirt] [PATCH 10/11] util: Introduce virGetFCHostNameByFabricWWN

John Ferlan jferlan at redhat.com
Fri Nov 18 14:26:36 UTC 2016


Create a utility routine in order to read the scsi_host fabric_name files
looking for a match to a passed fabric_name

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 src/libvirt_private.syms |  1 +
 src/util/virutil.c       | 86 ++++++++++++++++++++++++++++++++++++++++--------
 src/util/virutil.h       |  4 +++
 3 files changed, 78 insertions(+), 13 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 5673bda..3921897 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2620,6 +2620,7 @@ virGetDeviceID;
 virGetDeviceUnprivSGIO;
 virGetEnvAllowSUID;
 virGetEnvBlockSUID;
+virGetFCHostNameByFabricWWN;
 virGetFCHostNameByWWN;
 virGetGroupID;
 virGetGroupList;
diff --git a/src/util/virutil.c b/src/util/virutil.c
index a135819..fb72f2d 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -2166,6 +2166,18 @@ virManageVport(const int parent_host,
     return ret;
 }
 
+# define READ_WWN(wwn_path, buf)                      \
+    do {                                              \
+        if (virFileReadAll(wwn_path, 1024, &buf) < 0) \
+            goto cleanup;                             \
+        if ((p = strchr(buf, '\n')))                  \
+            *p = '\0';                                \
+        if (STRPREFIX(buf, "0x"))                     \
+            p = buf + strlen("0x");                   \
+        else                                          \
+            p = buf;                                  \
+    } while (0)
+
 /* virGetFCHostNameByWWN:
  *
  * Iterate over the sysfs tree to get FC host name (e.g. host5)
@@ -2192,18 +2204,6 @@ virGetFCHostNameByWWN(const char *sysfs_prefix,
     if (virDirOpen(&dir, prefix) < 0)
         return NULL;
 
-# define READ_WWN(wwn_path, buf)                      \
-    do {                                              \
-        if (virFileReadAll(wwn_path, 1024, &buf) < 0) \
-            goto cleanup;                             \
-        if ((p = strchr(buf, '\n')))                  \
-            *p = '\0';                                \
-        if (STRPREFIX(buf, "0x"))                     \
-            p = buf + strlen("0x");                   \
-        else                                          \
-            p = buf;                                  \
-    } while (0)
-
     while (virDirRead(dir, &entry, prefix) > 0) {
         VIR_FREE(wwnn_buf);
         VIR_FREE(wwnn_path);
@@ -2239,7 +2239,6 @@ virGetFCHostNameByWWN(const char *sysfs_prefix,
     }
 
  cleanup:
-# undef READ_WWN
     VIR_DIR_CLOSE(dir);
     VIR_FREE(wwnn_path);
     VIR_FREE(wwpn_path);
@@ -2248,6 +2247,67 @@ virGetFCHostNameByWWN(const char *sysfs_prefix,
     return ret;
 }
 
+/* virGetFCHostNameByFabricWWN:
+ *
+ * Iterate over the sysfs tree to get FC host name (e.g. host5)
+ * by the provided "fabric_wwn". This would find a host on a SAN.
+ *
+ * Returns the FC host name which must be freed by the caller,
+ * or NULL on failure.
+ */
+char *
+virGetFCHostNameByFabricWWN(const char *sysfs_prefix,
+                            const char *fabric_wwn)
+{
+    const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH;
+    struct dirent *entry = NULL;
+    DIR *dir = NULL;
+    char *fabric_wwn_path = NULL;
+    char *fabric_wwn_buf = NULL;
+    char *vport_create_path = NULL;
+    char *p;
+    char *ret = NULL;
+
+    if (virDirOpen(&dir, prefix) < 0)
+        return NULL;
+
+    while (virDirRead(dir, &entry, prefix) > 0) {
+        VIR_FREE(fabric_wwn_path);
+        VIR_FREE(fabric_wwn_buf);
+        VIR_FREE(vport_create_path);
+
+        if (virAsprintf(&fabric_wwn_path, "%s/%s/fabric_name", prefix,
+                        entry->d_name) < 0)
+            goto cleanup;
+
+        /* Existing vHBA's will have the same fabric_name, but won't
+         * have the vport_create file - so we check for both */
+        if (virAsprintf(&vport_create_path, "%s/%s/vport_create", prefix,
+                        entry->d_name) < 0)
+            goto cleanup;
+
+        if (!virFileExists(fabric_wwn_path) ||
+            !virFileExists(vport_create_path))
+            continue;
+
+        READ_WWN(fabric_wwn_path, fabric_wwn_buf);
+
+        if (STRNEQ(fabric_wwn, p))
+            continue;
+
+        ignore_value(VIR_STRDUP(ret, entry->d_name));
+        break;
+    }
+
+ cleanup:
+    VIR_DIR_CLOSE(dir);
+    VIR_FREE(fabric_wwn_path);
+    VIR_FREE(fabric_wwn_buf);
+    VIR_FREE(vport_create_path);
+    return ret;
+}
+# undef READ_WWN
+
 # define PORT_STATE_ONLINE "Online"
 
 /* virFindFCHostCapableVport:
diff --git a/src/util/virutil.h b/src/util/virutil.h
index 8c0d83c..3fbd7b0 100644
--- a/src/util/virutil.h
+++ b/src/util/virutil.h
@@ -206,6 +206,10 @@ char *virGetFCHostNameByWWN(const char *sysfs_prefix,
                             const char *wwpn)
     ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 
+char *virGetFCHostNameByFabricWWN(const char *sysfs_prefix,
+                                  const char *fabric_wwn)
+    ATTRIBUTE_NONNULL(2);
+
 char *virFindFCHostCapableVport(const char *sysfs_prefix);
 
 int virParseOwnershipIds(const char *label, uid_t *uidPtr, gid_t *gidPtr);
-- 
2.7.4




More information about the libvir-list mailing list