]> xenbits.xensource.com Git - libvirt.git/commitdiff
util: Introduce virGetFCHostNameByFabricWWN
authorJohn Ferlan <jferlan@redhat.com>
Fri, 18 Nov 2016 12:36:18 +0000 (07:36 -0500)
committerJohn Ferlan <jferlan@redhat.com>
Fri, 6 Jan 2017 22:15:34 +0000 (17:15 -0500)
Create a utility routine in order to read the scsi_host fabric_name files
looking for a match to a passed fabric_name

src/libvirt_private.syms
src/util/virutil.c
src/util/virutil.h

index 8e4e52d1cae01ec9c5ab32094528ae799f512212..c5b9cee45e067a653aedf84a6baa8b4062319e17 100644 (file)
@@ -2667,6 +2667,7 @@ virGetDeviceID;
 virGetDeviceUnprivSGIO;
 virGetEnvAllowSUID;
 virGetEnvBlockSUID;
+virGetFCHostNameByFabricWWN;
 virGetFCHostNameByWWN;
 virGetGroupID;
 virGetGroupList;
index 701c382a5dde46812ecb187b9c71548f77d1e815..da836b46d3d5669442971d11a5f8f3170c6839b6 100644 (file)
@@ -2166,6 +2166,60 @@ virManageVport(const int parent_host,
     return ret;
 }
 
+
+/* virReadCompareWWN
+ * @prefix: path to the wwn file
+ * @d_name: name of the current directory
+ * @f_name: file name to read
+ *
+ * Read/compare the on-disk file with the passed wwn value.
+ *
+ * Returns:
+ *   -1 : Error
+ *    0 : No match
+ *    1 : Match
+ */
+static int
+virReadCompareWWN(const char *prefix,
+                  const char *d_name,
+                  const char *f_name,
+                  const char *wwn)
+{
+    char *path;
+    char *buf = NULL;
+    char *p;
+    int ret = -1;
+
+    if (virAsprintf(&path, "%s/%s/%s", prefix, d_name, f_name) < 0)
+        return -1;
+
+    if (!virFileExists(path)) {
+        ret = 0;
+        goto cleanup;
+    }
+
+    if (virFileReadAll(path, 1024, &buf) < 0)
+        goto cleanup;
+
+    if ((p = strchr(buf, '\n')))
+        *p = '\0';
+    if (STRPREFIX(buf, "0x"))
+        p = buf + strlen("0x");
+    else
+        p = buf;
+
+    if (STRNEQ(wwn, p))
+        ret = 0;
+    else
+        ret = 1;
+
+ cleanup:
+    VIR_FREE(path);
+    VIR_FREE(buf);
+
+    return ret;
+}
+
 /* virGetFCHostNameByWWN:
  *
  * Iterate over the sysfs tree to get FC host name (e.g. host5)
@@ -2182,56 +2236,77 @@ virGetFCHostNameByWWN(const char *sysfs_prefix,
     const char *prefix = sysfs_prefix ? sysfs_prefix : SYSFS_FC_HOST_PATH;
     struct dirent *entry = NULL;
     DIR *dir = NULL;
-    char *wwnn_path = NULL;
-    char *wwpn_path = NULL;
-    char *wwnn_buf = NULL;
-    char *wwpn_buf = NULL;
-    char *p;
     char *ret = NULL;
 
     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);
-        VIR_FREE(wwpn_buf);
-        VIR_FREE(wwpn_path);
+        int rc;
 
-        if (virAsprintf(&wwnn_path, "%s/%s/node_name", prefix,
-                        entry->d_name) < 0)
+        if ((rc = virReadCompareWWN(prefix, entry->d_name,
+                                    "node_name", wwnn)) < 0)
             goto cleanup;
 
-        if (!virFileExists(wwnn_path))
+        if (rc == 0)
             continue;
 
-        READ_WWN(wwnn_path, wwnn_buf);
+        if ((rc = virReadCompareWWN(prefix, entry->d_name,
+                                    "port_name", wwpn)) < 0)
+            goto cleanup;
 
-        if (STRNEQ(wwnn, p))
+        if (rc == 0)
             continue;
 
-        if (virAsprintf(&wwpn_path, "%s/%s/port_name", prefix,
+        ignore_value(VIR_STRDUP(ret, entry->d_name));
+        break;
+    }
+
+ cleanup:
+    VIR_DIR_CLOSE(dir);
+    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 *vport_create_path = NULL;
+    char *ret = NULL;
+
+    if (virDirOpen(&dir, prefix) < 0)
+        return NULL;
+
+    while (virDirRead(dir, &entry, prefix) > 0) {
+        int rc;
+
+        VIR_FREE(vport_create_path);
+
+        /* 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(wwpn_path))
+        if (!virFileExists(vport_create_path))
             continue;
 
-        READ_WWN(wwpn_path, wwpn_buf);
+        if ((rc = virReadCompareWWN(prefix, entry->d_name,
+                                    "fabric_name", fabric_wwn)) < 0)
+            goto cleanup;
 
-        if (STRNEQ(wwpn, p))
+        if (rc == 0)
             continue;
 
         ignore_value(VIR_STRDUP(ret, entry->d_name));
@@ -2239,12 +2314,8 @@ virGetFCHostNameByWWN(const char *sysfs_prefix,
     }
 
  cleanup:
-# undef READ_WWN
     VIR_DIR_CLOSE(dir);
-    VIR_FREE(wwnn_path);
-    VIR_FREE(wwpn_path);
-    VIR_FREE(wwnn_buf);
-    VIR_FREE(wwpn_buf);
+    VIR_FREE(vport_create_path);
     return ret;
 }
 
index 8c0d83c9a5748e9c54aa96f9149c7e671cd9beb4..3fbd7b0688a0390781dc5c32a511497df7fcefc6 100644 (file)
@@ -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);