[libvirt] [PATCH 6/9 v2] nodedev: Dump max vports and vports in use for HBA's XML

Osier Yang jyang at redhat.com
Tue Jan 15 09:38:01 UTC 2013


This enrichs HBA's xml by dumping the number of max vports and
vports in use. Format is like:

  <capability type='vport_ops'>
    <max_vports>164</max_vports>
    <vports>5</vports>
  </capability>

* docs/formatnode.html.in: (Document the new XML)
* docs/schemas/nodedev.rng: (Add the schema)
* src/conf/node_device_conf.h: (New member for data.scsi_host)
* src/node_device/node_device_linux_sysfs.c: (Collect the value of
  max_vports and vports)
---
 docs/formatnode.html.in                   |   10 ++++--
 docs/schemas/nodedev.rng                  |    6 +++
 src/conf/node_device_conf.c               |    7 +++-
 src/conf/node_device_conf.h               |    2 +
 src/node_device/node_device_linux_sysfs.c |   49 ++++++++++++++++++++++++++--
 5 files changed, 66 insertions(+), 8 deletions(-)

diff --git a/docs/formatnode.html.in b/docs/formatnode.html.in
index fcaaaaf..5712bcf 100644
--- a/docs/formatnode.html.in
+++ b/docs/formatnode.html.in
@@ -136,9 +136,13 @@
               <dd>The SCSI host number.</dd>
               <dt><code>capability</code></dt>
               <dd>Current capabilities include "vports_ops" (indicates
-                vport operations are supported) and "fc_host", the later
-                implies following sub-elements: <code>wwnn</code>,
-                <code>wwpn</code>, <code>fabric_wwn</code>.
+                vport operations are supported) and "fc_host". "vport_ops"
+                could contain two optional sub-elements: <code>vports</code>,
+                and <code>max_vports</code>. <code>vports</code> shows the
+                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>.
               </dd>
             </dl>
           </dd>
diff --git a/docs/schemas/nodedev.rng b/docs/schemas/nodedev.rng
index 7c85815..b94cce6 100644
--- a/docs/schemas/nodedev.rng
+++ b/docs/schemas/nodedev.rng
@@ -267,6 +267,12 @@
     <attribute name='type'>
       <value>vports_ops</value>
     </attribute>
+    <element name='max_vports'>
+      <ref name='unsignedInt'/>
+    </element>
+    <element name='vports'>
+      <ref name='unsignedInt'/>
+    </element>
   </define>
 
   <define name='capscsihost'>
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index 819e6af..5962d58 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -392,7 +392,12 @@ char *virNodeDeviceDefFormat(const virNodeDeviceDefPtr def)
                 virBufferAddLit(&buf, "    </capability>\n");
             }
             if (data->scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS) {
-                virBufferAddLit(&buf, "    <capability type='vport_ops' />\n");
+                virBufferAddLit(&buf, "    <capability type='vport_ops'>\n");
+                virBufferAsprintf(&buf, "      <max_vports>%d</max_vports>\n",
+                                  data->scsi_host.max_vports);
+                virBufferAsprintf(&buf, "      <vports>%d</vports>\n",
+                                  data->scsi_host.vports);
+                virBufferAddLit(&buf, "    </capability>\n");
             }
 
             break;
diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h
index 145d699..4e584a3 100644
--- a/src/conf/node_device_conf.h
+++ b/src/conf/node_device_conf.h
@@ -137,6 +137,8 @@ struct _virNodeDevCapsDef {
             char *wwpn;
             char *fabric_wwn;
             unsigned int flags;
+            int max_vports;
+            int vports;
         } scsi_host;
         struct {
             char *name;
diff --git a/src/node_device/node_device_linux_sysfs.c b/src/node_device/node_device_linux_sysfs.c
index 85bbab6..a1c3637 100644
--- a/src/node_device/node_device_linux_sysfs.c
+++ b/src/node_device/node_device_linux_sysfs.c
@@ -40,6 +40,8 @@
 int
 detect_scsi_host_caps_linux(union _virNodeDevCapData *d)
 {
+    char *max_vports = NULL;
+    char *vports = NULL;
     int ret = -1;
 
     VIR_DEBUG("Checking if host%d is an FC HBA", d->scsi_host.host);
@@ -50,7 +52,7 @@ detect_scsi_host_caps_linux(union _virNodeDevCapData *d)
         if (virReadFCHost(NULL,
                           d->scsi_host.host,
                           "port_name",
-                          &d->scsi_host.wwpn) == -1) {
+                          &d->scsi_host.wwpn) < 0) {
             VIR_ERROR(_("Failed to read WWPN for host%d"), d->scsi_host.host);
             goto cleanup;
         }
@@ -58,7 +60,7 @@ detect_scsi_host_caps_linux(union _virNodeDevCapData *d)
         if (virReadFCHost(NULL,
                           d->scsi_host.host,
                           "node_name",
-                          &d->scsi_host.wwnn) == -1) {
+                          &d->scsi_host.wwnn) < 0) {
             VIR_ERROR(_("Failed to read WWNN for host%d"), d->scsi_host.host);
             goto cleanup;
         }
@@ -66,23 +68,62 @@ detect_scsi_host_caps_linux(union _virNodeDevCapData *d)
         if (virReadFCHost(NULL,
                           d->scsi_host.host,
                           "fabric_name",
-                          &d->scsi_host.fabric_wwn) == -1) {
+                          &d->scsi_host.fabric_wwn) < 0) {
             VIR_ERROR(_("Failed to read fabric WWN for host%d"),
                       d->scsi_host.host);
             goto cleanup;
         }
     }
 
-    if (virIsCapableVport(NULL, d->scsi_host.host) == 0)
+    if (virIsCapableVport(NULL, d->scsi_host.host) == 0) {
         d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS;
 
+        if (virReadFCHost(NULL,
+                          d->scsi_host.max_vports,
+                          "max_npiv_vports",
+                          &max_vports) < 0) {
+            VIR_ERROR(_("Failed to read max_npiv_vports for host%d"),
+                      d->scsi_host.host);
+            goto cleanup;
+        }
+
+         if (virReadFCHost(NULL,
+                          d->scsi_host.max_vports,
+                          "npiv_vports_inuse",
+                          &vports) < 0) {
+            VIR_ERROR(_("Failed to read npiv_vports_inuse for host%d"),
+                      d->scsi_host.host);
+            goto cleanup;
+        }
+
+        if (virStrToLong_i(max_vports, NULL, 10,
+                           &d->scsi_host.max_vports) < 0) {
+            VIR_ERROR(_("Failed to parse value of max_npiv_vports '%s'"),
+                      max_vports);
+            goto cleanup;
+        }
+
+        if (virStrToLong_i(vports, NULL, 10,
+                           &d->scsi_host.vports) < 0) {
+            VIR_ERROR(_("Failed to parse value of npiv_vports_inuse '%s'"),
+                      vports);
+            goto cleanup;
+        }
+    }
+
     ret = 0;
 cleanup:
     if (ret < 0) {
+        /* Clear the two flags in case of producing confusing XML output */
+        d->scsi_host.flags &= ~(VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST |
+                                VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS);
+
         VIR_FREE(d->scsi_host.wwnn);
         VIR_FREE(d->scsi_host.wwpn);
         VIR_FREE(d->scsi_host.fabric_wwn);
     }
+    VIR_FREE(max_vports);
+    VIR_FREE(vports);
     return ret;
 }
 
-- 
1.7.7.6




More information about the libvir-list mailing list