|
|
9119d9 |
From 36873e3b85a70d8bbd6d9e259165050e93f43612 Mon Sep 17 00:00:00 2001
|
|
|
9119d9 |
Message-Id: <36873e3b85a70d8bbd6d9e259165050e93f43612@dist-git>
|
|
|
9119d9 |
From: John Ferlan <jferlan@redhat.com>
|
|
|
9119d9 |
Date: Wed, 12 Nov 2014 13:34:47 -0500
|
|
|
9119d9 |
Subject: [PATCH] storage: Ensure fc_host parent matches wwnn/wwpn
|
|
|
9119d9 |
|
|
|
9119d9 |
https://bugzilla.redhat.com/show_bug.cgi?id=1160565
|
|
|
9119d9 |
|
|
|
9119d9 |
The existing code assumed that the configuration of a 'parent' attribute
|
|
|
9119d9 |
was correct for the createVport path. As it turns out, that may not be
|
|
|
9119d9 |
the case which leads errors during the deleteVport path because the
|
|
|
9119d9 |
wwnn/wwpn isn't associated with the parent.
|
|
|
9119d9 |
|
|
|
9119d9 |
With this change the following is reported:
|
|
|
9119d9 |
|
|
|
9119d9 |
error: Failed to start pool fc_pool_host3
|
|
|
9119d9 |
error: XML error: Parent attribute 'scsi_host4' does not match parent 'scsi_host3' determined for the 'scsi_host16' wwnn/wwpn lookup.
|
|
|
9119d9 |
|
|
|
9119d9 |
for XML as follows:
|
|
|
9119d9 |
|
|
|
9119d9 |
<pool type='scsi'>
|
|
|
9119d9 |
<name>fc_pool</name>
|
|
|
9119d9 |
<source>
|
|
|
9119d9 |
<adapter type='fc_host' parent='scsi_host4' wwnn='5001a4aaf3ca174b' wwpn='5001a4a77192b864'/>
|
|
|
9119d9 |
</source>
|
|
|
9119d9 |
|
|
|
9119d9 |
Where 'nodedev-dumpxml scsi_host16' provides:
|
|
|
9119d9 |
|
|
|
9119d9 |
<device>
|
|
|
9119d9 |
<name>scsi_host16</name>
|
|
|
9119d9 |
<path>/sys/devices/pci0000:00/0000:00:04.0/0000:10:00.0/host3/vport-3:0-11/host16</path>
|
|
|
9119d9 |
<parent>scsi_host3</parent>
|
|
|
9119d9 |
<capability type='scsi_host'>
|
|
|
9119d9 |
<host>16</host>
|
|
|
9119d9 |
<unique_id>13</unique_id>
|
|
|
9119d9 |
<capability type='fc_host'>
|
|
|
9119d9 |
<wwnn>5001a4aaf3ca174b</wwnn>
|
|
|
9119d9 |
<wwpn>5001a4a77192b864</wwpn>
|
|
|
9119d9 |
...
|
|
|
9119d9 |
|
|
|
9119d9 |
The patch also adjusts the description of the storage pool to describe the
|
|
|
9119d9 |
restrictions.
|
|
|
9119d9 |
|
|
|
9119d9 |
Signed-off-by: John Ferlan <jferlan@redhat.com>
|
|
|
9119d9 |
(cherry picked from commit 42a021c1204d7dcb531f5d476e65b53a8bd4f704)
|
|
|
9119d9 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
9119d9 |
---
|
|
|
9119d9 |
docs/formatstorage.html.in | 15 ++++-
|
|
|
9119d9 |
src/storage/storage_backend_scsi.c | 118 +++++++++++++++++++++++++++++++++++--
|
|
|
9119d9 |
2 files changed, 126 insertions(+), 7 deletions(-)
|
|
|
9119d9 |
|
|
|
9119d9 |
diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in
|
|
|
9119d9 |
index e25bba7..7872112 100644
|
|
|
9119d9 |
--- a/docs/formatstorage.html.in
|
|
|
9119d9 |
+++ b/docs/formatstorage.html.in
|
|
|
9119d9 |
@@ -165,7 +165,13 @@
|
|
|
9119d9 |
to uniquely identify the device in the Fibre Channel storage fabric
|
|
|
9119d9 |
(the device can be either a HBA or vHBA). Both wwnn and wwpn should
|
|
|
9119d9 |
be specified. Use the command 'virsh nodedev-dumpxml' to determine
|
|
|
9119d9 |
- how to set the values for the wwnn/wwpn of a (v)HBA.
|
|
|
9119d9 |
+ how to set the values for the wwnn/wwpn of a (v)HBA. The wwnn and
|
|
|
9119d9 |
+ wwpn have very specific numerical format requirements based on the
|
|
|
9119d9 |
+ hypervisor being used, thus care should be taken if you decide to
|
|
|
9119d9 |
+ generate your own to follow the standards; otherwise, the pool
|
|
|
9119d9 |
+ will fail to start with an opaque error message indicating failure
|
|
|
9119d9 |
+ to write to the vport_create file during vport create/delete due
|
|
|
9119d9 |
+ to "No such file or directory".
|
|
|
9119d9 |
Since 1.0.4
|
|
|
9119d9 |
|
|
|
9119d9 |
|
|
|
9119d9 |
@@ -175,7 +181,12 @@
|
|
|
9119d9 |
parent scsi_host device defined in the
|
|
|
9119d9 |
Node Device database as the
|
|
|
9119d9 |
NPIV
|
|
|
9119d9 |
- virtual Host Bus Adapter (vHBA).
|
|
|
9119d9 |
+ virtual Host Bus Adapter (vHBA). The value provided must be
|
|
|
9119d9 |
+ a vport capable scsi_host. The value is not the scsi_host of
|
|
|
9119d9 |
+ the vHBA created by 'virsh nodedev-create', rather it is
|
|
|
9119d9 |
+ the parent of that vHBA. If the value is not provided, libvirt
|
|
|
9119d9 |
+ will determine the parent based either finding the wwnn,wwpn
|
|
|
9119d9 |
+ defined for an existing scsi_host or by creating a vHBA.
|
|
|
9119d9 |
Since 1.0.4
|
|
|
9119d9 |
|
|
|
9119d9 |
|
|
|
9119d9 |
diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c
|
|
|
9119d9 |
index 88928c9..bfef219 100644
|
|
|
9119d9 |
--- a/src/storage/storage_backend_scsi.c
|
|
|
9119d9 |
+++ b/src/storage/storage_backend_scsi.c
|
|
|
9119d9 |
@@ -34,6 +34,7 @@
|
|
|
9119d9 |
#include "virlog.h"
|
|
|
9119d9 |
#include "virfile.h"
|
|
|
9119d9 |
#include "vircommand.h"
|
|
|
9119d9 |
+#include "viraccessapicheck.h"
|
|
|
9119d9 |
#include "virstring.h"
|
|
|
9119d9 |
|
|
|
9119d9 |
#define VIR_FROM_THIS VIR_FROM_STORAGE
|
|
|
9119d9 |
@@ -547,8 +548,103 @@ getAdapterName(virStoragePoolSourceAdapter adapter)
|
|
|
9119d9 |
return name;
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
+/*
|
|
|
9119d9 |
+ * Using the host# name found via wwnn/wwpn lookup in the fc_host
|
|
|
9119d9 |
+ * sysfs tree to get the parent 'scsi_host#'. On entry we need 'conn'
|
|
|
9119d9 |
+ * set. We won't get here from the autostart path since the caller
|
|
|
9119d9 |
+ * will return true before calling this function. For the shutdown
|
|
|
9119d9 |
+ * path we won't be able to delete the vport.
|
|
|
9119d9 |
+ */
|
|
|
9119d9 |
+static char * ATTRIBUTE_NONNULL(1)
|
|
|
9119d9 |
+getVhbaSCSIHostParent(virConnectPtr conn,
|
|
|
9119d9 |
+ const char *name)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+ char *nodedev_name = NULL;
|
|
|
9119d9 |
+ virNodeDevicePtr device = NULL;
|
|
|
9119d9 |
+ char *xml = NULL;
|
|
|
9119d9 |
+ virNodeDeviceDefPtr def = NULL;
|
|
|
9119d9 |
+ char *vhba_parent = NULL;
|
|
|
9119d9 |
+ virErrorPtr savedError = NULL;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ VIR_DEBUG("conn=%p, name=%s", conn, name);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ /* We get passed "host#" from the return from virGetFCHostNameByWWN,
|
|
|
9119d9 |
+ * so we need to adjust that to what the nodedev lookup expects
|
|
|
9119d9 |
+ */
|
|
|
9119d9 |
+ if (virAsprintf(&nodedev_name, "scsi_%s", name) < 0)
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ /* Compare the scsi_host for the name with the provided parent
|
|
|
9119d9 |
+ * if not the same, then fail
|
|
|
9119d9 |
+ */
|
|
|
9119d9 |
+ if (!(device = virNodeDeviceLookupByName(conn, nodedev_name))) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_XML_ERROR,
|
|
|
9119d9 |
+ _("Cannot find '%s' in node device database"),
|
|
|
9119d9 |
+ nodedev_name);
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!(xml = virNodeDeviceGetXMLDesc(device, 0)))
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!(def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL)))
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ ignore_value(VIR_STRDUP(vhba_parent, def->parent));
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ cleanup:
|
|
|
9119d9 |
+ if (!vhba_parent)
|
|
|
9119d9 |
+ savedError = virSaveLastError();
|
|
|
9119d9 |
+ VIR_FREE(nodedev_name);
|
|
|
9119d9 |
+ virNodeDeviceDefFree(def);
|
|
|
9119d9 |
+ VIR_FREE(xml);
|
|
|
9119d9 |
+ virNodeDeviceFree(device);
|
|
|
9119d9 |
+ if (savedError) {
|
|
|
9119d9 |
+ virSetError(savedError);
|
|
|
9119d9 |
+ virFreeError(savedError);
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+ return vhba_parent;
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+/*
|
|
|
9119d9 |
+ * Using the host# name found via wwnn/wwpn lookup in the fc_host
|
|
|
9119d9 |
+ * sysfs tree to get the parent 'scsi_host#' to ensure it matches.
|
|
|
9119d9 |
+ */
|
|
|
9119d9 |
+static bool
|
|
|
9119d9 |
+checkVhbaSCSIHostParent(virConnectPtr conn,
|
|
|
9119d9 |
+ const char *name,
|
|
|
9119d9 |
+ const char *parent_name)
|
|
|
9119d9 |
+{
|
|
|
9119d9 |
+ char *vhba_parent = NULL;
|
|
|
9119d9 |
+ bool retval = false;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ VIR_DEBUG("conn=%p, name=%s, parent_name=%s", conn, name, parent_name);
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ /* autostarted pool - assume we're OK */
|
|
|
9119d9 |
+ if (!conn)
|
|
|
9119d9 |
+ return true;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (!(vhba_parent = getVhbaSCSIHostParent(conn, name)))
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ if (STRNEQ(parent_name, vhba_parent)) {
|
|
|
9119d9 |
+ virReportError(VIR_ERR_XML_ERROR,
|
|
|
9119d9 |
+ _("Parent attribute '%s' does not match parent '%s' "
|
|
|
9119d9 |
+ "determined for the '%s' wwnn/wwpn lookup."),
|
|
|
9119d9 |
+ parent_name, vhba_parent, name);
|
|
|
9119d9 |
+ goto cleanup;
|
|
|
9119d9 |
+ }
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ retval = true;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ cleanup:
|
|
|
9119d9 |
+ VIR_FREE(vhba_parent);
|
|
|
9119d9 |
+ return retval;
|
|
|
9119d9 |
+}
|
|
|
9119d9 |
+
|
|
|
9119d9 |
static int
|
|
|
9119d9 |
-createVport(virStoragePoolSourceAdapter adapter)
|
|
|
9119d9 |
+createVport(virConnectPtr conn,
|
|
|
9119d9 |
+ virStoragePoolSourceAdapter adapter)
|
|
|
9119d9 |
{
|
|
|
9119d9 |
unsigned int parent_host;
|
|
|
9119d9 |
char *name = NULL;
|
|
|
9119d9 |
@@ -570,11 +666,23 @@ createVport(virStoragePoolSourceAdapter adapter)
|
|
|
9119d9 |
}
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
- /* This filters either HBA or already created vHBA */
|
|
|
9119d9 |
+ /* If we find an existing HBA/vHBA within the fc_host sysfs
|
|
|
9119d9 |
+ * using the wwnn/wwpn, then a nodedev is already created for
|
|
|
9119d9 |
+ * this pool and we don't have to create the vHBA
|
|
|
9119d9 |
+ */
|
|
|
9119d9 |
if ((name = virGetFCHostNameByWWN(NULL, adapter.data.fchost.wwnn,
|
|
|
9119d9 |
adapter.data.fchost.wwpn))) {
|
|
|
9119d9 |
+ int retval = 0;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
+ /* If a parent was provided, let's make sure the 'name' we've
|
|
|
9119d9 |
+ * retrieved has the same parent
|
|
|
9119d9 |
+ */
|
|
|
9119d9 |
+ if (adapter.data.fchost.parent &&
|
|
|
9119d9 |
+ !checkVhbaSCSIHostParent(conn, name, adapter.data.fchost.parent))
|
|
|
9119d9 |
+ retval = -1;
|
|
|
9119d9 |
+
|
|
|
9119d9 |
VIR_FREE(name);
|
|
|
9119d9 |
- return 0;
|
|
|
9119d9 |
+ return retval;
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
if (!adapter.data.fchost.parent) {
|
|
|
9119d9 |
@@ -705,11 +813,11 @@ virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
static int
|
|
|
9119d9 |
-virStorageBackendSCSIStartPool(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|
|
9119d9 |
+virStorageBackendSCSIStartPool(virConnectPtr conn,
|
|
|
9119d9 |
virStoragePoolObjPtr pool)
|
|
|
9119d9 |
{
|
|
|
9119d9 |
virStoragePoolSourceAdapter adapter = pool->def->source.adapter;
|
|
|
9119d9 |
- return createVport(adapter);
|
|
|
9119d9 |
+ return createVport(conn, adapter);
|
|
|
9119d9 |
}
|
|
|
9119d9 |
|
|
|
9119d9 |
static int
|
|
|
9119d9 |
--
|
|
|
9119d9 |
2.1.3
|
|
|
9119d9 |
|