[libvirt] [PATCH v2 1/2] nodedev: Fabric name must not be required for fc_host capability

Boris Fiuczynski fiuczy at linux.vnet.ibm.com
Fri Jan 13 11:56:06 UTC 2017


fabric_name is one of many fc_host attributes in Linux that is optional
and left to the low-level driver to decide if it is implemented.
The zfcp device driver does not provide a fabric name for an fcp host.

This patch removes the requirement for a fabric name by making it optional.

Signed-off-by: Boris Fiuczynski <fiuczy at linux.vnet.ibm.com>
---
 docs/formatnode.html.in                   |  2 +-
 docs/news.xml                             | 12 +++++++++
 docs/schemas/nodedev.rng                  |  8 +++---
 src/libvirt_private.syms                  |  1 +
 src/node_device/node_device_linux_sysfs.c |  6 ++---
 src/util/virutil.c                        | 23 ++++++++++++++++
 src/util/virutil.h                        |  5 ++++
 tests/fchostdata/fc_host/host6/node_name  |  1 +
 tests/fchostdata/fc_host/host6/port_name  |  1 +
 tests/fchostdata/fc_host/host6/port_state |  1 +
 tests/fchosttest.c                        | 44 ++++++++++++++++++++++++++++---
 11 files changed, 94 insertions(+), 10 deletions(-)
 create mode 100644 tests/fchostdata/fc_host/host6/node_name
 create mode 100644 tests/fchostdata/fc_host/host6/port_name
 create mode 100644 tests/fchostdata/fc_host/host6/port_state

diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in
index e7b1140..f8d0e12 100644
--- a/docs/formatnode.html.in
+++ b/docs/formatnode.html.in
@@ -254,7 +254,7 @@
                 number of vport in use. <code>max_vports</code> shows the
                 maximum vports the HBA supports. "fc_host" implies following
                 sub-elements: <code>wwnn</code>, <code>wwpn</code>, and
-                <code>fabric_wwn</code>.
+                optionally <code>fabric_wwn</code>.
               </dd>
             </dl>
           </dd>
diff --git a/docs/news.xml b/docs/news.xml
index 50c3b3e..a645953 100644
--- a/docs/news.xml
+++ b/docs/news.xml
@@ -144,6 +144,18 @@
     <section title="Bug fixes">
       <change>
         <summary>
+          nodedev: Fabric name must not be required for fc_host capability
+        </summary>
+        <description>
+          fabric_name is one of many fc_host attributes in Linux that is
+          optional and left to the low-level driver to decide if it is
+          implemented. For example the zfcp device driver does not provide a
+          fabric name for an fcp host. The requirement for the existence of
+          a fabric name has been removed by making it optional.
+        </description>
+      </change>
+      <change>
+        <summary>
           qemu: Correct GetBlockInfo values
         </summary>
         <description>
diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng
index 9c98402..b100a6e 100644
--- a/docs/schemas/nodedev.rng
+++ b/docs/schemas/nodedev.rng
@@ -367,9 +367,11 @@
       <ref name='wwn'/>
     </element>
 
-    <element name='fabric_wwn'>
-      <ref name='wwn'/>
-    </element>
+    <optional>
+      <element name='fabric_wwn'>
+        <ref name='wwn'/>
+      </element>
+    </optional>
   </define>
 
   <define name='capsvports'>
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 70ed87b..43f460f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2717,6 +2717,7 @@ virParseOwnershipIds;
 virParseVersionString;
 virPipeReadUntilEOF;
 virReadFCHost;
+virReadFCHostOption;
 virReadSCSIUniqueId;
 virScaleInteger;
 virSetBlocking;
diff --git a/src/node_device/node_device_linux_sysfs.c b/src/node_device/node_device_linux_sysfs.c
index be99c41..1bb5b74 100644
--- a/src/node_device/node_device_linux_sysfs.c
+++ b/src/node_device/node_device_linux_sysfs.c
@@ -72,10 +72,10 @@ nodeDeviceSysfsGetSCSIHostCaps(virNodeDevCapDataPtr d)
         VIR_FREE(d->scsi_host.wwnn);
         VIR_STEAL_PTR(d->scsi_host.wwnn, tmp);
 
