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@xxxxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list