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