[libvirt] [PATCH 04/15] tests: Create a more realistic vHBA

John Ferlan jferlan at redhat.com
Wed Jan 25 20:27:30 UTC 2017


Modify the code to react more like a real HBA -> vHBA creation.

Currently the code would just modify the input XML definition to
set the name to a wwpn and then modify the scsi_host capability
entry for the defintion to change the scsi_host# and unique_id
before adding that into the node device.

This patch does things a bit better. It finds and copies a known
existing vHBA (scsi_host11) in the node_device database and modifies
that definition to change the name to scsi_host12 and set the wwnn/
wwpn to what the input XML would expect before adding the def to the
node device object list.

Then rather than create a returned "dev" using the (poorly) mocked
name - perform the lookup using the new device name.

Signed-off-by: John Ferlan <jferlan at redhat.com>
---
 src/test/test_driver.c | 75 ++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 55 insertions(+), 20 deletions(-)

diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 5e628b5..0a0fa8f 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -5623,32 +5623,59 @@ testNodeDeviceListCaps(virNodeDevicePtr dev, char **const names, int maxnames)
 }
 
 
-static int
+static virNodeDeviceDefPtr
 testNodeDeviceMockCreateVport(virConnectPtr conn,
-                              virNodeDeviceDefPtr def,
+                              const char *wwnn,
                               const char *wwpn)
 {
-    int ret = -1;
     testDriverPtr driver = conn->privateData;
+    virNodeDevicePtr devcpy = NULL;
+    char *xml = NULL;
+    virNodeDeviceDefPtr def = NULL;
     virNodeDevCapsDefPtr caps;
     virNodeDeviceObjPtr obj = NULL;
     virObjectEventPtr event = NULL;
 
-    /* 'name' is supposed to be filled in by the node device backend, which
-     * we don't have. Use WWPN instead. */
+    /* In the real code, we'd call virVHBAManageVport which would take the
+     * wwnn/wwpn from the input XML in order to call the "vport_create"
+     * function for the parent. That in turn would set off a sequence of
+     * events resulting in the creation of a vHBA scsi_hostN in the
+     * node device objects list using the "next" host number with the
+     * wwnn/wwpn from the input XML. The following will mock this by
+     * using the scsi_host11 definition, changing the name and the
+     * scsi_host capability fields before calling virNodeDeviceAssignDef
+     * to add the def to the node device objects list. */
+    if (!(devcpy = virNodeDeviceLookupByName(conn, "scsi_host11")) ||
+        !(xml = virNodeDeviceGetXMLDesc(devcpy, 0)) ||
+        !(def = virNodeDeviceDefParseString(xml, EXISTING_DEVICE, NULL)))
+        goto cleanup;
+
     VIR_FREE(def->name);
-    if (VIR_STRDUP(def->name, wwpn) < 0)
+    if (VIR_STRDUP(def->name, "scsi_host12") < 0)
         goto cleanup;
 
-    /* Fill in a random 'host' and 'unique_id' value,
-     * since this would also come from the backend */
+    /* Find the 'scsi_host' cap and alter the host # and unique_id and
+     * then for the 'fc_host' capability modify the wwnn/wwpn to be that
+     * of the input XML. */
     caps = def->caps;
     while (caps) {
         if (caps->data.type != VIR_NODE_DEV_CAP_SCSI_HOST)
             continue;
 
-        caps->data.scsi_host.host = virRandomBits(10);
-        caps->data.scsi_host.unique_id = 2;
+        /* For the "fc_host" cap - change the wwnn/wwpn to match the input */
+        if (caps->data.scsi_host.flags & VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST) {
+            VIR_FREE(caps->data.scsi_host.wwnn);
+            VIR_FREE(caps->data.scsi_host.wwpn);
+            if (VIR_STRDUP(caps->data.scsi_host.wwnn, wwnn) < 0 ||
+                VIR_STRDUP(caps->data.scsi_host.wwpn, wwpn) < 0)
+                goto cleanup;
+        } else {
+            /* For the "scsi_host" cap, increment our host and unique_id to
+             * give the appearance that something new was created - then add
+             * that to the node device driver */
+            caps->data.scsi_host.host++;
+            caps->data.scsi_host.unique_id++;
+        }
         caps = caps->next;
     }
 
@@ -5661,10 +5688,16 @@ testNodeDeviceMockCreateVport(virConnectPtr conn,
                                            0);
     testObjectEventQueue(driver, event);
 
-    ret = 0;
-
  cleanup:
-    return ret;
+    VIR_FREE(xml);
+    if (!obj) {
+        virNodeDeviceDefFree(def);
+        def = NULL;
+    }
+    if (devcpy)
+        virNodeDeviceFree(devcpy);
+
+    return def;
 }
 
 
@@ -5678,6 +5711,7 @@ testNodeDeviceCreateXML(virConnectPtr conn,
     char *wwnn = NULL, *wwpn = NULL;
     int parent_host = -1;
     virNodeDevicePtr dev = NULL;
+    virNodeDeviceDefPtr newdef = NULL;
 
     virCheckFlags(0, NULL);
 
@@ -5699,14 +5733,15 @@ testNodeDeviceCreateXML(virConnectPtr conn,
 
     /* In the real code, we'd call virVHBAManageVport followed by
      * find_new_device, but we cannot do that here since we're not
-     * mocking udev. So we just mock a creation by altering the
-     * input XML enough to make it look like a vHBA and add it
-     * to the list of node devices */
-    if (testNodeDeviceMockCreateVport(conn, def, wwpn) < 0)
-        goto cleanup;
+     * mocking udev. The mock routine will copy an existing vHBA and
+     * rename a few fields to mock that. So in order to allow that to
+     * work properly, we need to drop our lock */
+    testDriverUnlock(driver);
+    if ((newdef = testNodeDeviceMockCreateVport(conn, wwnn, wwpn)))
+        dev = virNodeDeviceLookupByName(conn, newdef->name);
+    testDriverLock(driver);
+    newdef = NULL;
 
-    dev = virGetNodeDevice(conn, def->name);
-    def = NULL;
  cleanup:
     testDriverUnlock(driver);
     virNodeDeviceDefFree(def);
-- 
2.7.4




More information about the libvir-list mailing list