-        if (!(tmp = virReadFCHost(NULL, d->scsi_host.host, "fabric_name"))) {
-            VIR_WARN("Failed to read fabric WWN for host%d",
+        if (!(tmp = virReadFCHostOption(NULL, d->scsi_host.host,
+                                        "fabric_name", false))) {
+            VIR_INFO("Optional fabric WWN for host%d not available",
                      d->scsi_host.host);
-            goto cleanup;
         }
         VIR_FREE(d->scsi_host.fabric_wwn);
         VIR_STEAL_PTR(d->scsi_host.fabric_wwn, tmp);
diff --git a/src/util/virutil.c b/src/util/virutil.c
index aeaa7f9..5bfbf37 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -2019,6 +2019,26 @@ virReadFCHost(const char *sysfs_prefix,
               int host,
               const char *entry)
 {
+   return virReadFCHostOption(sysfs_prefix, host, entry, true);
+}
+
+/* virReadFCHostOption:
+ * @sysfs_prefix: "fc_host" sysfs path, defaults to SYSFS_FC_HOST_PATH
+ * @host: Host number, E.g. 5 of "fc_host/host5"
+ * @entry: Name of the sysfs entry to read
+ * @required: If true reports error when entry not found else no error
+ *
+ * Read the value of sysfs "fc_host" entry.
+ *
+ * Returns result as a string on success, caller must free @result after
+ * Otherwise returns NULL.
+ */
+char *
+virReadFCHostOption(const char *sysfs_prefix,
+                    int host,
+                    const char *entry,
+                    bool required)
+{
     char *sysfs_path = NULL;
     char *p = NULL;
     char *buf = NULL;
@@ -2029,6 +2049,9 @@ virReadFCHost(const char *sysfs_prefix,
                     host, entry) < 0)
         goto cleanup;
 
+    if (!required && !virFileExists(sysfs_path))
+        goto cleanup;
+
     if (virFileReadAll(sysfs_path, 1024, &buf) < 0)
         goto cleanup;
 
diff --git a/src/util/virutil.h b/src/util/virutil.h
index 3fbd7b0..db86052 100644
--- a/src/util/virutil.h
+++ b/src/util/virutil.h
@@ -186,6 +186,11 @@ char *virReadFCHost(const char *sysfs_prefix,
                     int host,
                     const char *entry)
     ATTRIBUTE_NONNULL(3);
+char *virReadFCHostOption(const char *sysfs_prefix,
+                          int host,
+                          const char *entry,
+                          bool required)
+    ATTRIBUTE_NONNULL(3);
 
 bool virIsCapableFCHost(const char *sysfs_prefix, int host);
 bool virIsCapableVport(const char *sysfs_prefix, int host);
diff --git a/tests/fchostdata/fc_host/host6/node_name b/tests/fchostdata/fc_host/host6/node_name
new file mode 100644
index 0000000..73a91bd
--- /dev/null
+++ b/tests/fchostdata/fc_host/host6/node_name
@@ -0,0 +1 @@
+0x2002001b32a9da4e
diff --git a/tests/fchostdata/fc_host/host6/port_name b/tests/fchostdata/fc_host/host6/port_name
new file mode 100644
index 0000000..f25abeb
--- /dev/null
+++ b/tests/fchostdata/fc_host/host6/port_name
@@ -0,0 +1 @@
+0x2102001b32a9da4e
diff --git a/tests/fchostdata/fc_host/host6/port_state b/tests/fchostdata/fc_host/host6/port_state
new file mode 100644
index 0000000..b73dd46
--- /dev/null
+++ b/tests/fchostdata/fc_host/host6/port_state
@@ -0,0 +1 @@
+Online
diff --git a/tests/fchosttest.c b/tests/fchosttest.c
index a08a2e8..01c20df 100644
--- a/tests/fchosttest.c
+++ b/tests/fchosttest.c
@@ -29,13 +29,16 @@ static char *fchost_prefix;
 
 #define TEST_FC_HOST_PREFIX fchost_prefix
 #define TEST_FC_HOST_NUM 5
+#define TEST_FC_HOST_NUM_NO_FAB 6
 
 /* Test virIsCapableFCHost */
 static int
 test1(const void *data ATTRIBUTE_UNUSED)
 {
     if (virIsCapableFCHost(TEST_FC_HOST_PREFIX,
-                           TEST_FC_HOST_NUM))
+                           TEST_FC_HOST_NUM) &&
+        virIsCapableFCHost(TEST_FC_HOST_PREFIX,
+                           TEST_FC_HOST_NUM_NO_FAB))
         return 0;
 
     return -1;
@@ -76,8 +79,8 @@ test3(const void *data ATTRIBUTE_UNUSED)
                                "port_name")))
         goto cleanup;
 
-    if (!(fabric_wwn = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM,
-                                     "fabric_name")))
+    if (!(fabric_wwn = virReadFCHostOption(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM,
+                                           "fabric_name", false)))
         goto cleanup;
 
     if (!(max_vports = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM,
@@ -148,6 +151,39 @@ test5(const void *data ATTRIBUTE_UNUSED)
     return ret;
 }
 
+/* Test virReadFCHost fabric name optional */
+static int
+test6(const void *data ATTRIBUTE_UNUSED)
+{
+    const char *expect_wwnn = "2002001b32a9da4e";
+    const char *expect_wwpn = "2102001b32a9da4e";
+    char *wwnn = NULL;
+    char *wwpn = NULL;
+    int ret = -1;
+
+    if (!(wwnn = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM_NO_FAB,
+                               "node_name")))
+        return -1;
+
+    if (!(wwpn = virReadFCHost(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM_NO_FAB,
+                               "port_name")))
+        goto cleanup;
+
+    if (virReadFCHostOption(TEST_FC_HOST_PREFIX, TEST_FC_HOST_NUM_NO_FAB,
+                            "fabric_name", false))
+        goto cleanup;
+
+    if (STRNEQ(expect_wwnn, wwnn) ||
+        STRNEQ(expect_wwpn, wwpn))
+        goto cleanup;
+
+    ret = 0;
+ cleanup:
+    VIR_FREE(wwnn);
+    VIR_FREE(wwpn);
+    return ret;
+}
+
 static int
 mymain(void)
 {
@@ -169,6 +205,8 @@ mymain(void)
         ret = -1;
     if (virTestRun("test5", test5, NULL) < 0)
         ret = -1;
+    if (virTestRun("test6", test6, NULL) < 0)
+        ret = -1;
 
  cleanup:
     VIR_FREE(fchost_prefix);
-- 
2.5.5




More information about the libvir-list mailing list