]> xenbits.xensource.com Git - libvirt.git/commitdiff
nodedev: Dump max vports and vports in use for HBA's XML
authorOsier Yang <jyang@redhat.com>
Mon, 7 Jan 2013 17:05:32 +0000 (01:05 +0800)
committerOsier Yang <jyang@redhat.com>
Mon, 25 Mar 2013 12:46:05 +0000 (20:46 +0800)
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
docs/schemas/nodedev.rng
src/conf/node_device_conf.c
src/conf/node_device_conf.h
src/node_device/node_device_linux_sysfs.c

index fcaaaafa39632dbe2db5367afc37b75ed7a2c1b8..5712bcf1f58187284964624181309591c4b47e1f 100644 (file)
               <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>
index 04d8ee9b1d19051712d85df6247ff599d241dc26..1f5dcb97188c818411db6a347a9f85cd99bf73f5 100644 (file)
     <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'>
index f743b26b1bc41d4ce7ee48c9a0cfad044fb48bbf..b4d8cb3169631b39c52a388bd44ad819767a7330 100644 (file)
@@ -391,7 +391,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;
index 2946026c4035291c11e99cfe3a858465a0899ff7..ca5ec726d5fd7bbae6ed2d3863a42ac34fe53f03 100644 (file)
@@ -138,6 +138,8 @@ struct _virNodeDevCapsDef {
             char *wwpn;
             char *fabric_wwn;
             unsigned int flags;
+            int max_vports;
+            int vports;
         } scsi_host;
         struct {
             char *name;
index 85bbab610feb5081596f5724f0f9df8cc486ced0..a1c36372b17a4c7b41744575334a64efe157d9d3 100644 (file)
@@ -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;
 }