[libvirt] [PATCH v3 00/18] Converge Storage Pool vHBA logic with Node Device

v2: http://www.redhat.com/archives/libvir-list/2017-March/msg00161.html Changes since v2: - Pushed the former patch1 after a slight adjustment replace a spurrious lost line - [NEW] Patch 1 - Fixes an existing bug - details in patch - [UPD] Patch 2 - Split out what Jano noted about new checks into it's own - [UPD] Patch 3->14 - Rework the former patch2 to split out the step by step details it took to get to patch2. - [No Change] Patch 15-18 -> Patch15->16 ACKed in v1, but I just left these in the order I had -> Patch17->18 Unchanged - same comment as v2 (copied so as to not force someone would go back to v2): Even though there is concern over usage of API's in this manner (e.g. calling virNodeDeviceLookupSCSIHostByWWN as well as virNodeDeviceCreateXML) - the "purpose" of the exercise is a means to have the StoragePool code use the same algorithms as the node device code instead of what could be a potentially long slow journey through the sysfs file system. The key piece being the replication of the API's that find the parent in the node device object list. I suppose it would be possible to add even more API's to get that answer, but I'm not sure it'd be worthwhile at this point. As for the concern about deadlock - I understand it, but since the whole purpose of the API is to essentially utilize the nodedev create algorithm there'd be no reason for nodedev to call it. If it doesn't get ACK'd - that's OK - I can hold onto it and reconsider some other means at some point in time in the future (probably distant future too). John Ferlan (18): conf: Ensure both parent_wwnn/parent_wwpn provided conf: Add missing validate for fchost search fields conf: Split out storage pool source adapter helpers conf: Rework parsing in virStoragePoolDefParseSourceAdapter conf: Introduce storage_adapter_conf conf: Rename API's in storage_adapter_conf conf: Extract FCHost adapter type processing into their own helpers conf: Extract SCSI adapter type processing into their own helpers conf: Split up virStoragePoolSourceAdapter conf: Rework storage_adapter_conf to use adapter specific typedefs conf: Rework storage_conf to use adapter specific typedefs storage: Rework getAdapterName to use adapter specific typedefs storage: Rework createVport and deleteVport conf: Convert virStoragePoolSourceAdapter to virStorageAdapter util: Rename virFileWaitForDevices conf: Move/rename createVport and deleteVport util: Alter virNodeDevice{Create|Delete}Vport to use nodedev APIs tests: Add more storage pool vHBA tests po/POTFILES.in | 1 + src/Makefile.am | 1 + src/conf/node_device_conf.c | 332 ++++++++++++++++++++++++++++++++ src/conf/node_device_conf.h | 9 + src/conf/storage_adapter_conf.c | 330 ++++++++++++++++++++++++++++++++ src/conf/storage_adapter_conf.h | 84 ++++++++ src/conf/storage_conf.c | 348 ++++++++-------------------------- src/conf/storage_conf.h | 36 +--- src/libvirt_private.syms | 13 +- src/node_device/node_device_driver.c | 2 +- src/phyp/phyp_driver.c | 3 +- src/storage/storage_backend_disk.c | 6 +- src/storage/storage_backend_iscsi.c | 2 +- src/storage/storage_backend_logical.c | 4 +- src/storage/storage_backend_mpath.c | 2 +- src/storage/storage_backend_scsi.c | 267 +++++--------------------- src/storage/storage_util.c | 2 +- src/test/test_driver.c | 11 +- src/util/virfile.h | 2 - src/util/virutil.c | 4 +- src/util/virutil.h | 2 + tests/fchosttest.c | 47 +++++ 22 files changed, 968 insertions(+), 540 deletions(-) create mode 100644 src/conf/storage_adapter_conf.c create mode 100644 src/conf/storage_adapter_conf.h -- 2.9.3

https://bugzilla.redhat.com/show_bug.cgi?id=1428209 Commit id 'bb74a7ffe' neglected to check that both the parent_wwnn parent_wwpn are in the XML if one or the other is similar to how the node device code checked (commit id '2b13361bc'). If only one is provided, the "default" is to use a vHBA capable adapter (see commit id '78be2e8b'), so the vHBA could start, but perhaps not on the expected adapter. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index a52eeba..e4d89dd 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -941,6 +941,17 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) goto error; + + if ((ret->source.adapter.data.fchost.parent_wwnn && + !ret->source.adapter.data.fchost.parent_wwpn) || + (!ret->source.adapter.data.fchost.parent_wwnn && + ret->source.adapter.data.fchost.parent_wwpn)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("must supply both parent_wwnn and " + "parent_wwpn not just one or the other")); + goto error; + } + } else if (ret->source.adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { if (!ret->source.adapter.data.scsi_host.name && -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=1428209
Commit id 'bb74a7ffe' neglected to check that both the parent_wwnn parent_wwpn are in the XML if one or the other is similar to how the node device code checked (commit id '2b13361bc').
If only one is provided, the "default" is to use a vHBA capable adapter (see commit id '78be2e8b'), so the vHBA could start, but perhaps not on the expected adapter.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index a52eeba..e4d89dd 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -941,6 +941,17 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) goto error; + + if ((ret->source.adapter.data.fchost.parent_wwnn && + !ret->source.adapter.data.fchost.parent_wwpn) || + (!ret->source.adapter.data.fchost.parent_wwnn && + ret->source.adapter.data.fchost.parent_wwpn)) {
If you want to make this more compact, you could use an XOR. Since there isn't a logical XOR operator in C, you could do this: if (!!ret->source.adapter.data.fchost.parent_wwnn ^ !!ret->source.adapter.data.fchost.parent_wwpn)
+ virReportError(VIR_ERR_XML_ERROR, "%s", + _("must supply both parent_wwnn and " + "parent_wwpn not just one or the other")); + goto error; + } +
Is there any other identifiable info available at this point that could give more useful context to the log message? If nothing else, maybe log whichever of the two values is set so there would be something for the user to search on when looking for the offending xml. (I see the error log in commit 2b13361bc has the same problem).
} else if (ret->source.adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { if (!ret->source.adapter.data.scsi_host.name &&
ACK, but I'd prefer if the error log gave more identifiable information.

On 03/11/2017 10:34 AM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=1428209
Commit id 'bb74a7ffe' neglected to check that both the parent_wwnn parent_wwpn are in the XML if one or the other is similar to how the node device code checked (commit id '2b13361bc').
If only one is provided, the "default" is to use a vHBA capable adapter (see commit id '78be2e8b'), so the vHBA could start, but perhaps not on the expected adapter.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index a52eeba..e4d89dd 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -941,6 +941,17 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) goto error; + + if ((ret->source.adapter.data.fchost.parent_wwnn && + !ret->source.adapter.data.fchost.parent_wwpn) || + (!ret->source.adapter.data.fchost.parent_wwnn && + ret->source.adapter.data.fchost.parent_wwpn)) { If you want to make this more compact, you could use an XOR. Since there isn't a logical XOR operator in C, you could do this:
if (!!ret->source.adapter.data.fchost.parent_wwnn ^ !!ret->source.adapter.data.fchost.parent_wwpn)
+ virReportError(VIR_ERR_XML_ERROR, "%s", + _("must supply both parent_wwnn and " + "parent_wwpn not just one or the other"));
While seeing this chunk fly by in patch 7, I realized that this message isn't complete - you must supply both of them *or neither of them* but never just one - you left out the bit inside the asterisks.
+ goto error; + } +
Is there any other identifiable info available at this point that could give more useful context to the log message? If nothing else, maybe log whichever of the two values is set so there would be something for the user to search on when looking for the offending xml. (I see the error log in commit 2b13361bc has the same problem).
} else if (ret->source.adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { if (!ret->source.adapter.data.scsi_host.name &&
ACK, but I'd prefer if the error log gave more identifiable information.
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

On 03/11/2017 09:56 PM, Laine Stump wrote:
On 03/11/2017 10:34 AM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
https://bugzilla.redhat.com/show_bug.cgi?id=1428209
Commit id 'bb74a7ffe' neglected to check that both the parent_wwnn parent_wwpn are in the XML if one or the other is similar to how the node device code checked (commit id '2b13361bc').
If only one is provided, the "default" is to use a vHBA capable adapter (see commit id '78be2e8b'), so the vHBA could start, but perhaps not on the expected adapter.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index a52eeba..e4d89dd 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -941,6 +941,17 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) goto error; + + if ((ret->source.adapter.data.fchost.parent_wwnn && + !ret->source.adapter.data.fchost.parent_wwpn) || + (!ret->source.adapter.data.fchost.parent_wwnn && + ret->source.adapter.data.fchost.parent_wwpn)) { If you want to make this more compact, you could use an XOR. Since there isn't a logical XOR operator in C, you could do this:
if (!!ret->source.adapter.data.fchost.parent_wwnn ^ !!ret->source.adapter.data.fchost.parent_wwpn)
Not a real fan of the !! unary and perhaps less so for the ^ unary. Let the compiler do that!
+ virReportError(VIR_ERR_XML_ERROR, "%s", + _("must supply both parent_wwnn and " + "parent_wwpn not just one or the other"));
While seeing this chunk fly by in patch 7, I realized that this message isn't complete - you must supply both of them *or neither of them* but never just one - you left out the bit inside the asterisks.
FWIW: From node_device_conf for a similar check: if ((def->parent_wwnn && !def->parent_wwpn) || (!def->parent_wwnn && def->parent_wwpn)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("must supply both wwnn and wwpn for parent")); goto error; } I can alter the message here (and there) to be something like: _("when used both parent_wwnn('%s') and parent_wwpn('%s') must be supplied, not just one"), NULLSTR(def->parent_wwnn), NULLSTR(def->parent_wwpn)...
+ goto error; + } +
Is there any other identifiable info available at this point that could give more useful context to the log message? If nothing else, maybe log whichever of the two values is set so there would be something for the user to search on when looking for the offending xml. (I see the error log in commit 2b13361bc has the same problem).
Nothing springs to mind, but it's still early ;-) Tks - John
} else if (ret->source.adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { if (!ret->source.adapter.data.scsi_host.name &&
ACK, but I'd prefer if the error log gave more identifiable information.
-- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list

Commit id 'bb74a7ffe' added some new fields to search for a fchost by parent wwnn/wwpn or parent_fabric_name, but neglected to validate that the data within the fields was valid at parse time. This could lead to eventual failure at run time, so rather than have the failure then, let's validate now. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index e4d89dd..8e3b175 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -952,6 +952,18 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) goto error; } + if (ret->source.adapter.data.fchost.parent_wwnn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_wwnn)) + goto error; + + if (ret->source.adapter.data.fchost.parent_wwpn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_wwpn)) + goto error; + + if (ret->source.adapter.data.fchost.parent_fabric_wwn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_fabric_wwn)) + goto error; + } else if (ret->source.adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { if (!ret->source.adapter.data.scsi_host.name && -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Commit id 'bb74a7ffe' added some new fields to search for a fchost by parent wwnn/wwpn or parent_fabric_name, but neglected to validate that the data within the fields was valid at parse time. This could lead to eventual failure at run time, so rather than have the failure then, let's validate now.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index e4d89dd..8e3b175 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -952,6 +952,18 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) goto error; }
+ if (ret->source.adapter.data.fchost.parent_wwnn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_wwnn)) + goto error; + + if (ret->source.adapter.data.fchost.parent_wwpn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_wwpn)) + goto error; + + if (ret->source.adapter.data.fchost.parent_fabric_wwn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_fabric_wwn)) + goto error; + } else if (ret->source.adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { if (!ret->source.adapter.data.scsi_host.name &&
ACK.

Split out the code that munges through the storage pool adapter into helpers - it's about to be moved into it's own source file. This is purely code motion at this point. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 455 ++++++++++++++++++++++++++---------------------- 1 file changed, 243 insertions(+), 212 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 8e3b175..1993d3a 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -463,6 +463,128 @@ virStoragePoolObjRemove(virStoragePoolObjListPtr pools, } static int +virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, + xmlXPathContextPtr ctxt) +{ + int ret = -1; + char *adapter_type = NULL; + char *managed = NULL; + + if ((adapter_type = virXPathString("string(./adapter/@type)", ctxt))) { + if ((source->adapter.type = + virStoragePoolSourceAdapterTypeFromString(adapter_type)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unknown pool adapter type '%s'"), + adapter_type); + goto cleanup; + } + + if (source->adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + source->adapter.data.fchost.parent = + virXPathString("string(./adapter/@parent)", ctxt); + managed = virXPathString("string(./adapter/@managed)", ctxt); + if (managed) { + source->adapter.data.fchost.managed = + virTristateBoolTypeFromString(managed); + if (source->adapter.data.fchost.managed < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown fc_host managed setting '%s'"), + managed); + goto cleanup; + } + } + + source->adapter.data.fchost.parent_wwnn = + virXPathString("string(./adapter/@parent_wwnn)", ctxt); + source->adapter.data.fchost.parent_wwpn = + virXPathString("string(./adapter/@parent_wwpn)", ctxt); + source->adapter.data.fchost.parent_fabric_wwn = + virXPathString("string(./adapter/@parent_fabric_wwn)", ctxt); + + source->adapter.data.fchost.wwpn = + virXPathString("string(./adapter/@wwpn)", ctxt); + source->adapter.data.fchost.wwnn = + virXPathString("string(./adapter/@wwnn)", ctxt); + } else if (source->adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + + source->adapter.data.scsi_host.name = + virXPathString("string(./adapter/@name)", ctxt); + if (virXPathNode("./adapter/parentaddr", ctxt)) { + xmlNodePtr addrnode = virXPathNode("./adapter/parentaddr/address", + ctxt); + virPCIDeviceAddressPtr addr = + &source->adapter.data.scsi_host.parentaddr; + + if (!addrnode) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing scsi_host PCI address element")); + goto cleanup; + } + source->adapter.data.scsi_host.has_parent = true; + if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) + goto cleanup; + if ((virXPathInt("string(./adapter/parentaddr/@unique_id)", + ctxt, + &source->adapter.data.scsi_host.unique_id) < 0) || + (source->adapter.data.scsi_host.unique_id < 0)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing or invalid scsi adapter " + "'unique_id' value")); + goto cleanup; + } + } + } + } else { + char *wwnn = NULL; + char *wwpn = NULL; + char *parent = NULL; + + /* "type" was not specified in the XML, so we must verify that + * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the + * XML. If any are found, then we cannot just use "name" alone". + */ + wwnn = virXPathString("string(./adapter/@wwnn)", ctxt); + wwpn = virXPathString("string(./adapter/@wwpn)", ctxt); + parent = virXPathString("string(./adapter/@parent)", ctxt); + + if (wwnn || wwpn || parent) { + VIR_FREE(wwnn); + VIR_FREE(wwpn); + VIR_FREE(parent); + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'wwnn', 'wwpn', and 'parent' attributes " + "requires use of the adapter 'type'")); + goto cleanup; + } + + if (virXPathNode("./adapter/parentaddr", ctxt)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'parent' element requires use " + "of the adapter 'type'")); + goto cleanup; + } + + /* To keep back-compat, 'type' is not required to specify + * for scsi_host adapter. + */ + if ((source->adapter.data.scsi_host.name = + virXPathString("string(./adapter/@name)", ctxt))) + source->adapter.type = + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; + } + + ret = 0; + + cleanup: + VIR_FREE(adapter_type); + VIR_FREE(managed); + return ret; +} + + +static int virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, virStoragePoolSourcePtr source, int pool_type, @@ -476,8 +598,6 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, virStorageAuthDefPtr authdef = NULL; char *name = NULL; char *port = NULL; - char *adapter_type = NULL; - char *managed = NULL; int n; relnode = ctxt->node; @@ -583,110 +703,8 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, VIR_STRDUP(source->dir, "/") < 0) goto cleanup; - if ((adapter_type = virXPathString("string(./adapter/@type)", ctxt))) { - if ((source->adapter.type = - virStoragePoolSourceAdapterTypeFromString(adapter_type)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Unknown pool adapter type '%s'"), - adapter_type); - goto cleanup; - } - - if (source->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - source->adapter.data.fchost.parent = - virXPathString("string(./adapter/@parent)", ctxt); - managed = virXPathString("string(./adapter/@managed)", ctxt); - if (managed) { - source->adapter.data.fchost.managed = - virTristateBoolTypeFromString(managed); - if (source->adapter.data.fchost.managed < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown fc_host managed setting '%s'"), - managed); - goto cleanup; - } - } - - source->adapter.data.fchost.parent_wwnn = - virXPathString("string(./adapter/@parent_wwnn)", ctxt); - source->adapter.data.fchost.parent_wwpn = - virXPathString("string(./adapter/@parent_wwpn)", ctxt); - source->adapter.data.fchost.parent_fabric_wwn = - virXPathString("string(./adapter/@parent_fabric_wwn)", ctxt); - - source->adapter.data.fchost.wwpn = - virXPathString("string(./adapter/@wwpn)", ctxt); - source->adapter.data.fchost.wwnn = - virXPathString("string(./adapter/@wwnn)", ctxt); - } else if (source->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - - source->adapter.data.scsi_host.name = - virXPathString("string(./adapter/@name)", ctxt); - if (virXPathNode("./adapter/parentaddr", ctxt)) { - xmlNodePtr addrnode = virXPathNode("./adapter/parentaddr/address", - ctxt); - virPCIDeviceAddressPtr addr = - &source->adapter.data.scsi_host.parentaddr; - - if (!addrnode) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing scsi_host PCI address element")); - goto cleanup; - } - source->adapter.data.scsi_host.has_parent = true; - if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) - goto cleanup; - if ((virXPathInt("string(./adapter/parentaddr/@unique_id)", - ctxt, - &source->adapter.data.scsi_host.unique_id) < 0) || - (source->adapter.data.scsi_host.unique_id < 0)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing or invalid scsi adapter " - "'unique_id' value")); - goto cleanup; - } - } - } - } else { - char *wwnn = NULL; - char *wwpn = NULL; - char *parent = NULL; - - /* "type" was not specified in the XML, so we must verify that - * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the - * XML. If any are found, then we cannot just use "name" alone". - */ - wwnn = virXPathString("string(./adapter/@wwnn)", ctxt); - wwpn = virXPathString("string(./adapter/@wwpn)", ctxt); - parent = virXPathString("string(./adapter/@parent)", ctxt); - - if (wwnn || wwpn || parent) { - VIR_FREE(wwnn); - VIR_FREE(wwpn); - VIR_FREE(parent); - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'wwnn', 'wwpn', and 'parent' attributes " - "requires use of the adapter 'type'")); - goto cleanup; - } - - if (virXPathNode("./adapter/parentaddr", ctxt)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'parent' element requires use " - "of the adapter 'type'")); - goto cleanup; - } - - /* To keep back-compat, 'type' is not required to specify - * for scsi_host adapter. - */ - if ((source->adapter.data.scsi_host.name = - virXPathString("string(./adapter/@name)", ctxt))) - source->adapter.type = - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; - } + if (virStoragePoolDefParseSourceAdapter(source, ctxt) < 0) + goto cleanup; if ((authnode = virXPathNode("./auth", ctxt))) { if (!(authdef = virStorageAuthDefParse(node->doc, authnode))) @@ -711,8 +729,6 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, VIR_FREE(port); VIR_FREE(nodeset); - VIR_FREE(adapter_type); - VIR_FREE(managed); virStorageAuthDefFree(authdef); return ret; } @@ -831,6 +847,74 @@ virStorageDefParsePerms(xmlXPathContextPtr ctxt, return ret; } +static int +virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret) +{ + if (!ret->source.adapter.type) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing storage pool source adapter")); + return -1; + } + + if (ret->source.adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (!ret->source.adapter.data.fchost.wwnn || + !ret->source.adapter.data.fchost.wwpn) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("'wwnn' and 'wwpn' must be specified for adapter " + "type 'fchost'")); + return -1; + } + + if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || + !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) + return -1; + + if ((ret->source.adapter.data.fchost.parent_wwnn && + !ret->source.adapter.data.fchost.parent_wwpn) || + (!ret->source.adapter.data.fchost.parent_wwnn && + ret->source.adapter.data.fchost.parent_wwpn)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("must supply both parent_wwnn and " + "parent_wwpn not just one or the other")); + return -1; + } + + if (ret->source.adapter.data.fchost.parent_wwnn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_wwnn)) + return -1; + + if (ret->source.adapter.data.fchost.parent_wwpn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_wwpn)) + return -1; + + if (ret->source.adapter.data.fchost.parent_fabric_wwn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_fabric_wwn)) + return -1; + + } else if (ret->source.adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + if (!ret->source.adapter.data.scsi_host.name && + !ret->source.adapter.data.scsi_host.has_parent) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Either 'name' or 'parent' must be specified " + "for the 'scsi_host' adapter")); + return -1; + } + + if (ret->source.adapter.data.scsi_host.name && + ret->source.adapter.data.scsi_host.has_parent) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Both 'name' and 'parent' cannot be specified " + "for the 'scsi_host' adapter")); + return -1; + } + } + + return 0; +} + + static virStoragePoolDefPtr virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) { @@ -921,68 +1005,9 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) } } - if (options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) { - if (!ret->source.adapter.type) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing storage pool source adapter")); + if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) && + (virStoragePoolSourceAdapterParseValidate(ret)) < 0) goto error; - } - - if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (!ret->source.adapter.data.fchost.wwnn || - !ret->source.adapter.data.fchost.wwpn) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("'wwnn' and 'wwpn' must be specified for adapter " - "type 'fchost'")); - goto error; - } - - if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || - !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) - goto error; - - if ((ret->source.adapter.data.fchost.parent_wwnn && - !ret->source.adapter.data.fchost.parent_wwpn) || - (!ret->source.adapter.data.fchost.parent_wwnn && - ret->source.adapter.data.fchost.parent_wwpn)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("must supply both parent_wwnn and " - "parent_wwpn not just one or the other")); - goto error; - } - - if (ret->source.adapter.data.fchost.parent_wwnn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_wwnn)) - goto error; - - if (ret->source.adapter.data.fchost.parent_wwpn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_wwpn)) - goto error; - - if (ret->source.adapter.data.fchost.parent_fabric_wwn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_fabric_wwn)) - goto error; - - } else if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (!ret->source.adapter.data.scsi_host.name && - !ret->source.adapter.data.scsi_host.has_parent) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Either 'name' or 'parent' must be specified " - "for the 'scsi_host' adapter")); - goto error; - } - - if (ret->source.adapter.data.scsi_host.name && - ret->source.adapter.data.scsi_host.has_parent) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Both 'name' and 'parent' cannot be specified " - "for the 'scsi_host' adapter")); - goto error; - } - } - } /* If DEVICE is the only source type, then its required */ if (options->flags == VIR_STORAGE_POOL_SOURCE_DEVICE) { @@ -1086,6 +1111,51 @@ virStoragePoolDefParseFile(const char *filename) return virStoragePoolDefParse(NULL, filename); } +static void +virStoragePoolSourceAdapterFormat(virBufferPtr buf, + virStoragePoolSourcePtr src) +{ + virBufferAsprintf(buf, "<adapter type='%s'", + virStoragePoolSourceAdapterTypeToString(src->adapter.type)); + + if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + virBufferEscapeString(buf, " parent='%s'", + src->adapter.data.fchost.parent); + if (src->adapter.data.fchost.managed) + virBufferAsprintf(buf, " managed='%s'", + virTristateBoolTypeToString(src->adapter.data.fchost.managed)); + virBufferEscapeString(buf, " parent_wwnn='%s'", + src->adapter.data.fchost.parent_wwnn); + virBufferEscapeString(buf, " parent_wwpn='%s'", + src->adapter.data.fchost.parent_wwpn); + virBufferEscapeString(buf, " parent_fabric_wwn='%s'", + src->adapter.data.fchost.parent_fabric_wwn); + + virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", + src->adapter.data.fchost.wwnn, + src->adapter.data.fchost.wwpn); + } else if (src->adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + if (src->adapter.data.scsi_host.name) { + virBufferAsprintf(buf, " name='%s'/>\n", + src->adapter.data.scsi_host.name); + } else { + virPCIDeviceAddress addr; + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "<parentaddr unique_id='%d'>\n", + src->adapter.data.scsi_host.unique_id); + virBufferAdjustIndent(buf, 2); + addr = src->adapter.data.scsi_host.parentaddr; + ignore_value(virPCIDeviceAddressFormat(buf, addr, false)); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</parentaddr>\n"); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</adapter>\n"); + } + } +} + static int virStoragePoolSourceFormat(virBufferPtr buf, virStoragePoolOptionsPtr options, @@ -1135,49 +1205,10 @@ virStoragePoolSourceFormat(virBufferPtr buf, if (options->flags & VIR_STORAGE_POOL_SOURCE_DIR) virBufferEscapeString(buf, "<dir path='%s'/>\n", src->dir); - if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER)) { - if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST || - src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) - virBufferAsprintf(buf, "<adapter type='%s'", - virStoragePoolSourceAdapterTypeToString(src->adapter.type)); - - if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - virBufferEscapeString(buf, " parent='%s'", - src->adapter.data.fchost.parent); - if (src->adapter.data.fchost.managed) - virBufferAsprintf(buf, " managed='%s'", - virTristateBoolTypeToString(src->adapter.data.fchost.managed)); - virBufferEscapeString(buf, " parent_wwnn='%s'", - src->adapter.data.fchost.parent_wwnn); - virBufferEscapeString(buf, " parent_wwpn='%s'", - src->adapter.data.fchost.parent_wwpn); - virBufferEscapeString(buf, " parent_fabric_wwn='%s'", - src->adapter.data.fchost.parent_fabric_wwn); - - virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", - src->adapter.data.fchost.wwnn, - src->adapter.data.fchost.wwpn); - } else if (src->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (src->adapter.data.scsi_host.name) { - virBufferAsprintf(buf, " name='%s'/>\n", - src->adapter.data.scsi_host.name); - } else { - virPCIDeviceAddress addr; - virBufferAddLit(buf, ">\n"); - virBufferAdjustIndent(buf, 2); - virBufferAsprintf(buf, "<parentaddr unique_id='%d'>\n", - src->adapter.data.scsi_host.unique_id); - virBufferAdjustIndent(buf, 2); - addr = src->adapter.data.scsi_host.parentaddr; - ignore_value(virPCIDeviceAddressFormat(buf, addr, false)); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</parentaddr>\n"); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</adapter>\n"); - } - } - } + if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) && + (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST || + src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST)) + virStoragePoolSourceAdapterFormat(buf, src); if (options->flags & VIR_STORAGE_POOL_SOURCE_NAME) virBufferEscapeString(buf, "<name>%s</name>\n", src->name); -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Split out the code that munges through the storage pool adapter into helpers - it's about to be moved into it's own source file.
This is purely code motion at this point.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 455 ++++++++++++++++++++++++++---------------------- 1 file changed, 243 insertions(+), 212 deletions(-)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 8e3b175..1993d3a 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -463,6 +463,128 @@ virStoragePoolObjRemove(virStoragePoolObjListPtr pools, }
static int +virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, + xmlXPathContextPtr ctxt) +{ + int ret = -1; + char *adapter_type = NULL; + char *managed = NULL; + + if ((adapter_type = virXPathString("string(./adapter/@type)", ctxt))) { + if ((source->adapter.type = + virStoragePoolSourceAdapterTypeFromString(adapter_type)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unknown pool adapter type '%s'"), + adapter_type); + goto cleanup; + } + + if (source->adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + source->adapter.data.fchost.parent = + virXPathString("string(./adapter/@parent)", ctxt); + managed = virXPathString("string(./adapter/@managed)", ctxt); + if (managed) { + source->adapter.data.fchost.managed = + virTristateBoolTypeFromString(managed); + if (source->adapter.data.fchost.managed < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown fc_host managed setting '%s'"), + managed); + goto cleanup; + } + } + + source->adapter.data.fchost.parent_wwnn = + virXPathString("string(./adapter/@parent_wwnn)", ctxt); + source->adapter.data.fchost.parent_wwpn = + virXPathString("string(./adapter/@parent_wwpn)", ctxt); + source->adapter.data.fchost.parent_fabric_wwn = + virXPathString("string(./adapter/@parent_fabric_wwn)", ctxt); + + source->adapter.data.fchost.wwpn = + virXPathString("string(./adapter/@wwpn)", ctxt); + source->adapter.data.fchost.wwnn = + virXPathString("string(./adapter/@wwnn)", ctxt); + } else if (source->adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + + source->adapter.data.scsi_host.name = + virXPathString("string(./adapter/@name)", ctxt); + if (virXPathNode("./adapter/parentaddr", ctxt)) { + xmlNodePtr addrnode = virXPathNode("./adapter/parentaddr/address", + ctxt); + virPCIDeviceAddressPtr addr = + &source->adapter.data.scsi_host.parentaddr; + + if (!addrnode) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing scsi_host PCI address element")); + goto cleanup; + } + source->adapter.data.scsi_host.has_parent = true; + if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) + goto cleanup; + if ((virXPathInt("string(./adapter/parentaddr/@unique_id)", + ctxt, + &source->adapter.data.scsi_host.unique_id) < 0) || + (source->adapter.data.scsi_host.unique_id < 0)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing or invalid scsi adapter " + "'unique_id' value")); + goto cleanup; + } + } + } + } else { + char *wwnn = NULL; + char *wwpn = NULL; + char *parent = NULL; + + /* "type" was not specified in the XML, so we must verify that + * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the + * XML. If any are found, then we cannot just use "name" alone". + */ + wwnn = virXPathString("string(./adapter/@wwnn)", ctxt); + wwpn = virXPathString("string(./adapter/@wwpn)", ctxt); + parent = virXPathString("string(./adapter/@parent)", ctxt); + + if (wwnn || wwpn || parent) { + VIR_FREE(wwnn); + VIR_FREE(wwpn); + VIR_FREE(parent); + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'wwnn', 'wwpn', and 'parent' attributes " + "requires use of the adapter 'type'")); + goto cleanup; + } + + if (virXPathNode("./adapter/parentaddr", ctxt)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'parent' element requires use " + "of the adapter 'type'")); + goto cleanup; + } + + /* To keep back-compat, 'type' is not required to specify + * for scsi_host adapter. + */ + if ((source->adapter.data.scsi_host.name = + virXPathString("string(./adapter/@name)", ctxt))) + source->adapter.type = + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; + } + + ret = 0; + + cleanup: + VIR_FREE(adapter_type); + VIR_FREE(managed); + return ret; +} + + +static int virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, virStoragePoolSourcePtr source, int pool_type, @@ -476,8 +598,6 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, virStorageAuthDefPtr authdef = NULL; char *name = NULL; char *port = NULL; - char *adapter_type = NULL; - char *managed = NULL; int n;
relnode = ctxt->node; @@ -583,110 +703,8 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, VIR_STRDUP(source->dir, "/") < 0) goto cleanup;
- if ((adapter_type = virXPathString("string(./adapter/@type)", ctxt))) { - if ((source->adapter.type = - virStoragePoolSourceAdapterTypeFromString(adapter_type)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Unknown pool adapter type '%s'"), - adapter_type); - goto cleanup; - } - - if (source->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - source->adapter.data.fchost.parent = - virXPathString("string(./adapter/@parent)", ctxt); - managed = virXPathString("string(./adapter/@managed)", ctxt); - if (managed) { - source->adapter.data.fchost.managed = - virTristateBoolTypeFromString(managed); - if (source->adapter.data.fchost.managed < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown fc_host managed setting '%s'"), - managed); - goto cleanup; - } - } - - source->adapter.data.fchost.parent_wwnn = - virXPathString("string(./adapter/@parent_wwnn)", ctxt); - source->adapter.data.fchost.parent_wwpn = - virXPathString("string(./adapter/@parent_wwpn)", ctxt); - source->adapter.data.fchost.parent_fabric_wwn = - virXPathString("string(./adapter/@parent_fabric_wwn)", ctxt); - - source->adapter.data.fchost.wwpn = - virXPathString("string(./adapter/@wwpn)", ctxt); - source->adapter.data.fchost.wwnn = - virXPathString("string(./adapter/@wwnn)", ctxt); - } else if (source->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - - source->adapter.data.scsi_host.name = - virXPathString("string(./adapter/@name)", ctxt); - if (virXPathNode("./adapter/parentaddr", ctxt)) { - xmlNodePtr addrnode = virXPathNode("./adapter/parentaddr/address", - ctxt); - virPCIDeviceAddressPtr addr = - &source->adapter.data.scsi_host.parentaddr; - - if (!addrnode) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing scsi_host PCI address element")); - goto cleanup; - } - source->adapter.data.scsi_host.has_parent = true; - if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) - goto cleanup; - if ((virXPathInt("string(./adapter/parentaddr/@unique_id)", - ctxt, - &source->adapter.data.scsi_host.unique_id) < 0) || - (source->adapter.data.scsi_host.unique_id < 0)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing or invalid scsi adapter " - "'unique_id' value")); - goto cleanup; - } - } - } - } else { - char *wwnn = NULL; - char *wwpn = NULL; - char *parent = NULL; - - /* "type" was not specified in the XML, so we must verify that - * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the - * XML. If any are found, then we cannot just use "name" alone". - */ - wwnn = virXPathString("string(./adapter/@wwnn)", ctxt); - wwpn = virXPathString("string(./adapter/@wwpn)", ctxt); - parent = virXPathString("string(./adapter/@parent)", ctxt); - - if (wwnn || wwpn || parent) { - VIR_FREE(wwnn); - VIR_FREE(wwpn); - VIR_FREE(parent); - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'wwnn', 'wwpn', and 'parent' attributes " - "requires use of the adapter 'type'")); - goto cleanup; - } - - if (virXPathNode("./adapter/parentaddr", ctxt)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'parent' element requires use " - "of the adapter 'type'")); - goto cleanup; - } - - /* To keep back-compat, 'type' is not required to specify - * for scsi_host adapter. - */ - if ((source->adapter.data.scsi_host.name = - virXPathString("string(./adapter/@name)", ctxt))) - source->adapter.type = - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; - } + if (virStoragePoolDefParseSourceAdapter(source, ctxt) < 0) + goto cleanup;
if ((authnode = virXPathNode("./auth", ctxt))) { if (!(authdef = virStorageAuthDefParse(node->doc, authnode))) @@ -711,8 +729,6 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
VIR_FREE(port); VIR_FREE(nodeset); - VIR_FREE(adapter_type); - VIR_FREE(managed); virStorageAuthDefFree(authdef); return ret; } @@ -831,6 +847,74 @@ virStorageDefParsePerms(xmlXPathContextPtr ctxt, return ret; }
+static int +virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret)
(looking ahead, I see that at least some of this discussion is moot because you're moving/renaming the same stuff again in later patches, so take it for what its worth...) Since function naming is a hot topic these days.... The first new function you created operates on a virStoragePoolSourcePtr and is named: virStoragePoolDef Parse SourceAdapter This function operates on a virStoragePoolDefPtr and is named: virStoragePoolSourceAdapter Parse Validate So they are inconsistent about the subject of the function name vs. the argument that is passed. In the first case, it looks like all uses of the virStoragePoolSourcePtr "source" actually use "source->adapter", so you could change the function to take a virStoragePoolSourceAdapter as its arg (and then either leave it in virSubjectVerbObject format as it is, or change it to virStoragePoolSourceAdapterParse()). In the 2nd case, I think the "Parse" part is incorrect, since it's only Validating the data, not parsing it, and also, every use of the virStoragePoolDefPtr ("ret") is actually using "ret->source.adapter", so again the arg could be changed to match what's implied in the function name. But maybe you're just doing this to make it easier to verify that it's plain code motion (and that definitely *was* a help :-)). ACK based on the assumption that the arguments and function names will be made more appropriate in later patches.

On 03/11/2017 12:22 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
Split out the code that munges through the storage pool adapter into helpers - it's about to be moved into it's own source file.
This is purely code motion at this point.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 455 ++++++++++++++++++++++++++---------------------- 1 file changed, 243 insertions(+), 212 deletions(-)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 8e3b175..1993d3a 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -463,6 +463,128 @@ virStoragePoolObjRemove(virStoragePoolObjListPtr pools, }
static int +virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, + xmlXPathContextPtr ctxt) +{ + int ret = -1; + char *adapter_type = NULL; + char *managed = NULL; + + if ((adapter_type = virXPathString("string(./adapter/@type)", ctxt))) { + if ((source->adapter.type = + virStoragePoolSourceAdapterTypeFromString(adapter_type)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unknown pool adapter type '%s'"), + adapter_type); + goto cleanup; + } + + if (source->adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + source->adapter.data.fchost.parent = + virXPathString("string(./adapter/@parent)", ctxt); + managed = virXPathString("string(./adapter/@managed)", ctxt); + if (managed) { + source->adapter.data.fchost.managed = + virTristateBoolTypeFromString(managed); + if (source->adapter.data.fchost.managed < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown fc_host managed setting '%s'"), + managed); + goto cleanup; + } + } + + source->adapter.data.fchost.parent_wwnn = + virXPathString("string(./adapter/@parent_wwnn)", ctxt); + source->adapter.data.fchost.parent_wwpn = + virXPathString("string(./adapter/@parent_wwpn)", ctxt); + source->adapter.data.fchost.parent_fabric_wwn = + virXPathString("string(./adapter/@parent_fabric_wwn)", ctxt); + + source->adapter.data.fchost.wwpn = + virXPathString("string(./adapter/@wwpn)", ctxt); + source->adapter.data.fchost.wwnn = + virXPathString("string(./adapter/@wwnn)", ctxt); + } else if (source->adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + + source->adapter.data.scsi_host.name = + virXPathString("string(./adapter/@name)", ctxt); + if (virXPathNode("./adapter/parentaddr", ctxt)) { + xmlNodePtr addrnode = virXPathNode("./adapter/parentaddr/address", + ctxt); + virPCIDeviceAddressPtr addr = + &source->adapter.data.scsi_host.parentaddr; + + if (!addrnode) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing scsi_host PCI address element")); + goto cleanup; + } + source->adapter.data.scsi_host.has_parent = true; + if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) + goto cleanup; + if ((virXPathInt("string(./adapter/parentaddr/@unique_id)", + ctxt, + &source->adapter.data.scsi_host.unique_id) < 0) || + (source->adapter.data.scsi_host.unique_id < 0)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing or invalid scsi adapter " + "'unique_id' value")); + goto cleanup; + } + } + } + } else { + char *wwnn = NULL; + char *wwpn = NULL; + char *parent = NULL; + + /* "type" was not specified in the XML, so we must verify that + * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the + * XML. If any are found, then we cannot just use "name" alone". + */ + wwnn = virXPathString("string(./adapter/@wwnn)", ctxt); + wwpn = virXPathString("string(./adapter/@wwpn)", ctxt); + parent = virXPathString("string(./adapter/@parent)", ctxt); + + if (wwnn || wwpn || parent) { + VIR_FREE(wwnn); + VIR_FREE(wwpn); + VIR_FREE(parent); + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'wwnn', 'wwpn', and 'parent' attributes " + "requires use of the adapter 'type'")); + goto cleanup; + } + + if (virXPathNode("./adapter/parentaddr", ctxt)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'parent' element requires use " + "of the adapter 'type'")); + goto cleanup; + } + + /* To keep back-compat, 'type' is not required to specify + * for scsi_host adapter. + */ + if ((source->adapter.data.scsi_host.name = + virXPathString("string(./adapter/@name)", ctxt))) + source->adapter.type = + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; + } + + ret = 0; + + cleanup: + VIR_FREE(adapter_type); + VIR_FREE(managed); + return ret; +} + + +static int virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, virStoragePoolSourcePtr source, int pool_type, @@ -476,8 +598,6 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, virStorageAuthDefPtr authdef = NULL; char *name = NULL; char *port = NULL; - char *adapter_type = NULL; - char *managed = NULL; int n;
relnode = ctxt->node; @@ -583,110 +703,8 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, VIR_STRDUP(source->dir, "/") < 0) goto cleanup;
- if ((adapter_type = virXPathString("string(./adapter/@type)", ctxt))) { - if ((source->adapter.type = - virStoragePoolSourceAdapterTypeFromString(adapter_type)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Unknown pool adapter type '%s'"), - adapter_type); - goto cleanup; - } - - if (source->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - source->adapter.data.fchost.parent = - virXPathString("string(./adapter/@parent)", ctxt); - managed = virXPathString("string(./adapter/@managed)", ctxt); - if (managed) { - source->adapter.data.fchost.managed = - virTristateBoolTypeFromString(managed); - if (source->adapter.data.fchost.managed < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown fc_host managed setting '%s'"), - managed); - goto cleanup; - } - } - - source->adapter.data.fchost.parent_wwnn = - virXPathString("string(./adapter/@parent_wwnn)", ctxt); - source->adapter.data.fchost.parent_wwpn = - virXPathString("string(./adapter/@parent_wwpn)", ctxt); - source->adapter.data.fchost.parent_fabric_wwn = - virXPathString("string(./adapter/@parent_fabric_wwn)", ctxt); - - source->adapter.data.fchost.wwpn = - virXPathString("string(./adapter/@wwpn)", ctxt); - source->adapter.data.fchost.wwnn = - virXPathString("string(./adapter/@wwnn)", ctxt); - } else if (source->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - - source->adapter.data.scsi_host.name = - virXPathString("string(./adapter/@name)", ctxt); - if (virXPathNode("./adapter/parentaddr", ctxt)) { - xmlNodePtr addrnode = virXPathNode("./adapter/parentaddr/address", - ctxt); - virPCIDeviceAddressPtr addr = - &source->adapter.data.scsi_host.parentaddr; - - if (!addrnode) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing scsi_host PCI address element")); - goto cleanup; - } - source->adapter.data.scsi_host.has_parent = true; - if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) - goto cleanup; - if ((virXPathInt("string(./adapter/parentaddr/@unique_id)", - ctxt, - &source->adapter.data.scsi_host.unique_id) < 0) || - (source->adapter.data.scsi_host.unique_id < 0)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing or invalid scsi adapter " - "'unique_id' value")); - goto cleanup; - } - } - } - } else { - char *wwnn = NULL; - char *wwpn = NULL; - char *parent = NULL; - - /* "type" was not specified in the XML, so we must verify that - * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the - * XML. If any are found, then we cannot just use "name" alone". - */ - wwnn = virXPathString("string(./adapter/@wwnn)", ctxt); - wwpn = virXPathString("string(./adapter/@wwpn)", ctxt); - parent = virXPathString("string(./adapter/@parent)", ctxt); - - if (wwnn || wwpn || parent) { - VIR_FREE(wwnn); - VIR_FREE(wwpn); - VIR_FREE(parent); - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'wwnn', 'wwpn', and 'parent' attributes " - "requires use of the adapter 'type'")); - goto cleanup; - } - - if (virXPathNode("./adapter/parentaddr", ctxt)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'parent' element requires use " - "of the adapter 'type'")); - goto cleanup; - } - - /* To keep back-compat, 'type' is not required to specify - * for scsi_host adapter. - */ - if ((source->adapter.data.scsi_host.name = - virXPathString("string(./adapter/@name)", ctxt))) - source->adapter.type = - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; - } + if (virStoragePoolDefParseSourceAdapter(source, ctxt) < 0) + goto cleanup;
if ((authnode = virXPathNode("./auth", ctxt))) { if (!(authdef = virStorageAuthDefParse(node->doc, authnode))) @@ -711,8 +729,6 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt,
VIR_FREE(port); VIR_FREE(nodeset); - VIR_FREE(adapter_type); - VIR_FREE(managed); virStorageAuthDefFree(authdef); return ret; } @@ -831,6 +847,74 @@ virStorageDefParsePerms(xmlXPathContextPtr ctxt, return ret; }
+static int +virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret)
(looking ahead, I see that at least some of this discussion is moot because you're moving/renaming the same stuff again in later patches, so take it for what its worth...)
All this work started long before that discussion started... The original goal was to just be sure to remove "StoragePool" from the name because this same structure was going to be reused inside a domain controller. A vHBA "kind of" lives between a SCSI hostdev and the controller used by that hostdev. Unlike a SCSI hostdev which provides access to a single LUN via it's controller address, this thing would (or could) provide access to all the LUN's controlled by the vHBA. Of course in a way I find this strangely similar to (at least) the (early) discussions regarding how vGPU/mdev's are being presented/related. There is a single device with a "pool" (of sorts) of children devices that have use for a guest. Whether all or some are provided and how they need to be presented is something I was never clear on, but then again I wasn't paying close attention. Anyway, that's a different topic...
Since function naming is a hot topic these days....
The first new function you created operates on a virStoragePoolSourcePtr and is named:
virStoragePoolDef Parse SourceAdapter
This function operates on a virStoragePoolDefPtr and is named:
virStoragePoolSourceAdapter Parse Validate
So they are inconsistent about the subject of the function name vs. the argument that is passed.
In the first case, it looks like all uses of the virStoragePoolSourcePtr "source" actually use "source->adapter", so you could change the function to take a virStoragePoolSourceAdapter as its arg (and then either leave it in virSubjectVerbObject format as it is, or change it to virStoragePoolSourceAdapterParse()).
In the 2nd case, I think the "Parse" part is incorrect, since it's only Validating the data, not parsing it, and also, every use of the virStoragePoolDefPtr ("ret") is actually using "ret->source.adapter", so again the arg could be changed to match what's implied in the function name.
But maybe you're just doing this to make it easier to verify that it's plain code motion (and that definitely *was* a help :-)).
Well yes, these are essentially set up for code motion so I didn't have to rename the functions later. What I did was start with the patch2 from v2 and work backwards piecing things together. As I went along destructing the original body of work - I wanted to be sure I wasn't altering logic in the final target - rather only having to merge in name changes that would hopefully protect the innocent bystanders. John FWIW/IMO: These kind of functions and how we've (recently) historically name things are where some of the discussions about the proper naming start to break down. I see us spending too much time focusing on naming... What I really wouldn't want to see is a spate of patches that just start "fixing" names - that's busywork...
ACK based on the assumption that the arguments and function names will be made more appropriate in later patches.

Rather than use virXPathString, pass along an virXPathNode and alter the parsing to use virXMLPropString. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 51 ++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 1993d3a..4fa7c12 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -464,13 +464,17 @@ virStoragePoolObjRemove(virStoragePoolObjListPtr pools, static int virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, + xmlNodePtr node, xmlXPathContextPtr ctxt) { int ret = -1; + xmlNodePtr relnode = ctxt->node; char *adapter_type = NULL; char *managed = NULL; - if ((adapter_type = virXPathString("string(./adapter/@type)", ctxt))) { + ctxt->node = node; + + if ((adapter_type = virXMLPropString(node, "type"))) { if ((source->adapter.type = virStoragePoolSourceAdapterTypeFromString(adapter_type)) <= 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -482,8 +486,8 @@ virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, if (source->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { source->adapter.data.fchost.parent = - virXPathString("string(./adapter/@parent)", ctxt); - managed = virXPathString("string(./adapter/@managed)", ctxt); + virXMLPropString(node, "parent"); + managed = virXMLPropString(node, "managed"); if (managed) { source->adapter.data.fchost.managed = virTristateBoolTypeFromString(managed); @@ -496,23 +500,21 @@ virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, } source->adapter.data.fchost.parent_wwnn = - virXPathString("string(./adapter/@parent_wwnn)", ctxt); + virXMLPropString(node, "parent_wwnn"); source->adapter.data.fchost.parent_wwpn = - virXPathString("string(./adapter/@parent_wwpn)", ctxt); + virXMLPropString(node, "parent_wwpn"); source->adapter.data.fchost.parent_fabric_wwn = - virXPathString("string(./adapter/@parent_fabric_wwn)", ctxt); + virXMLPropString(node, "parent_fabric_wwn"); - source->adapter.data.fchost.wwpn = - virXPathString("string(./adapter/@wwpn)", ctxt); - source->adapter.data.fchost.wwnn = - virXPathString("string(./adapter/@wwnn)", ctxt); + source->adapter.data.fchost.wwpn = virXMLPropString(node, "wwpn"); + source->adapter.data.fchost.wwnn = virXMLPropString(node, "wwnn"); } else if (source->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { source->adapter.data.scsi_host.name = - virXPathString("string(./adapter/@name)", ctxt); - if (virXPathNode("./adapter/parentaddr", ctxt)) { - xmlNodePtr addrnode = virXPathNode("./adapter/parentaddr/address", + virXMLPropString(node, "name"); + if (virXPathNode("./parentaddr", ctxt)) { + xmlNodePtr addrnode = virXPathNode("./parentaddr/address", ctxt); virPCIDeviceAddressPtr addr = &source->adapter.data.scsi_host.parentaddr; @@ -525,7 +527,7 @@ virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, source->adapter.data.scsi_host.has_parent = true; if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) goto cleanup; - if ((virXPathInt("string(./adapter/parentaddr/@unique_id)", + if ((virXPathInt("string(./parentaddr/@unique_id)", ctxt, &source->adapter.data.scsi_host.unique_id) < 0) || (source->adapter.data.scsi_host.unique_id < 0)) { @@ -537,17 +539,14 @@ virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, } } } else { - char *wwnn = NULL; - char *wwpn = NULL; - char *parent = NULL; + char *wwnn = virXMLPropString(node, "wwnn"); + char *wwpn = virXMLPropString(node, "wwpn"); + char *parent = virXMLPropString(node, "parent"); /* "type" was not specified in the XML, so we must verify that * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the * XML. If any are found, then we cannot just use "name" alone". */ - wwnn = virXPathString("string(./adapter/@wwnn)", ctxt); - wwpn = virXPathString("string(./adapter/@wwpn)", ctxt); - parent = virXPathString("string(./adapter/@parent)", ctxt); if (wwnn || wwpn || parent) { VIR_FREE(wwnn); @@ -559,7 +558,7 @@ virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, goto cleanup; } - if (virXPathNode("./adapter/parentaddr", ctxt)) { + if (virXPathNode("./parentaddr", ctxt)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Use of 'parent' element requires use " "of the adapter 'type'")); @@ -570,7 +569,7 @@ virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, * for scsi_host adapter. */ if ((source->adapter.data.scsi_host.name = - virXPathString("string(./adapter/@name)", ctxt))) + virXMLPropString(node, "name"))) source->adapter.type = VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; } @@ -578,6 +577,7 @@ virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, ret = 0; cleanup: + ctxt->node = relnode; VIR_FREE(adapter_type); VIR_FREE(managed); return ret; @@ -592,6 +592,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, { int ret = -1; xmlNodePtr relnode, authnode, *nodeset = NULL; + xmlNodePtr adapternode; int nsource; size_t i; virStoragePoolOptionsPtr options; @@ -703,8 +704,10 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, VIR_STRDUP(source->dir, "/") < 0) goto cleanup; - if (virStoragePoolDefParseSourceAdapter(source, ctxt) < 0) - goto cleanup; + if ((adapternode = virXPathNode("./adapter", ctxt))) { + if (virStoragePoolDefParseSourceAdapter(source, adapternode, ctxt) < 0) + goto cleanup; + } if ((authnode = virXPathNode("./auth", ctxt))) { if (!(authdef = virStorageAuthDefParse(node->doc, authnode))) -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Rather than use virXPathString, pass along an virXPathNode and alter the parsing to use virXMLPropString.
Just so I understand the reasoning correctly - you're not doing this so you can use virXMLPropString() instead of virXPathString(), but just so you can remove the "adapter" from the path to each attribute (and in the cases where that turns a "path" into simply the attribute name, you're switching to virXMLPropString() because it's presumably slightly more efficient. Right? Or is there some other reason you prefer virXMLPropString()?
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 51 ++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 24 deletions(-)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 1993d3a..4fa7c12 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -464,13 +464,17 @@ virStoragePoolObjRemove(virStoragePoolObjListPtr pools,
static int virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, + xmlNodePtr node, xmlXPathContextPtr ctxt) { int ret = -1; + xmlNodePtr relnode = ctxt->node;
(This is the first time I've seen "relnode" used to save a ctxt->node. When I look through the source, the one other place I see it is in virxml.c (other places use "node", "save_node", "oldnode", "save_ctxt", "tmpnode", and on an on). Now I'm trying to figure out what "rel" stands for but nothing comes to mind. How stupid am I?)
[...]
ACK.

On 03/11/2017 08:16 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
Rather than use virXPathString, pass along an virXPathNode and alter the parsing to use virXMLPropString.
Just so I understand the reasoning correctly - you're not doing this so you can use virXMLPropString() instead of virXPathString(), but just so you can remove the "adapter" from the path to each attribute (and in the cases where that turns a "path" into simply the attribute name, you're switching to virXMLPropString() because it's presumably slightly more efficient. Right? Or is there some other reason you prefer virXMLPropString()?
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 51 ++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 24 deletions(-)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 1993d3a..4fa7c12 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -464,13 +464,17 @@ virStoragePoolObjRemove(virStoragePoolObjListPtr pools,
static int virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, + xmlNodePtr node, xmlXPathContextPtr ctxt) { int ret = -1; + xmlNodePtr relnode = ctxt->node;
(This is the first time I've seen "relnode" used to save a ctxt->node. When I look through the source, the one other place I see it is in virxml.c (other places use "node", "save_node", "oldnode", "save_ctxt", "tmpnode", and on an on). Now I'm trying to figure out what "rel" stands for but nothing comes to mind. How stupid am I?)
I can change it to tmpnode... I got it from virStoragePoolDefParseSource from a piece of the patch you snipped out: @@ -592,6 +592,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, { int ret = -1; xmlNodePtr relnode, authnode, *nodeset = NULL; + xmlNodePtr adapternode; John
[...]
ACK.

On 03/12/2017 08:42 AM, John Ferlan wrote:
(This is the first time I've seen "relnode" used to save a ctxt->node. When I look through the source, the one other place I see it is in virxml.c (other places use "node", "save_node", "oldnode", "save_ctxt", "tmpnode", and on an on). Now I'm trying to figure out what "rel" stands for but nothing comes to mind. How stupid am I?)
I can change it to tmpnode...
Nah, makes no difference to me. The "rel" must stand for something, my brain is just too muddled to figure out *what* :-)
I got it from virStoragePoolDefParseSource from a piece of the patch you snipped out:
Yep, and whoever wrote that probably got it from the ultimate reference for using libxml2 within libvirt - virxml.c.

On 03/11/2017 08:16 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
Rather than use virXPathString, pass along an virXPathNode and alter the parsing to use virXMLPropString.
Just so I understand the reasoning correctly - you're not doing this so you can use virXMLPropString() instead of virXPathString(), but just so you can remove the "adapter" from the path to each attribute (and in the cases where that turns a "path" into simply the attribute name, you're switching to virXMLPropString() because it's presumably slightly more efficient. Right? Or is there some other reason you prefer virXMLPropString()?
Missed this on the first pass through your review... Probably because your email client has stopped believing in line wrapping or my client isn't seeing some setting properly <sigh> I had originally wanted the ability to just parse an <adapter...> since that was how this would be represented in the domain; however, even though that got mothballed - I still felt what I'd done so far was at least a step up in readability, flow, etc. over what was there before. Secondary to that I find it easier to "read" the code when using virXMLPropString instead of virXPathString John
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 51 ++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 24 deletions(-)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 1993d3a..4fa7c12 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -464,13 +464,17 @@ virStoragePoolObjRemove(virStoragePoolObjListPtr pools,
static int virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, + xmlNodePtr node, xmlXPathContextPtr ctxt) { int ret = -1; + xmlNodePtr relnode = ctxt->node;
(This is the first time I've seen "relnode" used to save a ctxt->node. When I look through the source, the one other place I see it is in virxml.c (other places use "node", "save_node", "oldnode", "save_ctxt", "tmpnode", and on an on). Now I'm trying to figure out what "rel" stands for but nothing comes to mind. How stupid am I?)
[...]
ACK.

On 03/14/2017 02:30 PM, John Ferlan wrote:
On 03/11/2017 08:16 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
Rather than use virXPathString, pass along an virXPathNode and alter the parsing to use virXMLPropString. Just so I understand the reasoning correctly - you're not doing this so you can use virXMLPropString() instead of virXPathString(), but just so you can remove the "adapter" from the path to each attribute (and in the cases where that turns a "path" into simply the attribute name, you're switching to virXMLPropString() because it's presumably slightly more efficient. Right? Or is there some other reason you prefer virXMLPropString()?
Missed this on the first pass through your review... Probably because your email client has stopped believing in line wrapping or my client isn't seeing some setting properly <sigh>
Really? Oh %&*()%$*)%$... Late last week I encountered messages from someone which, when replied to, led to all of *their* quoted paragraphs in the reply each being a single very long line. So I asked about it on IRC, and Dan pointed me to some webpage claiming to know how to "fix" Thunderbird so that it worked reasonably with git-generated emails. I made the suggested changes, it didn't help, and then *I thought* I changed everything back. Apparently not :-(
I had originally wanted the ability to just parse an <adapter...> since that was how this would be represented in the domain; however, even though that got mothballed - I still felt what I'd done so far was at least a step up in readability, flow, etc. over what was there before.
Okay, so even more reason than what I'd assumed, i.e. more than enough :-)

On 03/14/2017 03:08 PM, Laine Stump wrote:
On 03/14/2017 02:30 PM, John Ferlan wrote:
On 03/11/2017 08:16 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
Rather than use virXPathString, pass along an virXPathNode and alter the parsing to use virXMLPropString. Just so I understand the reasoning correctly - you're not doing this so you can use virXMLPropString() instead of virXPathString(), but just so you can remove the "adapter" from the path to each attribute (and in the cases where that turns a "path" into simply the attribute name, you're switching to virXMLPropString() because it's presumably slightly more efficient. Right? Or is there some other reason you prefer virXMLPropString()?
Missed this on the first pass through your review... Probably because your email client has stopped believing in line wrapping or my client isn't seeing some setting properly <sigh>
Really? Oh %&*()%$*)%$...
Late last week I encountered messages from someone which, when replied to, led to all of *their* quoted paragraphs in the reply each being a single very long line. So I asked about it on IRC, and Dan pointed me to some webpage claiming to know how to "fix" Thunderbird so that it worked reasonably with git-generated emails. I made the suggested changes, it didn't help, and then *I thought* I changed everything back. Apparently not :-(
My (old) notes on this... Configuring thunderbird to wrap long lines... Make sure sends are only in TEXT format in the 'account' settings and the 'prefs' settings... Find/use the word wrap add on Use the config editor (prefs -> advanced -> config editor) to change: (You'll prefs is a dialog box, advance a tab, and you have to promise to be careful when using the config editor) ("mailnews.send_plaintext_flowed", false) Make sure the mailnews.wraplength is set at the default of 72 John
I had originally wanted the ability to just parse an <adapter...> since that was how this would be represented in the domain; however, even though that got mothballed - I still felt what I'd done so far was at least a step up in readability, flow, etc. over what was there before.
Okay, so even more reason than what I'd assumed, i.e. more than enough :-)

Move code from storage_conf into storage_adapter_conf Pure code motion Signed-off-by: John Ferlan <jferlan@redhat.com> --- po/POTFILES.in | 1 + src/Makefile.am | 1 + src/conf/storage_adapter_conf.c | 290 ++++++++++++++++++++++++++++++++++++++++ src/conf/storage_adapter_conf.h | 43 ++++++ src/conf/storage_conf.c | 253 +---------------------------------- src/libvirt_private.syms | 7 + 6 files changed, 343 insertions(+), 252 deletions(-) create mode 100644 src/conf/storage_adapter_conf.c create mode 100644 src/conf/storage_adapter_conf.h diff --git a/po/POTFILES.in b/po/POTFILES.in index ceda3ed..d802bdc 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -39,6 +39,7 @@ src/conf/nwfilter_params.c src/conf/object_event.c src/conf/secret_conf.c src/conf/snapshot_conf.c +src/conf/storage_adapter_conf.c src/conf/storage_conf.c src/conf/virchrdev.c src/conf/virdomainobjlist.c diff --git a/src/Makefile.am b/src/Makefile.am index 0257965..67db861 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -379,6 +379,7 @@ NWFILTER_CONF_SOURCES = \ # Storage driver generic impl APIs STORAGE_CONF_SOURCES = \ + conf/storage_adapter_conf.h conf/storage_adapter_conf.c \ conf/storage_conf.h conf/storage_conf.c # Interface driver generic impl APIs diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c new file mode 100644 index 0000000..3a16bcc --- /dev/null +++ b/src/conf/storage_adapter_conf.c @@ -0,0 +1,290 @@ +/* + * storage_adapter_conf.c: helpers to handle storage pool adapter manipulation + * (derived from storage_conf.c) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include "storage_adapter_conf.h" + +#include "viralloc.h" +#include "virerror.h" +#include "virlog.h" +#include "virstring.h" +#include "virutil.h" +#include "virxml.h" + +#define VIR_FROM_THIS VIR_FROM_STORAGE + +VIR_LOG_INIT("conf.storage_adapter_conf"); + +VIR_ENUM_IMPL(virStoragePoolSourceAdapter, + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_LAST, + "default", "scsi_host", "fc_host") + + +void +virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter) +{ + if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + VIR_FREE(adapter->data.fchost.wwnn); + VIR_FREE(adapter->data.fchost.wwpn); + VIR_FREE(adapter->data.fchost.parent); + VIR_FREE(adapter->data.fchost.parent_wwnn); + VIR_FREE(adapter->data.fchost.parent_wwpn); + VIR_FREE(adapter->data.fchost.parent_fabric_wwn); + } else if (adapter->type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + VIR_FREE(adapter->data.scsi_host.name); + } +} + + +int +virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, + xmlNodePtr node, + xmlXPathContextPtr ctxt) +{ + int ret = -1; + xmlNodePtr relnode = ctxt->node; + char *adapter_type = NULL; + char *managed = NULL; + + ctxt->node = node; + + if ((adapter_type = virXMLPropString(node, "type"))) { + if ((source->adapter.type = + virStoragePoolSourceAdapterTypeFromString(adapter_type)) <= 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Unknown pool adapter type '%s'"), + adapter_type); + goto cleanup; + } + + if (source->adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + source->adapter.data.fchost.parent = + virXMLPropString(node, "parent"); + managed = virXMLPropString(node, "managed"); + if (managed) { + source->adapter.data.fchost.managed = + virTristateBoolTypeFromString(managed); + if (source->adapter.data.fchost.managed < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown fc_host managed setting '%s'"), + managed); + goto cleanup; + } + } + + source->adapter.data.fchost.parent_wwnn = + virXMLPropString(node, "parent_wwnn"); + source->adapter.data.fchost.parent_wwpn = + virXMLPropString(node, "parent_wwpn"); + source->adapter.data.fchost.parent_fabric_wwn = + virXMLPropString(node, "parent_fabric_wwn"); + + source->adapter.data.fchost.wwpn = virXMLPropString(node, "wwpn"); + source->adapter.data.fchost.wwnn = virXMLPropString(node, "wwnn"); + } else if (source->adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + + source->adapter.data.scsi_host.name = + virXMLPropString(node, "name"); + if (virXPathNode("./parentaddr", ctxt)) { + xmlNodePtr addrnode = virXPathNode("./parentaddr/address", + ctxt); + virPCIDeviceAddressPtr addr = + &source->adapter.data.scsi_host.parentaddr; + + if (!addrnode) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing scsi_host PCI address element")); + goto cleanup; + } + source->adapter.data.scsi_host.has_parent = true; + if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) + goto cleanup; + if ((virXPathInt("string(./parentaddr/@unique_id)", + ctxt, + &source->adapter.data.scsi_host.unique_id) < 0) || + (source->adapter.data.scsi_host.unique_id < 0)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing or invalid scsi adapter " + "'unique_id' value")); + goto cleanup; + } + } + } + } else { + char *wwnn = virXMLPropString(node, "wwnn"); + char *wwpn = virXMLPropString(node, "wwpn"); + char *parent = virXMLPropString(node, "parent"); + + /* "type" was not specified in the XML, so we must verify that + * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the + * XML. If any are found, then we cannot just use "name" alone". + */ + + if (wwnn || wwpn || parent) { + VIR_FREE(wwnn); + VIR_FREE(wwpn); + VIR_FREE(parent); + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'wwnn', 'wwpn', and 'parent' attributes " + "requires use of the adapter 'type'")); + goto cleanup; + } + + if (virXPathNode("./parentaddr", ctxt)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'parent' element requires use " + "of the adapter 'type'")); + goto cleanup; + } + + /* To keep back-compat, 'type' is not required to specify + * for scsi_host adapter. + */ + if ((source->adapter.data.scsi_host.name = + virXMLPropString(node, "name"))) + source->adapter.type = + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; + } + + ret = 0; + + cleanup: + ctxt->node = relnode; + VIR_FREE(adapter_type); + VIR_FREE(managed); + return ret; +} + + +int +virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret) +{ + if (!ret->source.adapter.type) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing storage pool source adapter")); + return -1; + } + + if (ret->source.adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (!ret->source.adapter.data.fchost.wwnn || + !ret->source.adapter.data.fchost.wwpn) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("'wwnn' and 'wwpn' must be specified for adapter " + "type 'fchost'")); + return -1; + } + + if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || + !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) + return -1; + + if ((ret->source.adapter.data.fchost.parent_wwnn && + !ret->source.adapter.data.fchost.parent_wwpn) || + (!ret->source.adapter.data.fchost.parent_wwnn && + ret->source.adapter.data.fchost.parent_wwpn)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("must supply both parent_wwnn and " + "parent_wwpn not just one or the other")); + return -1; + } + + if (ret->source.adapter.data.fchost.parent_wwnn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_wwnn)) + return -1; + + if (ret->source.adapter.data.fchost.parent_wwpn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_wwpn)) + return -1; + + if (ret->source.adapter.data.fchost.parent_fabric_wwn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_fabric_wwn)) + return -1; + + } else if (ret->source.adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + if (!ret->source.adapter.data.scsi_host.name && + !ret->source.adapter.data.scsi_host.has_parent) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Either 'name' or 'parent' must be specified " + "for the 'scsi_host' adapter")); + return -1; + } + + if (ret->source.adapter.data.scsi_host.name && + ret->source.adapter.data.scsi_host.has_parent) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Both 'name' and 'parent' cannot be specified " + "for the 'scsi_host' adapter")); + return -1; + } + } + + return 0; +} + + +void +virStoragePoolSourceAdapterFormat(virBufferPtr buf, + virStoragePoolSourcePtr src) +{ + virBufferAsprintf(buf, "<adapter type='%s'", + virStoragePoolSourceAdapterTypeToString(src->adapter.type)); + + if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + virBufferEscapeString(buf, " parent='%s'", + src->adapter.data.fchost.parent); + if (src->adapter.data.fchost.managed) + virBufferAsprintf(buf, " managed='%s'", + virTristateBoolTypeToString(src->adapter.data.fchost.managed)); + virBufferEscapeString(buf, " parent_wwnn='%s'", + src->adapter.data.fchost.parent_wwnn); + virBufferEscapeString(buf, " parent_wwpn='%s'", + src->adapter.data.fchost.parent_wwpn); + virBufferEscapeString(buf, " parent_fabric_wwn='%s'", + src->adapter.data.fchost.parent_fabric_wwn); + + virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", + src->adapter.data.fchost.wwnn, + src->adapter.data.fchost.wwpn); + } else if (src->adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + if (src->adapter.data.scsi_host.name) { + virBufferAsprintf(buf, " name='%s'/>\n", + src->adapter.data.scsi_host.name); + } else { + virPCIDeviceAddress addr; + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "<parentaddr unique_id='%d'>\n", + src->adapter.data.scsi_host.unique_id); + virBufferAdjustIndent(buf, 2); + addr = src->adapter.data.scsi_host.parentaddr; + ignore_value(virPCIDeviceAddressFormat(buf, addr, false)); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</parentaddr>\n"); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</adapter>\n"); + } + } +} diff --git a/src/conf/storage_adapter_conf.h b/src/conf/storage_adapter_conf.h new file mode 100644 index 0000000..dec2f18 --- /dev/null +++ b/src/conf/storage_adapter_conf.h @@ -0,0 +1,43 @@ +/* + * storage_adapter_conf.h: helpers to handle storage pool adapter manipulation + * (derived from storage_conf.h) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * <http://www.gnu.org/licenses/>. + */ + +#ifndef __VIR_STORAGE_ADAPTER_CONF_H__ +# define __VIR_STORAGE_ADAPTER_CONF_H__ + +# include "virpci.h" +# include "virxml.h" + +# include "storage_conf.h" + +void +virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter); + +int +virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, + xmlNodePtr node, + xmlXPathContextPtr ctxt); + +int +virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret); + +void +virStoragePoolSourceAdapterFormat(virBufferPtr buf, + virStoragePoolSourcePtr src); + +#endif /* __VIR_STORAGE_ADAPTER_CONF_H__ */ diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 4fa7c12..9314504 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -36,6 +36,7 @@ #include "virerror.h" #include "datatypes.h" #include "node_device_conf.h" +#include "storage_adapter_conf.h" #include "storage_conf.h" #include "virstoragefile.h" @@ -100,10 +101,6 @@ VIR_ENUM_IMPL(virStoragePartedFs, "ext2", "ext2", "extended") -VIR_ENUM_IMPL(virStoragePoolSourceAdapter, - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_LAST, - "default", "scsi_host", "fc_host") - typedef const char *(*virStorageVolFormatToString)(int format); typedef int (*virStorageVolFormatFromString)(const char *format); @@ -342,22 +339,6 @@ virStorageVolDefFree(virStorageVolDefPtr def) VIR_FREE(def); } -static void -virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter) -{ - if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - VIR_FREE(adapter->data.fchost.wwnn); - VIR_FREE(adapter->data.fchost.wwpn); - VIR_FREE(adapter->data.fchost.parent); - VIR_FREE(adapter->data.fchost.parent_wwnn); - VIR_FREE(adapter->data.fchost.parent_wwpn); - VIR_FREE(adapter->data.fchost.parent_fabric_wwn); - } else if (adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - VIR_FREE(adapter->data.scsi_host.name); - } -} - void virStoragePoolSourceDeviceClear(virStoragePoolSourceDevicePtr dev) { @@ -462,127 +443,6 @@ virStoragePoolObjRemove(virStoragePoolObjListPtr pools, } } -static int -virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, - xmlNodePtr node, - xmlXPathContextPtr ctxt) -{ - int ret = -1; - xmlNodePtr relnode = ctxt->node; - char *adapter_type = NULL; - char *managed = NULL; - - ctxt->node = node; - - if ((adapter_type = virXMLPropString(node, "type"))) { - if ((source->adapter.type = - virStoragePoolSourceAdapterTypeFromString(adapter_type)) <= 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("Unknown pool adapter type '%s'"), - adapter_type); - goto cleanup; - } - - if (source->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - source->adapter.data.fchost.parent = - virXMLPropString(node, "parent"); - managed = virXMLPropString(node, "managed"); - if (managed) { - source->adapter.data.fchost.managed = - virTristateBoolTypeFromString(managed); - if (source->adapter.data.fchost.managed < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown fc_host managed setting '%s'"), - managed); - goto cleanup; - } - } - - source->adapter.data.fchost.parent_wwnn = - virXMLPropString(node, "parent_wwnn"); - source->adapter.data.fchost.parent_wwpn = - virXMLPropString(node, "parent_wwpn"); - source->adapter.data.fchost.parent_fabric_wwn = - virXMLPropString(node, "parent_fabric_wwn"); - - source->adapter.data.fchost.wwpn = virXMLPropString(node, "wwpn"); - source->adapter.data.fchost.wwnn = virXMLPropString(node, "wwnn"); - } else if (source->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - - source->adapter.data.scsi_host.name = - virXMLPropString(node, "name"); - if (virXPathNode("./parentaddr", ctxt)) { - xmlNodePtr addrnode = virXPathNode("./parentaddr/address", - ctxt); - virPCIDeviceAddressPtr addr = - &source->adapter.data.scsi_host.parentaddr; - - if (!addrnode) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing scsi_host PCI address element")); - goto cleanup; - } - source->adapter.data.scsi_host.has_parent = true; - if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) - goto cleanup; - if ((virXPathInt("string(./parentaddr/@unique_id)", - ctxt, - &source->adapter.data.scsi_host.unique_id) < 0) || - (source->adapter.data.scsi_host.unique_id < 0)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing or invalid scsi adapter " - "'unique_id' value")); - goto cleanup; - } - } - } - } else { - char *wwnn = virXMLPropString(node, "wwnn"); - char *wwpn = virXMLPropString(node, "wwpn"); - char *parent = virXMLPropString(node, "parent"); - - /* "type" was not specified in the XML, so we must verify that - * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the - * XML. If any are found, then we cannot just use "name" alone". - */ - - if (wwnn || wwpn || parent) { - VIR_FREE(wwnn); - VIR_FREE(wwpn); - VIR_FREE(parent); - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'wwnn', 'wwpn', and 'parent' attributes " - "requires use of the adapter 'type'")); - goto cleanup; - } - - if (virXPathNode("./parentaddr", ctxt)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'parent' element requires use " - "of the adapter 'type'")); - goto cleanup; - } - - /* To keep back-compat, 'type' is not required to specify - * for scsi_host adapter. - */ - if ((source->adapter.data.scsi_host.name = - virXMLPropString(node, "name"))) - source->adapter.type = - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; - } - - ret = 0; - - cleanup: - ctxt->node = relnode; - VIR_FREE(adapter_type); - VIR_FREE(managed); - return ret; -} - static int virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, @@ -850,73 +710,6 @@ virStorageDefParsePerms(xmlXPathContextPtr ctxt, return ret; } -static int -virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret) -{ - if (!ret->source.adapter.type) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing storage pool source adapter")); - return -1; - } - - if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (!ret->source.adapter.data.fchost.wwnn || - !ret->source.adapter.data.fchost.wwpn) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("'wwnn' and 'wwpn' must be specified for adapter " - "type 'fchost'")); - return -1; - } - - if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || - !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) - return -1; - - if ((ret->source.adapter.data.fchost.parent_wwnn && - !ret->source.adapter.data.fchost.parent_wwpn) || - (!ret->source.adapter.data.fchost.parent_wwnn && - ret->source.adapter.data.fchost.parent_wwpn)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("must supply both parent_wwnn and " - "parent_wwpn not just one or the other")); - return -1; - } - - if (ret->source.adapter.data.fchost.parent_wwnn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_wwnn)) - return -1; - - if (ret->source.adapter.data.fchost.parent_wwpn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_wwpn)) - return -1; - - if (ret->source.adapter.data.fchost.parent_fabric_wwn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_fabric_wwn)) - return -1; - - } else if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (!ret->source.adapter.data.scsi_host.name && - !ret->source.adapter.data.scsi_host.has_parent) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Either 'name' or 'parent' must be specified " - "for the 'scsi_host' adapter")); - return -1; - } - - if (ret->source.adapter.data.scsi_host.name && - ret->source.adapter.data.scsi_host.has_parent) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Both 'name' and 'parent' cannot be specified " - "for the 'scsi_host' adapter")); - return -1; - } - } - - return 0; -} - static virStoragePoolDefPtr virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) @@ -1114,50 +907,6 @@ virStoragePoolDefParseFile(const char *filename) return virStoragePoolDefParse(NULL, filename); } -static void -virStoragePoolSourceAdapterFormat(virBufferPtr buf, - virStoragePoolSourcePtr src) -{ - virBufferAsprintf(buf, "<adapter type='%s'", - virStoragePoolSourceAdapterTypeToString(src->adapter.type)); - - if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - virBufferEscapeString(buf, " parent='%s'", - src->adapter.data.fchost.parent); - if (src->adapter.data.fchost.managed) - virBufferAsprintf(buf, " managed='%s'", - virTristateBoolTypeToString(src->adapter.data.fchost.managed)); - virBufferEscapeString(buf, " parent_wwnn='%s'", - src->adapter.data.fchost.parent_wwnn); - virBufferEscapeString(buf, " parent_wwpn='%s'", - src->adapter.data.fchost.parent_wwpn); - virBufferEscapeString(buf, " parent_fabric_wwn='%s'", - src->adapter.data.fchost.parent_fabric_wwn); - - virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", - src->adapter.data.fchost.wwnn, - src->adapter.data.fchost.wwpn); - } else if (src->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (src->adapter.data.scsi_host.name) { - virBufferAsprintf(buf, " name='%s'/>\n", - src->adapter.data.scsi_host.name); - } else { - virPCIDeviceAddress addr; - virBufferAddLit(buf, ">\n"); - virBufferAdjustIndent(buf, 2); - virBufferAsprintf(buf, "<parentaddr unique_id='%d'>\n", - src->adapter.data.scsi_host.unique_id); - virBufferAdjustIndent(buf, 2); - addr = src->adapter.data.scsi_host.parentaddr; - ignore_value(virPCIDeviceAddressFormat(buf, addr, false)); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</parentaddr>\n"); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</adapter>\n"); - } - } -} static int virStoragePoolSourceFormat(virBufferPtr buf, diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6c89d44..76cf2ae 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -847,6 +847,13 @@ virDomainSnapshotStateTypeToString; virDomainSnapshotUpdateRelations; +# conf/storage_adapter_conf.h +virStoragePoolDefParseSourceAdapter; +virStoragePoolSourceAdapterClear; +virStoragePoolSourceAdapterFormat; +virStoragePoolSourceAdapterParseValidate; + + # conf/storage_conf.h virStoragePartedFsTypeToString; virStoragePoolDefFormat; -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Move code from storage_conf into storage_adapter_conf
Pure code motion
Signed-off-by: John Ferlan <jferlan@redhat.com>
ACK. (Function naming vs argument type is inconsistent, but again I'm assuming that will be fixed later, and this patch was purposefully done with no renaming to make it easy to review)

Rename the API's to remove the storage pool source pieces Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 14 +++++++------- src/conf/storage_adapter_conf.h | 14 +++++++------- src/conf/storage_conf.c | 8 ++++---- src/libvirt_private.syms | 8 ++++---- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index 3a16bcc..4f5b665 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -38,7 +38,7 @@ VIR_ENUM_IMPL(virStoragePoolSourceAdapter, void -virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter) +virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) { if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { VIR_FREE(adapter->data.fchost.wwnn); @@ -55,9 +55,9 @@ virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter) int -virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, - xmlNodePtr node, - xmlXPathContextPtr ctxt) +virStorageAdapterParseXML(virStoragePoolSourcePtr source, + xmlNodePtr node, + xmlXPathContextPtr ctxt) { int ret = -1; xmlNodePtr relnode = ctxt->node; @@ -177,7 +177,7 @@ virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, int -virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret) +virStorageAdapterParseValidate(virStoragePoolDefPtr ret) { if (!ret->source.adapter.type) { virReportError(VIR_ERR_XML_ERROR, "%s", @@ -245,8 +245,8 @@ virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret) void -virStoragePoolSourceAdapterFormat(virBufferPtr buf, - virStoragePoolSourcePtr src) +virStorageAdapterFormat(virBufferPtr buf, + virStoragePoolSourcePtr src) { virBufferAsprintf(buf, "<adapter type='%s'", virStoragePoolSourceAdapterTypeToString(src->adapter.type)); diff --git a/src/conf/storage_adapter_conf.h b/src/conf/storage_adapter_conf.h index dec2f18..ec812a1 100644 --- a/src/conf/storage_adapter_conf.h +++ b/src/conf/storage_adapter_conf.h @@ -26,18 +26,18 @@ # include "storage_conf.h" void -virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter); +virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter); int -virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, - xmlNodePtr node, - xmlXPathContextPtr ctxt); +virStorageAdapterParseXML(virStoragePoolSourcePtr source, + xmlNodePtr node, + xmlXPathContextPtr ctxt); int -virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret); +virStorageAdapterParseValidate(virStoragePoolDefPtr ret); void -virStoragePoolSourceAdapterFormat(virBufferPtr buf, - virStoragePoolSourcePtr src); +virStorageAdapterFormat(virBufferPtr buf, + virStoragePoolSourcePtr src); #endif /* __VIR_STORAGE_ADAPTER_CONF_H__ */ diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 9314504..8709101 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -363,7 +363,7 @@ virStoragePoolSourceClear(virStoragePoolSourcePtr source) VIR_FREE(source->devices); VIR_FREE(source->dir); VIR_FREE(source->name); - virStoragePoolSourceAdapterClear(&source->adapter); + virStorageAdapterClear(&source->adapter); VIR_FREE(source->initiator.iqn); virStorageAuthDefFree(source->auth); VIR_FREE(source->vendor); @@ -565,7 +565,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, goto cleanup; if ((adapternode = virXPathNode("./adapter", ctxt))) { - if (virStoragePoolDefParseSourceAdapter(source, adapternode, ctxt) < 0) + if (virStorageAdapterParseXML(source, adapternode, ctxt) < 0) goto cleanup; } @@ -802,7 +802,7 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) } if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) && - (virStoragePoolSourceAdapterParseValidate(ret)) < 0) + (virStorageAdapterParseValidate(ret)) < 0) goto error; /* If DEVICE is the only source type, then its required */ @@ -960,7 +960,7 @@ virStoragePoolSourceFormat(virBufferPtr buf, if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) && (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST || src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST)) - virStoragePoolSourceAdapterFormat(buf, src); + virStorageAdapterFormat(buf, src); if (options->flags & VIR_STORAGE_POOL_SOURCE_NAME) virBufferEscapeString(buf, "<name>%s</name>\n", src->name); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 76cf2ae..6a2bdf2 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -848,10 +848,10 @@ virDomainSnapshotUpdateRelations; # conf/storage_adapter_conf.h -virStoragePoolDefParseSourceAdapter; -virStoragePoolSourceAdapterClear; -virStoragePoolSourceAdapterFormat; -virStoragePoolSourceAdapterParseValidate; +virStorageAdapterClear; +virStorageAdapterFormat; +virStorageAdapterParseValidate; +virStorageAdapterParseXML; # conf/storage_conf.h -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Rename the API's to remove the storage pool source pieces
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 14 +++++++------- src/conf/storage_adapter_conf.h | 14 +++++++------- src/conf/storage_conf.c | 8 ++++---- src/libvirt_private.syms | 8 ++++---- 4 files changed, 22 insertions(+), 22 deletions(-)
ACK.

Ah, but wait! I ACKed this too soon! *This* is the patch that's renaming the functions. It should be changing the arguments in some cases too (and at least one of the names seems wrong). On 03/10/2017 04:10 PM, John Ferlan wrote:
Rename the API's to remove the storage pool source pieces
Yeah, if it's consistent in all cases, I can agree with that...
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 14 +++++++------- src/conf/storage_adapter_conf.h | 14 +++++++------- src/conf/storage_conf.c | 8 ++++---- src/libvirt_private.syms | 8 ++++---- 4 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index 3a16bcc..4f5b665 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -38,7 +38,7 @@ VIR_ENUM_IMPL(virStoragePoolSourceAdapter,
void -virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter) +virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) { if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { VIR_FREE(adapter->data.fchost.wwnn); @@ -55,9 +55,9 @@ virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter)
int -virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, - xmlNodePtr node, - xmlXPathContextPtr ctxt) +virStorageAdapterParseXML(virStoragePoolSourcePtr source, + xmlNodePtr node, + xmlXPathContextPtr ctxt)
This function should take a virStoragePoolSourceAdapterPtr rather than a virStoragePoolSourcePtr.
{ int ret = -1; xmlNodePtr relnode = ctxt->node; @@ -177,7 +177,7 @@ virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source,
int -virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret) +virStorageAdapterParseValidate(virStoragePoolDefPtr ret)
This function should take a virStoragePoolSourceAdapterPtr rather than virStoragePoolDefPtr, and the name should just be "virStorageAdapterValidate(), since the parsing is already finished, and this function just validates.
{ if (!ret->source.adapter.type) { virReportError(VIR_ERR_XML_ERROR, "%s", @@ -245,8 +245,8 @@ virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret)
void -virStoragePoolSourceAdapterFormat(virBufferPtr buf, - virStoragePoolSourcePtr src) +virStorageAdapterFormat(virBufferPtr buf, + virStoragePoolSourcePtr src)
Again - the arg should be virStoragePoolSourceAdapterPtr.
{ virBufferAsprintf(buf, "<adapter type='%s'", virStoragePoolSourceAdapterTypeToString(src->adapter.type)); diff --git a/src/conf/storage_adapter_conf.h b/src/conf/storage_adapter_conf.h index dec2f18..ec812a1 100644 --- a/src/conf/storage_adapter_conf.h +++ b/src/conf/storage_adapter_conf.h @@ -26,18 +26,18 @@ # include "storage_conf.h"
void -virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter); +virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter);
int -virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, - xmlNodePtr node, - xmlXPathContextPtr ctxt); +virStorageAdapterParseXML(virStoragePoolSourcePtr source, + xmlNodePtr node, + xmlXPathContextPtr ctxt);
same
int -virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret); +virStorageAdapterParseValidate(virStoragePoolDefPtr ret);
void -virStoragePoolSourceAdapterFormat(virBufferPtr buf, - virStoragePoolSourcePtr src); +virStorageAdapterFormat(virBufferPtr buf, + virStoragePoolSourcePtr src);
#endif /* __VIR_STORAGE_ADAPTER_CONF_H__ */ diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 9314504..8709101 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -363,7 +363,7 @@ virStoragePoolSourceClear(virStoragePoolSourcePtr source) VIR_FREE(source->devices); VIR_FREE(source->dir); VIR_FREE(source->name); - virStoragePoolSourceAdapterClear(&source->adapter); + virStorageAdapterClear(&source->adapter); VIR_FREE(source->initiator.iqn); virStorageAuthDefFree(source->auth); VIR_FREE(source->vendor); @@ -565,7 +565,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, goto cleanup;
if ((adapternode = virXPathNode("./adapter", ctxt))) { - if (virStoragePoolDefParseSourceAdapter(source, adapternode, ctxt) < 0) + if (virStorageAdapterParseXML(source, adapternode, ctxt) < 0) goto cleanup; }
@@ -802,7 +802,7 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) }
if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) && - (virStoragePoolSourceAdapterParseValidate(ret)) < 0) + (virStorageAdapterParseValidate(ret)) < 0) goto error;
/* If DEVICE is the only source type, then its required */ @@ -960,7 +960,7 @@ virStoragePoolSourceFormat(virBufferPtr buf, if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) && (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST || src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST)) - virStoragePoolSourceAdapterFormat(buf, src); + virStorageAdapterFormat(buf, src);
if (options->flags & VIR_STORAGE_POOL_SOURCE_NAME) virBufferEscapeString(buf, "<name>%s</name>\n", src->name); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 76cf2ae..6a2bdf2 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -848,10 +848,10 @@ virDomainSnapshotUpdateRelations;
# conf/storage_adapter_conf.h -virStoragePoolDefParseSourceAdapter; -virStoragePoolSourceAdapterClear; -virStoragePoolSourceAdapterFormat; -virStoragePoolSourceAdapterParseValidate; +virStorageAdapterClear; +virStorageAdapterFormat; +virStorageAdapterParseValidate; +virStorageAdapterParseXML;
# conf/storage_conf.h

On 03/11/2017 09:41 PM, Laine Stump wrote:
Ah, but wait! I ACKed this too soon! *This* is the patch that's renaming the functions. It should be changing the arguments in some cases too (and at least one of the names seems wrong).
On 03/10/2017 04:10 PM, John Ferlan wrote:
Rename the API's to remove the storage pool source pieces
Yeah, if it's consistent in all cases, I can agree with that...
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 14 +++++++------- src/conf/storage_adapter_conf.h | 14 +++++++------- src/conf/storage_conf.c | 8 ++++---- src/libvirt_private.syms | 8 ++++---- 4 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index 3a16bcc..4f5b665 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -38,7 +38,7 @@ VIR_ENUM_IMPL(virStoragePoolSourceAdapter,
void -virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter) +virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) { if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { VIR_FREE(adapter->data.fchost.wwnn); @@ -55,9 +55,9 @@ virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter)
int -virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, - xmlNodePtr node, - xmlXPathContextPtr ctxt) +virStorageAdapterParseXML(virStoragePoolSourcePtr source, + xmlNodePtr node, + xmlXPathContextPtr ctxt)
This function should take a virStoragePoolSourceAdapterPtr rather than a virStoragePoolSourcePtr.
{ int ret = -1; xmlNodePtr relnode = ctxt->node; @@ -177,7 +177,7 @@ virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source,
int -virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret) +virStorageAdapterParseValidate(virStoragePoolDefPtr ret)
This function should take a virStoragePoolSourceAdapterPtr rather than virStoragePoolDefPtr, and the name should just be "virStorageAdapterValidate(), since the parsing is already finished, and this function just validates.
I'd prefer to use virStorageAdapterValidateParse() - as that what it's doing validating that the parse was correct. So is this is a case where a verb can turn into an adverb? (it's a grammar question!) I don't think there's any "order" I could choose other than a really painful use a long name now only to change to a shorter name approach in later patches. I'd like to reduce the amount of churn though just for the sake of "name sanity" between the steps that no one will care about except when they have to backport something... In which case, gitk is your friend because it really makes the what changed when lookup simple. John
{ if (!ret->source.adapter.type) { virReportError(VIR_ERR_XML_ERROR, "%s", @@ -245,8 +245,8 @@ virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret)
void -virStoragePoolSourceAdapterFormat(virBufferPtr buf, - virStoragePoolSourcePtr src) +virStorageAdapterFormat(virBufferPtr buf, + virStoragePoolSourcePtr src)
Again - the arg should be virStoragePoolSourceAdapterPtr.
{ virBufferAsprintf(buf, "<adapter type='%s'", virStoragePoolSourceAdapterTypeToString(src->adapter.type)); diff --git a/src/conf/storage_adapter_conf.h b/src/conf/storage_adapter_conf.h index dec2f18..ec812a1 100644 --- a/src/conf/storage_adapter_conf.h +++ b/src/conf/storage_adapter_conf.h @@ -26,18 +26,18 @@ # include "storage_conf.h"
void -virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter); +virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter);
int -virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, - xmlNodePtr node, - xmlXPathContextPtr ctxt); +virStorageAdapterParseXML(virStoragePoolSourcePtr source, + xmlNodePtr node, + xmlXPathContextPtr ctxt);
same
int -virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret); +virStorageAdapterParseValidate(virStoragePoolDefPtr ret);
void -virStoragePoolSourceAdapterFormat(virBufferPtr buf, - virStoragePoolSourcePtr src); +virStorageAdapterFormat(virBufferPtr buf, + virStoragePoolSourcePtr src);
#endif /* __VIR_STORAGE_ADAPTER_CONF_H__ */ diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 9314504..8709101 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -363,7 +363,7 @@ virStoragePoolSourceClear(virStoragePoolSourcePtr source) VIR_FREE(source->devices); VIR_FREE(source->dir); VIR_FREE(source->name); - virStoragePoolSourceAdapterClear(&source->adapter); + virStorageAdapterClear(&source->adapter); VIR_FREE(source->initiator.iqn); virStorageAuthDefFree(source->auth); VIR_FREE(source->vendor); @@ -565,7 +565,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, goto cleanup;
if ((adapternode = virXPathNode("./adapter", ctxt))) { - if (virStoragePoolDefParseSourceAdapter(source, adapternode, ctxt) < 0) + if (virStorageAdapterParseXML(source, adapternode, ctxt) < 0) goto cleanup; }
@@ -802,7 +802,7 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) }
if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) && - (virStoragePoolSourceAdapterParseValidate(ret)) < 0) + (virStorageAdapterParseValidate(ret)) < 0) goto error;
/* If DEVICE is the only source type, then its required */ @@ -960,7 +960,7 @@ virStoragePoolSourceFormat(virBufferPtr buf, if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) && (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST || src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST)) - virStoragePoolSourceAdapterFormat(buf, src); + virStorageAdapterFormat(buf, src);
if (options->flags & VIR_STORAGE_POOL_SOURCE_NAME) virBufferEscapeString(buf, "<name>%s</name>\n", src->name); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 76cf2ae..6a2bdf2 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -848,10 +848,10 @@ virDomainSnapshotUpdateRelations;
# conf/storage_adapter_conf.h -virStoragePoolDefParseSourceAdapter; -virStoragePoolSourceAdapterClear; -virStoragePoolSourceAdapterFormat; -virStoragePoolSourceAdapterParseValidate; +virStorageAdapterClear; +virStorageAdapterFormat; +virStorageAdapterParseValidate; +virStorageAdapterParseXML;
# conf/storage_conf.h

On 03/14/2017 07:05 PM, John Ferlan wrote:
On 03/11/2017 09:41 PM, Laine Stump wrote:
Ah, but wait! I ACKed this too soon! *This* is the patch that's renaming the functions. It should be changing the arguments in some cases too (and at least one of the names seems wrong).
On 03/10/2017 04:10 PM, John Ferlan wrote:
Rename the API's to remove the storage pool source pieces Yeah, if it's consistent in all cases, I can agree with that...
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 14 +++++++------- src/conf/storage_adapter_conf.h | 14 +++++++------- src/conf/storage_conf.c | 8 ++++---- src/libvirt_private.syms | 8 ++++---- 4 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index 3a16bcc..4f5b665 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -38,7 +38,7 @@ VIR_ENUM_IMPL(virStoragePoolSourceAdapter,
void -virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter) +virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) { if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { VIR_FREE(adapter->data.fchost.wwnn); @@ -55,9 +55,9 @@ virStoragePoolSourceAdapterClear(virStoragePoolSourceAdapterPtr adapter)
int -virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source, - xmlNodePtr node, - xmlXPathContextPtr ctxt) +virStorageAdapterParseXML(virStoragePoolSourcePtr source, + xmlNodePtr node, + xmlXPathContextPtr ctxt) This function should take a virStoragePoolSourceAdapterPtr rather than a virStoragePoolSourcePtr.
{ int ret = -1; xmlNodePtr relnode = ctxt->node; @@ -177,7 +177,7 @@ virStoragePoolDefParseSourceAdapter(virStoragePoolSourcePtr source,
int -virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret) +virStorageAdapterParseValidate(virStoragePoolDefPtr ret)
This function should take a virStoragePoolSourceAdapterPtr rather than virStoragePoolDefPtr, and the name should just be "virStorageAdapterValidate(), since the parsing is already finished, and this function just validates.
I'd prefer to use virStorageAdapterValidateParse() - as that what it's doing validating that the parse was correct. So is this is a case where a verb can turn into an adverb? (it's a grammar question!)
Yeah, that name makes sense once you explain it. Maybe. Is it really validating that the parse was done correctly? Or is it just validating that the data in the object meets various criteria? Seems like it's the latter. Would you really want to validate the object any differently if it had just been parsed from XML vs. if the object was generated in some other manner? (e.g. some chunk of C code that created the object and filled in attributes programmatically)
I don't think there's any "order" I could choose other than a really painful use a long name now only to change to a shorter name approach in later patches.
Yeah, I didn't look ahead when I started reviewing the series, so I didn't realize what the end product was going to be. *A lot* of my comments are moot in light of that.
I'd like to reduce the amount of churn though just for the sake of "name sanity" between the steps that no one will care about except when they have to backport something... In which case, gitk is your friend because it really makes the what changed when lookup simple.
I've stared straight at it for multiple years now, but just last week thought to try out for the first time the "old Version" and "new Version" buttons in gitk - combine those with a very large number for context lines, and it is truly very useful. Another nice way to look at diffs is with "git difftool -d -t meld revA..revB". I haven't found a simple way to move from one commit to the next, but once it's displayed it is a very nice format. (while on the topic of tools, what I would *really* like is a tool like gitk where you could select a chunk and drag it from one commit to another, or drag entire commits around to change the order on a branch, or copy a commit or group of commits from one branch to another (essentially something that would do an entire "git rebase -i master" or "git cherry-pick" at the drag of a mouse). Any suggestions?

[...]
int -virStoragePoolSourceAdapterParseValidate(virStoragePoolDefPtr ret) +virStorageAdapterParseValidate(virStoragePoolDefPtr ret)
This function should take a virStoragePoolSourceAdapterPtr rather than virStoragePoolDefPtr, and the name should just be "virStorageAdapterValidate(), since the parsing is already finished, and this function just validates.
I'd prefer to use virStorageAdapterValidateParse() - as that what it's doing validating that the parse was correct. So is this is a case where a verb can turn into an adverb? (it's a grammar question!)
Yeah, that name makes sense once you explain it. Maybe. Is it really validating that the parse was done correctly? Or is it just validating that the data in the object meets various criteria? Seems like it's the latter. Would you really want to validate the object any differently if it had just been parsed from XML vs. if the object was generated in some other manner? (e.g. some chunk of C code that created the object and filled in attributes programmatically)
Fair enough - I'll just change to Validate, but while working through merge conflicts in my branch I ran into virDomainDiskDefParseValidate It's a change that wasn't sent with this series, but I think I know now where I got the name originally. John

Rather than have lots of ugly inline code create helpers to try and make things more readable. While creating the helpers realign the code as necessary. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 194 +++++++++++++++++++++++----------------- 1 file changed, 114 insertions(+), 80 deletions(-) diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index 4f5b665..a2d4a3a 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -37,16 +37,23 @@ VIR_ENUM_IMPL(virStoragePoolSourceAdapter, "default", "scsi_host", "fc_host") +static void +virStorageAdapterFCHostClear(virStoragePoolSourceAdapterPtr adapter) +{ + VIR_FREE(adapter->data.fchost.wwnn); + VIR_FREE(adapter->data.fchost.wwpn); + VIR_FREE(adapter->data.fchost.parent); + VIR_FREE(adapter->data.fchost.parent_wwnn); + VIR_FREE(adapter->data.fchost.parent_wwpn); + VIR_FREE(adapter->data.fchost.parent_fabric_wwn); +} + + void virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) { if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - VIR_FREE(adapter->data.fchost.wwnn); - VIR_FREE(adapter->data.fchost.wwpn); - VIR_FREE(adapter->data.fchost.parent); - VIR_FREE(adapter->data.fchost.parent_wwnn); - VIR_FREE(adapter->data.fchost.parent_wwpn); - VIR_FREE(adapter->data.fchost.parent_fabric_wwn); + virStorageAdapterFCHostClear(adapter); } else if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { VIR_FREE(adapter->data.scsi_host.name); @@ -54,6 +61,40 @@ virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) } +static int +virStorageAdapterFCHostParseXML(xmlNodePtr node, + virStoragePoolSourcePtr source) +{ + char *managed = NULL; + + source->adapter.data.fchost.parent = virXMLPropString(node, "parent"); + if ((managed = virXMLPropString(node, "managed"))) { + source->adapter.data.fchost.managed = + virTristateBoolTypeFromString(managed); + if (source->adapter.data.fchost.managed < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown fc_host managed setting '%s'"), + managed); + VIR_FREE(managed); + return -1; + } + } + + source->adapter.data.fchost.parent_wwnn = + virXMLPropString(node, "parent_wwnn"); + source->adapter.data.fchost.parent_wwpn = + virXMLPropString(node, "parent_wwpn"); + source->adapter.data.fchost.parent_fabric_wwn = + virXMLPropString(node, "parent_fabric_wwn"); + + source->adapter.data.fchost.wwpn = virXMLPropString(node, "wwpn"); + source->adapter.data.fchost.wwnn = virXMLPropString(node, "wwnn"); + + VIR_FREE(managed); + return 0; +} + + int virStorageAdapterParseXML(virStoragePoolSourcePtr source, xmlNodePtr node, @@ -62,7 +103,6 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, int ret = -1; xmlNodePtr relnode = ctxt->node; char *adapter_type = NULL; - char *managed = NULL; ctxt->node = node; @@ -77,29 +117,8 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, if (source->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - source->adapter.data.fchost.parent = - virXMLPropString(node, "parent"); - managed = virXMLPropString(node, "managed"); - if (managed) { - source->adapter.data.fchost.managed = - virTristateBoolTypeFromString(managed); - if (source->adapter.data.fchost.managed < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown fc_host managed setting '%s'"), - managed); - goto cleanup; - } - } - - source->adapter.data.fchost.parent_wwnn = - virXMLPropString(node, "parent_wwnn"); - source->adapter.data.fchost.parent_wwpn = - virXMLPropString(node, "parent_wwpn"); - source->adapter.data.fchost.parent_fabric_wwn = - virXMLPropString(node, "parent_fabric_wwn"); - - source->adapter.data.fchost.wwpn = virXMLPropString(node, "wwpn"); - source->adapter.data.fchost.wwnn = virXMLPropString(node, "wwnn"); + if (virStorageAdapterFCHostParseXML(node, source) < 0) + goto cleanup; } else if (source->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { @@ -171,56 +190,63 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, cleanup: ctxt->node = relnode; VIR_FREE(adapter_type); - VIR_FREE(managed); return ret; } -int -virStorageAdapterParseValidate(virStoragePoolDefPtr ret) +static int +virStorageAdapterFCHostParseValidate(virStoragePoolDefPtr ret) { - if (!ret->source.adapter.type) { + if (!ret->source.adapter.data.fchost.wwnn || + !ret->source.adapter.data.fchost.wwpn) { virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing storage pool source adapter")); + _("'wwnn' and 'wwpn' must be specified for adapter " + "type 'fchost'")); return -1; } - if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (!ret->source.adapter.data.fchost.wwnn || - !ret->source.adapter.data.fchost.wwpn) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("'wwnn' and 'wwpn' must be specified for adapter " - "type 'fchost'")); - return -1; - } + if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || + !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) + return -1; - if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || - !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) - return -1; + if ((ret->source.adapter.data.fchost.parent_wwnn && + !ret->source.adapter.data.fchost.parent_wwpn) || + (!ret->source.adapter.data.fchost.parent_wwnn && + ret->source.adapter.data.fchost.parent_wwpn)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("must supply both parent_wwnn and " + "parent_wwpn not just one or the other")); + return -1; + } - if ((ret->source.adapter.data.fchost.parent_wwnn && - !ret->source.adapter.data.fchost.parent_wwpn) || - (!ret->source.adapter.data.fchost.parent_wwnn && - ret->source.adapter.data.fchost.parent_wwpn)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("must supply both parent_wwnn and " - "parent_wwpn not just one or the other")); - return -1; - } + if (ret->source.adapter.data.fchost.parent_wwnn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_wwnn)) + return -1; - if (ret->source.adapter.data.fchost.parent_wwnn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_wwnn)) - return -1; + if (ret->source.adapter.data.fchost.parent_wwpn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_wwpn)) + return -1; - if (ret->source.adapter.data.fchost.parent_wwpn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_wwpn)) - return -1; + if (ret->source.adapter.data.fchost.parent_fabric_wwn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_fabric_wwn)) + return -1; - if (ret->source.adapter.data.fchost.parent_fabric_wwn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_fabric_wwn)) - return -1; + return 0; +} + +int +virStorageAdapterParseValidate(virStoragePoolDefPtr ret) +{ + if (!ret->source.adapter.type) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing storage pool source adapter")); + return -1; + } + + if (ret->source.adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + return virStorageAdapterFCHostParseValidate(ret); } else if (ret->source.adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { if (!ret->source.adapter.data.scsi_host.name && @@ -244,6 +270,28 @@ virStorageAdapterParseValidate(virStoragePoolDefPtr ret) } +static void +virStorageAdapterFCHostFormat(virBufferPtr buf, + virStoragePoolSourcePtr src) +{ + virBufferEscapeString(buf, " parent='%s'", + src->adapter.data.fchost.parent); + if (src->adapter.data.fchost.managed) + virBufferAsprintf(buf, " managed='%s'", + virTristateBoolTypeToString(src->adapter.data.fchost.managed)); + virBufferEscapeString(buf, " parent_wwnn='%s'", + src->adapter.data.fchost.parent_wwnn); + virBufferEscapeString(buf, " parent_wwpn='%s'", + src->adapter.data.fchost.parent_wwpn); + virBufferEscapeString(buf, " parent_fabric_wwn='%s'", + src->adapter.data.fchost.parent_fabric_wwn); + + virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", + src->adapter.data.fchost.wwnn, + src->adapter.data.fchost.wwpn); +} + + void virStorageAdapterFormat(virBufferPtr buf, virStoragePoolSourcePtr src) @@ -252,21 +300,7 @@ virStorageAdapterFormat(virBufferPtr buf, virStoragePoolSourceAdapterTypeToString(src->adapter.type)); if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - virBufferEscapeString(buf, " parent='%s'", - src->adapter.data.fchost.parent); - if (src->adapter.data.fchost.managed) - virBufferAsprintf(buf, " managed='%s'", - virTristateBoolTypeToString(src->adapter.data.fchost.managed)); - virBufferEscapeString(buf, " parent_wwnn='%s'", - src->adapter.data.fchost.parent_wwnn); - virBufferEscapeString(buf, " parent_wwpn='%s'", - src->adapter.data.fchost.parent_wwpn); - virBufferEscapeString(buf, " parent_fabric_wwn='%s'", - src->adapter.data.fchost.parent_fabric_wwn); - - virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", - src->adapter.data.fchost.wwnn, - src->adapter.data.fchost.wwpn); + virStorageAdapterFCHostFormat(buf, src); } else if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { if (src->adapter.data.scsi_host.name) { -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Rather than have lots of ugly inline code create helpers to try and
s/code create/code, create/ (it took me a second to parse it - at first my brain wanted to understand that there had been ugly inline code that was creating helpers (whatever *that* might mean!)
make things more readable.
So this is being done just because the functions are each "too long", not because these new functions are going to be called from multiple places. Seems kind of unnecessary, since they don't even have the upside of shortening long variable names and repeated pointer dereferences (which of course will be optimized out anyway)...
While creating the helpers realign the code as necessary.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 194 +++++++++++++++++++++++----------------- 1 file changed, 114 insertions(+), 80 deletions(-)
diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index 4f5b665..a2d4a3a 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -37,16 +37,23 @@ VIR_ENUM_IMPL(virStoragePoolSourceAdapter, "default", "scsi_host", "fc_host")
+static void +virStorageAdapterFCHostClear(virStoragePoolSourceAdapterPtr adapter)
I *think* Dan's new function naming guidelines had said that functions could be either virSubjectVerbObject or virSubjectObjectVerb, so I guess this is okay (although I think I may slightly prefer virStorageAdapterClearFCHost() since the object being operated on is a virStorage[PoolSource]AdapterPtr).
+{ + VIR_FREE(adapter->data.fchost.wwnn); + VIR_FREE(adapter->data.fchost.wwpn); + VIR_FREE(adapter->data.fchost.parent); + VIR_FREE(adapter->data.fchost.parent_wwnn); + VIR_FREE(adapter->data.fchost.parent_wwpn); + VIR_FREE(adapter->data.fchost.parent_fabric_wwn); +} + + void virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) { if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - VIR_FREE(adapter->data.fchost.wwnn); - VIR_FREE(adapter->data.fchost.wwpn); - VIR_FREE(adapter->data.fchost.parent); - VIR_FREE(adapter->data.fchost.parent_wwnn); - VIR_FREE(adapter->data.fchost.parent_wwpn); - VIR_FREE(adapter->data.fchost.parent_fabric_wwn); + virStorageAdapterFCHostClear(adapter); } else if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { VIR_FREE(adapter->data.scsi_host.name); @@ -54,6 +61,40 @@ virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) }
+static int +virStorageAdapterFCHostParseXML(xmlNodePtr node, + virStoragePoolSourcePtr source)
Hmmm, or maybe these functions could take a virStorageFCHostPtr (if only such a thing existed, rather than it being an anonymous struct inside an anonymous union inside a virStoragePoolSourceAdapter :-/ ) In the end I guess I'm okay with the names you've given and leaving well enough alone with the struct.
+{ + char *managed = NULL; + + source->adapter.data.fchost.parent = virXMLPropString(node, "parent"); + if ((managed = virXMLPropString(node, "managed"))) { + source->adapter.data.fchost.managed = + virTristateBoolTypeFromString(managed); + if (source->adapter.data.fchost.managed < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown fc_host managed setting '%s'"), + managed); + VIR_FREE(managed); + return -1; + } + } + + source->adapter.data.fchost.parent_wwnn = + virXMLPropString(node, "parent_wwnn"); + source->adapter.data.fchost.parent_wwpn = + virXMLPropString(node, "parent_wwpn"); + source->adapter.data.fchost.parent_fabric_wwn = + virXMLPropString(node, "parent_fabric_wwn"); + + source->adapter.data.fchost.wwpn = virXMLPropString(node, "wwpn"); + source->adapter.data.fchost.wwnn = virXMLPropString(node, "wwnn"); + + VIR_FREE(managed); + return 0; +} + + int virStorageAdapterParseXML(virStoragePoolSourcePtr source, xmlNodePtr node, @@ -62,7 +103,6 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, int ret = -1; xmlNodePtr relnode = ctxt->node; char *adapter_type = NULL; - char *managed = NULL;
ctxt->node = node;
@@ -77,29 +117,8 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source,
if (source->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - source->adapter.data.fchost.parent = - virXMLPropString(node, "parent"); - managed = virXMLPropString(node, "managed"); - if (managed) { - source->adapter.data.fchost.managed = - virTristateBoolTypeFromString(managed); - if (source->adapter.data.fchost.managed < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown fc_host managed setting '%s'"), - managed); - goto cleanup; - } - } - - source->adapter.data.fchost.parent_wwnn = - virXMLPropString(node, "parent_wwnn"); - source->adapter.data.fchost.parent_wwpn = - virXMLPropString(node, "parent_wwpn"); - source->adapter.data.fchost.parent_fabric_wwn = - virXMLPropString(node, "parent_fabric_wwn"); - - source->adapter.data.fchost.wwpn = virXMLPropString(node, "wwpn"); - source->adapter.data.fchost.wwnn = virXMLPropString(node, "wwnn"); + if (virStorageAdapterFCHostParseXML(node, source) < 0) + goto cleanup; } else if (source->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) {
@@ -171,56 +190,63 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, cleanup: ctxt->node = relnode; VIR_FREE(adapter_type); - VIR_FREE(managed); return ret; }
-int -virStorageAdapterParseValidate(virStoragePoolDefPtr ret) +static int +virStorageAdapterFCHostParseValidate(virStoragePoolDefPtr ret)
Please get rid of "Parse" in this name though.
{ - if (!ret->source.adapter.type) { + if (!ret->source.adapter.data.fchost.wwnn || + !ret->source.adapter.data.fchost.wwpn) { virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing storage pool source adapter")); + _("'wwnn' and 'wwpn' must be specified for adapter " + "type 'fchost'")); return -1; }
- if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (!ret->source.adapter.data.fchost.wwnn || - !ret->source.adapter.data.fchost.wwpn) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("'wwnn' and 'wwpn' must be specified for adapter " - "type 'fchost'")); - return -1; - } + if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || + !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) + return -1;
- if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || - !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) - return -1; + if ((ret->source.adapter.data.fchost.parent_wwnn && + !ret->source.adapter.data.fchost.parent_wwpn) || + (!ret->source.adapter.data.fchost.parent_wwnn && + ret->source.adapter.data.fchost.parent_wwpn)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("must supply both parent_wwnn and " + "parent_wwpn not just one or the other")); + return -1; + }
- if ((ret->source.adapter.data.fchost.parent_wwnn && - !ret->source.adapter.data.fchost.parent_wwpn) || - (!ret->source.adapter.data.fchost.parent_wwnn && - ret->source.adapter.data.fchost.parent_wwpn)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("must supply both parent_wwnn and " - "parent_wwpn not just one or the other")); - return -1; - } + if (ret->source.adapter.data.fchost.parent_wwnn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_wwnn))
It's a separate issue, but maybe this function should be named virWWNValidate (even though there is no object called "virWWN")
+ return -1;
- if (ret->source.adapter.data.fchost.parent_wwnn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_wwnn)) - return -1; + if (ret->source.adapter.data.fchost.parent_wwpn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_wwpn)) + return -1;
- if (ret->source.adapter.data.fchost.parent_wwpn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_wwpn)) - return -1; + if (ret->source.adapter.data.fchost.parent_fabric_wwn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_fabric_wwn)) + return -1;
- if (ret->source.adapter.data.fchost.parent_fabric_wwn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_fabric_wwn)) - return -1; + return 0; +}
+ +int +virStorageAdapterParseValidate(virStoragePoolDefPtr ret) +{ + if (!ret->source.adapter.type) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing storage pool source adapter")); + return -1; + } + + if (ret->source.adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + return virStorageAdapterFCHostParseValidate(ret); } else if (ret->source.adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { if (!ret->source.adapter.data.scsi_host.name && @@ -244,6 +270,28 @@ virStorageAdapterParseValidate(virStoragePoolDefPtr ret) }
+static void +virStorageAdapterFCHostFormat(virBufferPtr buf, + virStoragePoolSourcePtr src) +{ + virBufferEscapeString(buf, " parent='%s'", + src->adapter.data.fchost.parent); + if (src->adapter.data.fchost.managed) + virBufferAsprintf(buf, " managed='%s'", + virTristateBoolTypeToString(src->adapter.data.fchost.managed)); + virBufferEscapeString(buf, " parent_wwnn='%s'", + src->adapter.data.fchost.parent_wwnn); + virBufferEscapeString(buf, " parent_wwpn='%s'", + src->adapter.data.fchost.parent_wwpn); + virBufferEscapeString(buf, " parent_fabric_wwn='%s'", + src->adapter.data.fchost.parent_fabric_wwn); + + virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", + src->adapter.data.fchost.wwnn, + src->adapter.data.fchost.wwpn); +} + + void virStorageAdapterFormat(virBufferPtr buf, virStoragePoolSourcePtr src) @@ -252,21 +300,7 @@ virStorageAdapterFormat(virBufferPtr buf, virStoragePoolSourceAdapterTypeToString(src->adapter.type));
if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - virBufferEscapeString(buf, " parent='%s'", - src->adapter.data.fchost.parent); - if (src->adapter.data.fchost.managed) - virBufferAsprintf(buf, " managed='%s'", - virTristateBoolTypeToString(src->adapter.data.fchost.managed)); - virBufferEscapeString(buf, " parent_wwnn='%s'", - src->adapter.data.fchost.parent_wwnn); - virBufferEscapeString(buf, " parent_wwpn='%s'", - src->adapter.data.fchost.parent_wwpn); - virBufferEscapeString(buf, " parent_fabric_wwn='%s'", - src->adapter.data.fchost.parent_fabric_wwn); - - virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", - src->adapter.data.fchost.wwnn, - src->adapter.data.fchost.wwpn); + virStorageAdapterFCHostFormat(buf, src); } else if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { if (src->adapter.data.scsi_host.name) {
ACK with "Parse" removed from the one validation functions name.

On 03/11/2017 10:02 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
Rather than have lots of ugly inline code create helpers to try and
s/code create/code, create/ (it took me a second to parse it - at first my brain wanted to understand that there had been ugly inline code that was creating helpers (whatever *that* might mean!)
make things more readable.
So this is being done just because the functions are each "too long", not because these new functions are going to be called from multiple places. Seems kind of unnecessary, since they don't even have the upside of shortening long variable names and repeated pointer dereferences (which of course will be optimized out anyway)...
While creating the helpers realign the code as necessary.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 194 +++++++++++++++++++++++----------------- 1 file changed, 114 insertions(+), 80 deletions(-)
diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index 4f5b665..a2d4a3a 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -37,16 +37,23 @@ VIR_ENUM_IMPL(virStoragePoolSourceAdapter, "default", "scsi_host", "fc_host")
+static void +virStorageAdapterFCHostClear(virStoragePoolSourceAdapterPtr adapter)
I *think* Dan's new function naming guidelines had said that functions could be either virSubjectVerbObject or virSubjectObjectVerb, so I guess this is okay (although I think I may slightly prefer virStorageAdapterClearFCHost() since the object being operated on is a virStorage[PoolSource]AdapterPtr).
+{ + VIR_FREE(adapter->data.fchost.wwnn); + VIR_FREE(adapter->data.fchost.wwpn); + VIR_FREE(adapter->data.fchost.parent); + VIR_FREE(adapter->data.fchost.parent_wwnn); + VIR_FREE(adapter->data.fchost.parent_wwpn); + VIR_FREE(adapter->data.fchost.parent_fabric_wwn); +} + + void virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) { if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - VIR_FREE(adapter->data.fchost.wwnn); - VIR_FREE(adapter->data.fchost.wwpn); - VIR_FREE(adapter->data.fchost.parent); - VIR_FREE(adapter->data.fchost.parent_wwnn); - VIR_FREE(adapter->data.fchost.parent_wwpn); - VIR_FREE(adapter->data.fchost.parent_fabric_wwn); + virStorageAdapterFCHostClear(adapter); } else if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { VIR_FREE(adapter->data.scsi_host.name); @@ -54,6 +61,40 @@ virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) }
+static int +virStorageAdapterFCHostParseXML(xmlNodePtr node, + virStoragePoolSourcePtr source)
Hmmm, or maybe these functions could take a virStorageFCHostPtr (if only such a thing existed, rather than it being an anonymous struct inside an anonymous union inside a virStoragePoolSourceAdapter :-/ ) In the end I guess I'm okay with the names you've given and leaving well enough alone with the struct.
Right as you found out I had it in mind... Of course it's a matter of order!
+{ + char *managed = NULL; + + source->adapter.data.fchost.parent = virXMLPropString(node, "parent"); + if ((managed = virXMLPropString(node, "managed"))) { + source->adapter.data.fchost.managed = + virTristateBoolTypeFromString(managed); + if (source->adapter.data.fchost.managed < 0) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown fc_host managed setting '%s'"), + managed); + VIR_FREE(managed); + return -1; + } + } + + source->adapter.data.fchost.parent_wwnn = + virXMLPropString(node, "parent_wwnn"); + source->adapter.data.fchost.parent_wwpn = + virXMLPropString(node, "parent_wwpn"); + source->adapter.data.fchost.parent_fabric_wwn = + virXMLPropString(node, "parent_fabric_wwn"); + + source->adapter.data.fchost.wwpn = virXMLPropString(node, "wwpn"); + source->adapter.data.fchost.wwnn = virXMLPropString(node, "wwnn"); + + VIR_FREE(managed); + return 0; +} + + int virStorageAdapterParseXML(virStoragePoolSourcePtr source, xmlNodePtr node, @@ -62,7 +103,6 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, int ret = -1; xmlNodePtr relnode = ctxt->node; char *adapter_type = NULL; - char *managed = NULL;
ctxt->node = node;
@@ -77,29 +117,8 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source,
if (source->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - source->adapter.data.fchost.parent = - virXMLPropString(node, "parent"); - managed = virXMLPropString(node, "managed"); - if (managed) { - source->adapter.data.fchost.managed = - virTristateBoolTypeFromString(managed); - if (source->adapter.data.fchost.managed < 0) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown fc_host managed setting '%s'"), - managed); - goto cleanup; - } - } - - source->adapter.data.fchost.parent_wwnn = - virXMLPropString(node, "parent_wwnn"); - source->adapter.data.fchost.parent_wwpn = - virXMLPropString(node, "parent_wwpn"); - source->adapter.data.fchost.parent_fabric_wwn = - virXMLPropString(node, "parent_fabric_wwn"); - - source->adapter.data.fchost.wwpn = virXMLPropString(node, "wwpn"); - source->adapter.data.fchost.wwnn = virXMLPropString(node, "wwnn"); + if (virStorageAdapterFCHostParseXML(node, source) < 0) + goto cleanup; } else if (source->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) {
@@ -171,56 +190,63 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, cleanup: ctxt->node = relnode; VIR_FREE(adapter_type); - VIR_FREE(managed); return ret; }
-int -virStorageAdapterParseValidate(virStoragePoolDefPtr ret) +static int +virStorageAdapterFCHostParseValidate(virStoragePoolDefPtr ret)
Please get rid of "Parse" in this name though.
I'll change the name to be ValidateParse rather than ParseValidate
{ - if (!ret->source.adapter.type) { + if (!ret->source.adapter.data.fchost.wwnn || + !ret->source.adapter.data.fchost.wwpn) { virReportError(VIR_ERR_XML_ERROR, "%s", - _("missing storage pool source adapter")); + _("'wwnn' and 'wwpn' must be specified for adapter " + "type 'fchost'")); return -1; }
- if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (!ret->source.adapter.data.fchost.wwnn || - !ret->source.adapter.data.fchost.wwpn) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("'wwnn' and 'wwpn' must be specified for adapter " - "type 'fchost'")); - return -1; - } + if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || + !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) + return -1;
- if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || - !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) - return -1; + if ((ret->source.adapter.data.fchost.parent_wwnn && + !ret->source.adapter.data.fchost.parent_wwpn) || + (!ret->source.adapter.data.fchost.parent_wwnn && + ret->source.adapter.data.fchost.parent_wwpn)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("must supply both parent_wwnn and " + "parent_wwpn not just one or the other")); + return -1; + }
- if ((ret->source.adapter.data.fchost.parent_wwnn && - !ret->source.adapter.data.fchost.parent_wwpn) || - (!ret->source.adapter.data.fchost.parent_wwnn && - ret->source.adapter.data.fchost.parent_wwpn)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("must supply both parent_wwnn and " - "parent_wwpn not just one or the other")); - return -1; - } + if (ret->source.adapter.data.fchost.parent_wwnn && + !(ret->source.adapter.data.fchost.parent_wwnn))
It's a separate issue, but maybe this function should be named virWWNValidate (even though there is no object called "virWWN")
Well technically I suppose it should be virUtilValidateWWN... We could enter the theatre of the absurd though just generating patches to match some function name algorithm! John
+ return -1;
- if (ret->source.adapter.data.fchost.parent_wwnn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_wwnn)) - return -1; + if (ret->source.adapter.data.fchost.parent_wwpn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_wwpn)) + return -1;
- if (ret->source.adapter.data.fchost.parent_wwpn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_wwpn)) - return -1; + if (ret->source.adapter.data.fchost.parent_fabric_wwn && + !virValidateWWN(ret->source.adapter.data.fchost.parent_fabric_wwn)) + return -1;
- if (ret->source.adapter.data.fchost.parent_fabric_wwn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_fabric_wwn)) - return -1; + return 0; +}
+ +int +virStorageAdapterParseValidate(virStoragePoolDefPtr ret) +{ + if (!ret->source.adapter.type) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing storage pool source adapter")); + return -1; + } + + if (ret->source.adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + return virStorageAdapterFCHostParseValidate(ret); } else if (ret->source.adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { if (!ret->source.adapter.data.scsi_host.name && @@ -244,6 +270,28 @@ virStorageAdapterParseValidate(virStoragePoolDefPtr ret) }
+static void +virStorageAdapterFCHostFormat(virBufferPtr buf, + virStoragePoolSourcePtr src) +{ + virBufferEscapeString(buf, " parent='%s'", + src->adapter.data.fchost.parent); + if (src->adapter.data.fchost.managed) + virBufferAsprintf(buf, " managed='%s'", + virTristateBoolTypeToString(src->adapter.data.fchost.managed)); + virBufferEscapeString(buf, " parent_wwnn='%s'", + src->adapter.data.fchost.parent_wwnn); + virBufferEscapeString(buf, " parent_wwpn='%s'", + src->adapter.data.fchost.parent_wwpn); + virBufferEscapeString(buf, " parent_fabric_wwn='%s'", + src->adapter.data.fchost.parent_fabric_wwn); + + virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", + src->adapter.data.fchost.wwnn, + src->adapter.data.fchost.wwpn); +} + + void virStorageAdapterFormat(virBufferPtr buf, virStoragePoolSourcePtr src) @@ -252,21 +300,7 @@ virStorageAdapterFormat(virBufferPtr buf, virStoragePoolSourceAdapterTypeToString(src->adapter.type));
if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - virBufferEscapeString(buf, " parent='%s'", - src->adapter.data.fchost.parent); - if (src->adapter.data.fchost.managed) - virBufferAsprintf(buf, " managed='%s'", - virTristateBoolTypeToString(src->adapter.data.fchost.managed)); - virBufferEscapeString(buf, " parent_wwnn='%s'", - src->adapter.data.fchost.parent_wwnn); - virBufferEscapeString(buf, " parent_wwpn='%s'", - src->adapter.data.fchost.parent_wwpn); - virBufferEscapeString(buf, " parent_fabric_wwn='%s'", - src->adapter.data.fchost.parent_fabric_wwn); - - virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", - src->adapter.data.fchost.wwnn, - src->adapter.data.fchost.wwpn); + virStorageAdapterFCHostFormat(buf, src); } else if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { if (src->adapter.data.scsi_host.name) {
ACK with "Parse" removed from the one validation functions name.

Rather than have lots of ugly inline code create helpers to try and make things more readable. While creating the helpers realign the code as necessary. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 239 +++++++++++++++++++++++----------------- 1 file changed, 138 insertions(+), 101 deletions(-) diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index a2d4a3a..a361c34 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -52,12 +52,11 @@ virStorageAdapterFCHostClear(virStoragePoolSourceAdapterPtr adapter) void virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) { - if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) virStorageAdapterFCHostClear(adapter); - } else if (adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + + if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) VIR_FREE(adapter->data.scsi_host.name); - } } @@ -95,6 +94,83 @@ virStorageAdapterFCHostParseXML(xmlNodePtr node, } +static int +virStorageAdapterSCSIHostParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt, + virStoragePoolSourcePtr source) +{ + source->adapter.data.scsi_host.name = + virXMLPropString(node, "name"); + if (virXPathNode("./parentaddr", ctxt)) { + xmlNodePtr addrnode = virXPathNode("./parentaddr/address", ctxt); + virPCIDeviceAddressPtr addr = + &source->adapter.data.scsi_host.parentaddr; + + if (!addrnode) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing scsi_host PCI address element")); + return -1; + } + source->adapter.data.scsi_host.has_parent = true; + if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) + return -1; + if ((virXPathInt("string(./parentaddr/@unique_id)", + ctxt, + &source->adapter.data.scsi_host.unique_id) < 0) || + (source->adapter.data.scsi_host.unique_id < 0)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing or invalid scsi adapter " + "'unique_id' value")); + return -1; + } + } + + return 0; +} + + +static int +virStorageAdapterLegacyParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt, + virStoragePoolSourcePtr source) +{ + char *wwnn = virXMLPropString(node, "wwnn"); + char *wwpn = virXMLPropString(node, "wwpn"); + char *parent = virXMLPropString(node, "parent"); + + /* "type" was not specified in the XML, so we must verify that + * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the + * XML. If any are found, then we cannot just use "name" alone". + */ + if (wwnn || wwpn || parent) { + VIR_FREE(wwnn); + VIR_FREE(wwpn); + VIR_FREE(parent); + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'wwnn', 'wwpn', and 'parent' attributes " + "requires use of the adapter 'type'")); + return -1; + } + + if (virXPathNode("./parentaddr", ctxt)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'parent' element requires use " + "of the adapter 'type'")); + return -1; + } + + /* To keep back-compat, 'type' is not required to specify + * for scsi_host adapter. + */ + if ((source->adapter.data.scsi_host.name = + virXMLPropString(node, "name"))) + source->adapter.type = + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; + + return 0; +} + + int virStorageAdapterParseXML(virStoragePoolSourcePtr source, xmlNodePtr node, @@ -121,68 +197,13 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, goto cleanup; } else if (source->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + if (virStorageAdapterSCSIHostParseXML(node, ctxt, source) < 0) + goto cleanup; - source->adapter.data.scsi_host.name = - virXMLPropString(node, "name"); - if (virXPathNode("./parentaddr", ctxt)) { - xmlNodePtr addrnode = virXPathNode("./parentaddr/address", - ctxt); - virPCIDeviceAddressPtr addr = - &source->adapter.data.scsi_host.parentaddr; - - if (!addrnode) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing scsi_host PCI address element")); - goto cleanup; - } - source->adapter.data.scsi_host.has_parent = true; - if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) - goto cleanup; - if ((virXPathInt("string(./parentaddr/@unique_id)", - ctxt, - &source->adapter.data.scsi_host.unique_id) < 0) || - (source->adapter.data.scsi_host.unique_id < 0)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing or invalid scsi adapter " - "'unique_id' value")); - goto cleanup; - } - } } } else { - char *wwnn = virXMLPropString(node, "wwnn"); - char *wwpn = virXMLPropString(node, "wwpn"); - char *parent = virXMLPropString(node, "parent"); - - /* "type" was not specified in the XML, so we must verify that - * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the - * XML. If any are found, then we cannot just use "name" alone". - */ - - if (wwnn || wwpn || parent) { - VIR_FREE(wwnn); - VIR_FREE(wwpn); - VIR_FREE(parent); - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'wwnn', 'wwpn', and 'parent' attributes " - "requires use of the adapter 'type'")); + if (virStorageAdapterLegacyParseXML(node, ctxt, source) < 0) goto cleanup; - } - - if (virXPathNode("./parentaddr", ctxt)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'parent' element requires use " - "of the adapter 'type'")); - goto cleanup; - } - - /* To keep back-compat, 'type' is not required to specify - * for scsi_host adapter. - */ - if ((source->adapter.data.scsi_host.name = - virXMLPropString(node, "name"))) - source->adapter.type = - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; } ret = 0; @@ -235,6 +256,29 @@ virStorageAdapterFCHostParseValidate(virStoragePoolDefPtr ret) } +static int +virStorageAdapterSCSIHostParseValidate(virStoragePoolDefPtr ret) +{ + if (!ret->source.adapter.data.scsi_host.name && + !ret->source.adapter.data.scsi_host.has_parent) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Either 'name' or 'parent' must be specified " + "for the 'scsi_host' adapter")); + return -1; + } + + if (ret->source.adapter.data.scsi_host.name && + ret->source.adapter.data.scsi_host.has_parent) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Both 'name' and 'parent' cannot be specified " + "for the 'scsi_host' adapter")); + return -1; + } + + return 0; +} + + int virStorageAdapterParseValidate(virStoragePoolDefPtr ret) { @@ -245,26 +289,12 @@ virStorageAdapterParseValidate(virStoragePoolDefPtr ret) } if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) return virStorageAdapterFCHostParseValidate(ret); - } else if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (!ret->source.adapter.data.scsi_host.name && - !ret->source.adapter.data.scsi_host.has_parent) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Either 'name' or 'parent' must be specified " - "for the 'scsi_host' adapter")); - return -1; - } - if (ret->source.adapter.data.scsi_host.name && - ret->source.adapter.data.scsi_host.has_parent) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Both 'name' and 'parent' cannot be specified " - "for the 'scsi_host' adapter")); - return -1; - } - } + if (ret->source.adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) + return virStorageAdapterSCSIHostParseValidate(ret); return 0; } @@ -292,6 +322,30 @@ virStorageAdapterFCHostFormat(virBufferPtr buf, } +static void +virStorageAdapterSCSIHostFormat(virBufferPtr buf, + virStoragePoolSourcePtr src) +{ + if (src->adapter.data.scsi_host.name) { + virBufferAsprintf(buf, " name='%s'/>\n", + src->adapter.data.scsi_host.name); + } else { + virPCIDeviceAddress addr; + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "<parentaddr unique_id='%d'>\n", + src->adapter.data.scsi_host.unique_id); + virBufferAdjustIndent(buf, 2); + addr = src->adapter.data.scsi_host.parentaddr; + ignore_value(virPCIDeviceAddressFormat(buf, addr, false)); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</parentaddr>\n"); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</adapter>\n"); + } +} + + void virStorageAdapterFormat(virBufferPtr buf, virStoragePoolSourcePtr src) @@ -299,26 +353,9 @@ virStorageAdapterFormat(virBufferPtr buf, virBufferAsprintf(buf, "<adapter type='%s'", virStoragePoolSourceAdapterTypeToString(src->adapter.type)); - if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) virStorageAdapterFCHostFormat(buf, src); - } else if (src->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (src->adapter.data.scsi_host.name) { - virBufferAsprintf(buf, " name='%s'/>\n", - src->adapter.data.scsi_host.name); - } else { - virPCIDeviceAddress addr; - virBufferAddLit(buf, ">\n"); - virBufferAdjustIndent(buf, 2); - virBufferAsprintf(buf, "<parentaddr unique_id='%d'>\n", - src->adapter.data.scsi_host.unique_id); - virBufferAdjustIndent(buf, 2); - addr = src->adapter.data.scsi_host.parentaddr; - ignore_value(virPCIDeviceAddressFormat(buf, addr, false)); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</parentaddr>\n"); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</adapter>\n"); - } - } + + if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) + virStorageAdapterSCSIHostFormat(buf, src); } -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Rather than have lots of ugly inline code create helpers to try and make things more readable. While creating the helpers realign the code as necessary.
[same opinionated commentary about this being semi-pointless code churn :-P]
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 239 +++++++++++++++++++++++----------------- 1 file changed, 138 insertions(+), 101 deletions(-)
diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index a2d4a3a..a361c34 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -52,12 +52,11 @@ virStorageAdapterFCHostClear(virStoragePoolSourceAdapterPtr adapter) void virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) { - if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) virStorageAdapterFCHostClear(adapter); - } else if (adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + + if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) VIR_FREE(adapter->data.scsi_host.name);
That works fine as long as virStorageAdapterFCHostClear() doesn't modify adapter->type ;-) Yeah, I'm sure it doesn't and that it never will. I just wanted to point out the theoretical danger of changing the logic of code just to make a line shorter so you can eliminate the braces :-P
- } }
@@ -95,6 +94,83 @@ virStorageAdapterFCHostParseXML(xmlNodePtr node, }
+static int +virStorageAdapterSCSIHostParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt, + virStoragePoolSourcePtr source)
This should take a virStoragePoolSourceAdapterPtr (since "scsi" is an anonymous struct inside and anonymous union inside .... [see Path 07/18].
+{ + source->adapter.data.scsi_host.name = + virXMLPropString(node, "name"); + if (virXPathNode("./parentaddr", ctxt)) { + xmlNodePtr addrnode = virXPathNode("./parentaddr/address", ctxt); + virPCIDeviceAddressPtr addr = + &source->adapter.data.scsi_host.parentaddr; + + if (!addrnode) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing scsi_host PCI address element")); + return -1; + } + source->adapter.data.scsi_host.has_parent = true; + if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) + return -1; + if ((virXPathInt("string(./parentaddr/@unique_id)", + ctxt, + &source->adapter.data.scsi_host.unique_id) < 0) || + (source->adapter.data.scsi_host.unique_id < 0)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing or invalid scsi adapter " + "'unique_id' value")); + return -1; + } + } + + return 0; +} + + +static int +virStorageAdapterLegacyParseXML(xmlNodePtr node,
?Legacy?
+ xmlXPathContextPtr ctxt, + virStoragePoolSourcePtr source)
Same.
+{ + char *wwnn = virXMLPropString(node, "wwnn"); + char *wwpn = virXMLPropString(node, "wwpn"); + char *parent = virXMLPropString(node, "parent"); + + /* "type" was not specified in the XML, so we must verify that + * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the + * XML. If any are found, then we cannot just use "name" alone". + */ + if (wwnn || wwpn || parent) { + VIR_FREE(wwnn); + VIR_FREE(wwpn); + VIR_FREE(parent); + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'wwnn', 'wwpn', and 'parent' attributes " + "requires use of the adapter 'type'")); + return -1; + } + + if (virXPathNode("./parentaddr", ctxt)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'parent' element requires use " + "of the adapter 'type'")); + return -1; + } + + /* To keep back-compat, 'type' is not required to specify + * for scsi_host adapter. + */ + if ((source->adapter.data.scsi_host.name = + virXMLPropString(node, "name"))) + source->adapter.type = + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; + + return 0; +} + + int virStorageAdapterParseXML(virStoragePoolSourcePtr source, xmlNodePtr node, @@ -121,68 +197,13 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, goto cleanup; } else if (source->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + if (virStorageAdapterSCSIHostParseXML(node, ctxt, source) < 0) + goto cleanup;
- source->adapter.data.scsi_host.name = - virXMLPropString(node, "name"); - if (virXPathNode("./parentaddr", ctxt)) { - xmlNodePtr addrnode = virXPathNode("./parentaddr/address", - ctxt); - virPCIDeviceAddressPtr addr = - &source->adapter.data.scsi_host.parentaddr; - - if (!addrnode) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing scsi_host PCI address element")); - goto cleanup; - } - source->adapter.data.scsi_host.has_parent = true; - if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) - goto cleanup; - if ((virXPathInt("string(./parentaddr/@unique_id)", - ctxt, - &source->adapter.data.scsi_host.unique_id) < 0) || - (source->adapter.data.scsi_host.unique_id < 0)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing or invalid scsi adapter " - "'unique_id' value")); - goto cleanup; - } - } } } else { - char *wwnn = virXMLPropString(node, "wwnn"); - char *wwpn = virXMLPropString(node, "wwpn"); - char *parent = virXMLPropString(node, "parent"); - - /* "type" was not specified in the XML, so we must verify that - * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the - * XML. If any are found, then we cannot just use "name" alone". - */ - - if (wwnn || wwpn || parent) { - VIR_FREE(wwnn); - VIR_FREE(wwpn); - VIR_FREE(parent); - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'wwnn', 'wwpn', and 'parent' attributes " - "requires use of the adapter 'type'")); + if (virStorageAdapterLegacyParseXML(node, ctxt, source) < 0) goto cleanup; - } - - if (virXPathNode("./parentaddr", ctxt)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'parent' element requires use " - "of the adapter 'type'")); - goto cleanup; - } - - /* To keep back-compat, 'type' is not required to specify - * for scsi_host adapter. - */ - if ((source->adapter.data.scsi_host.name = - virXMLPropString(node, "name"))) - source->adapter.type = - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; }
ret = 0; @@ -235,6 +256,29 @@ virStorageAdapterFCHostParseValidate(virStoragePoolDefPtr ret) }
+static int +virStorageAdapterSCSIHostParseValidate(virStoragePoolDefPtr ret)
Again with the "ParseValidate". I see validation, but I don't see any parsing. (yeah, I know it's just because the calling function is named virBlahParseValidate - that needs to be fixed too)
+{ + if (!ret->source.adapter.data.scsi_host.name && + !ret->source.adapter.data.scsi_host.has_parent) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Either 'name' or 'parent' must be specified " + "for the 'scsi_host' adapter")); + return -1; + } + + if (ret->source.adapter.data.scsi_host.name && + ret->source.adapter.data.scsi_host.has_parent) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Both 'name' and 'parent' cannot be specified " + "for the 'scsi_host' adapter")); + return -1; + } + + return 0; +} + + int virStorageAdapterParseValidate(virStoragePoolDefPtr ret) { @@ -245,26 +289,12 @@ virStorageAdapterParseValidate(virStoragePoolDefPtr ret) }
if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) return virStorageAdapterFCHostParseValidate(ret); - } else if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (!ret->source.adapter.data.scsi_host.name && - !ret->source.adapter.data.scsi_host.has_parent) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Either 'name' or 'parent' must be specified " - "for the 'scsi_host' adapter")); - return -1; - }
- if (ret->source.adapter.data.scsi_host.name && - ret->source.adapter.data.scsi_host.has_parent) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Both 'name' and 'parent' cannot be specified " - "for the 'scsi_host' adapter")); - return -1; - } - } + if (ret->source.adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) + return virStorageAdapterSCSIHostParseValidate(ret);
return 0; } @@ -292,6 +322,30 @@ virStorageAdapterFCHostFormat(virBufferPtr buf, }
+static void +virStorageAdapterSCSIHostFormat(virBufferPtr buf, + virStoragePoolSourcePtr src)
I didn't mention it for a couple of the functions up above, but in general *all* of these need to change their arg to be as specific as possible (which I guess is virStoragePoolSourceAdapterPtr)
+{ + if (src->adapter.data.scsi_host.name) { + virBufferAsprintf(buf, " name='%s'/>\n", + src->adapter.data.scsi_host.name); + } else { + virPCIDeviceAddress addr; + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "<parentaddr unique_id='%d'>\n", + src->adapter.data.scsi_host.unique_id); + virBufferAdjustIndent(buf, 2); + addr = src->adapter.data.scsi_host.parentaddr; + ignore_value(virPCIDeviceAddressFormat(buf, addr, false)); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</parentaddr>\n"); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</adapter>\n"); + } +} + + void virStorageAdapterFormat(virBufferPtr buf, virStoragePoolSourcePtr src) @@ -299,26 +353,9 @@ virStorageAdapterFormat(virBufferPtr buf, virBufferAsprintf(buf, "<adapter type='%s'", virStoragePoolSourceAdapterTypeToString(src->adapter.type));
- if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) virStorageAdapterFCHostFormat(buf, src); - } else if (src->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (src->adapter.data.scsi_host.name) { - virBufferAsprintf(buf, " name='%s'/>\n", - src->adapter.data.scsi_host.name); - } else { - virPCIDeviceAddress addr; - virBufferAddLit(buf, ">\n"); - virBufferAdjustIndent(buf, 2); - virBufferAsprintf(buf, "<parentaddr unique_id='%d'>\n", - src->adapter.data.scsi_host.unique_id); - virBufferAdjustIndent(buf, 2); - addr = src->adapter.data.scsi_host.parentaddr; - ignore_value(virPCIDeviceAddressFormat(buf, addr, false)); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</parentaddr>\n"); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</adapter>\n"); - } - } + + if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) + virStorageAdapterSCSIHostFormat(buf, src); }
I think this patch is okay if the args are changed to virStoragePoolSourceAdapterPtr, "Parse" is removed from the Validate function's name, and the use of "Legacy" in the one function is explained in a comment.

On 03/11/2017 10:14 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
Rather than have lots of ugly inline code create helpers to try and make things more readable. While creating the helpers realign the code as necessary.
[same opinionated commentary about this being semi-pointless code churn :-P]
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 239 +++++++++++++++++++++++----------------- 1 file changed, 138 insertions(+), 101 deletions(-)
diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index a2d4a3a..a361c34 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -52,12 +52,11 @@ virStorageAdapterFCHostClear(virStoragePoolSourceAdapterPtr adapter) void virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) { - if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) virStorageAdapterFCHostClear(adapter); - } else if (adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + + if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) VIR_FREE(adapter->data.scsi_host.name);
That works fine as long as virStorageAdapterFCHostClear() doesn't modify adapter->type ;-) Yeah, I'm sure it doesn't and that it never will. I just wanted to point out the theoretical danger of changing the logic of code just to make a line shorter so you can eliminate the braces :-P
True... Of course this could become a switch too right?
- } }
@@ -95,6 +94,83 @@ virStorageAdapterFCHostParseXML(xmlNodePtr node, }
+static int +virStorageAdapterSCSIHostParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt, + virStoragePoolSourcePtr source)
This should take a virStoragePoolSourceAdapterPtr (since "scsi" is an anonymous struct inside and anonymous union inside .... [see Path 07/18].
As you found out - that was later.
+{ + source->adapter.data.scsi_host.name = + virXMLPropString(node, "name"); + if (virXPathNode("./parentaddr", ctxt)) { + xmlNodePtr addrnode = virXPathNode("./parentaddr/address", ctxt); + virPCIDeviceAddressPtr addr = + &source->adapter.data.scsi_host.parentaddr; + + if (!addrnode) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing scsi_host PCI address element")); + return -1; + } + source->adapter.data.scsi_host.has_parent = true; + if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) + return -1; + if ((virXPathInt("string(./parentaddr/@unique_id)", + ctxt, + &source->adapter.data.scsi_host.unique_id) < 0) || + (source->adapter.data.scsi_host.unique_id < 0)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing or invalid scsi adapter " + "'unique_id' value")); + return -1; + } + } + + return 0; +} + + +static int +virStorageAdapterLegacyParseXML(xmlNodePtr node,
?Legacy?
Well the "old" format for SCSI parsed only "name" - I had no better idea other than legacy
+ xmlXPathContextPtr ctxt, + virStoragePoolSourcePtr source)
Same.
+{ + char *wwnn = virXMLPropString(node, "wwnn"); + char *wwpn = virXMLPropString(node, "wwpn"); + char *parent = virXMLPropString(node, "parent"); + + /* "type" was not specified in the XML, so we must verify that + * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the + * XML. If any are found, then we cannot just use "name" alone". + */ + if (wwnn || wwpn || parent) { + VIR_FREE(wwnn); + VIR_FREE(wwpn); + VIR_FREE(parent); + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'wwnn', 'wwpn', and 'parent' attributes " + "requires use of the adapter 'type'")); + return -1; + } + + if (virXPathNode("./parentaddr", ctxt)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Use of 'parent' element requires use " + "of the adapter 'type'")); + return -1; + } + + /* To keep back-compat, 'type' is not required to specify + * for scsi_host adapter. + */ + if ((source->adapter.data.scsi_host.name = + virXMLPropString(node, "name"))) + source->adapter.type = + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; + + return 0; +} + + int virStorageAdapterParseXML(virStoragePoolSourcePtr source, xmlNodePtr node, @@ -121,68 +197,13 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, goto cleanup; } else if (source->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + if (virStorageAdapterSCSIHostParseXML(node, ctxt, source) < 0) + goto cleanup;
- source->adapter.data.scsi_host.name = - virXMLPropString(node, "name"); - if (virXPathNode("./parentaddr", ctxt)) { - xmlNodePtr addrnode = virXPathNode("./parentaddr/address", - ctxt); - virPCIDeviceAddressPtr addr = - &source->adapter.data.scsi_host.parentaddr; - - if (!addrnode) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing scsi_host PCI address element")); - goto cleanup; - } - source->adapter.data.scsi_host.has_parent = true; - if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) - goto cleanup; - if ((virXPathInt("string(./parentaddr/@unique_id)", - ctxt, - &source->adapter.data.scsi_host.unique_id) < 0) || - (source->adapter.data.scsi_host.unique_id < 0)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Missing or invalid scsi adapter " - "'unique_id' value")); - goto cleanup; - } - } } } else { - char *wwnn = virXMLPropString(node, "wwnn"); - char *wwpn = virXMLPropString(node, "wwpn"); - char *parent = virXMLPropString(node, "parent"); - - /* "type" was not specified in the XML, so we must verify that - * "wwnn", "wwpn", "parent", or "parentaddr" are also not in the - * XML. If any are found, then we cannot just use "name" alone". - */ - - if (wwnn || wwpn || parent) { - VIR_FREE(wwnn); - VIR_FREE(wwpn); - VIR_FREE(parent); - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'wwnn', 'wwpn', and 'parent' attributes " - "requires use of the adapter 'type'")); + if (virStorageAdapterLegacyParseXML(node, ctxt, source) < 0) goto cleanup; - } - - if (virXPathNode("./parentaddr", ctxt)) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Use of 'parent' element requires use " - "of the adapter 'type'")); - goto cleanup; - } - - /* To keep back-compat, 'type' is not required to specify - * for scsi_host adapter. - */ - if ((source->adapter.data.scsi_host.name = - virXMLPropString(node, "name"))) - source->adapter.type = - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; }
ret = 0; @@ -235,6 +256,29 @@ virStorageAdapterFCHostParseValidate(virStoragePoolDefPtr ret) }
+static int +virStorageAdapterSCSIHostParseValidate(virStoragePoolDefPtr ret)
Again with the "ParseValidate". I see validation, but I don't see any parsing. (yeah, I know it's just because the calling function is named virBlahParseValidate - that needs to be fixed too)
Similar I'll modify to ValidateParse John
+{ + if (!ret->source.adapter.data.scsi_host.name && + !ret->source.adapter.data.scsi_host.has_parent) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Either 'name' or 'parent' must be specified " + "for the 'scsi_host' adapter")); + return -1; + } + + if (ret->source.adapter.data.scsi_host.name && + ret->source.adapter.data.scsi_host.has_parent) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Both 'name' and 'parent' cannot be specified " + "for the 'scsi_host' adapter")); + return -1; + } + + return 0; +} + + int virStorageAdapterParseValidate(virStoragePoolDefPtr ret) { @@ -245,26 +289,12 @@ virStorageAdapterParseValidate(virStoragePoolDefPtr ret) }
if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) return virStorageAdapterFCHostParseValidate(ret); - } else if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (!ret->source.adapter.data.scsi_host.name && - !ret->source.adapter.data.scsi_host.has_parent) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Either 'name' or 'parent' must be specified " - "for the 'scsi_host' adapter")); - return -1; - }
- if (ret->source.adapter.data.scsi_host.name && - ret->source.adapter.data.scsi_host.has_parent) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("Both 'name' and 'parent' cannot be specified " - "for the 'scsi_host' adapter")); - return -1; - } - } + if (ret->source.adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) + return virStorageAdapterSCSIHostParseValidate(ret);
return 0; } @@ -292,6 +322,30 @@ virStorageAdapterFCHostFormat(virBufferPtr buf, }
+static void +virStorageAdapterSCSIHostFormat(virBufferPtr buf, + virStoragePoolSourcePtr src)
I didn't mention it for a couple of the functions up above, but in general *all* of these need to change their arg to be as specific as possible (which I guess is virStoragePoolSourceAdapterPtr)
+{ + if (src->adapter.data.scsi_host.name) { + virBufferAsprintf(buf, " name='%s'/>\n", + src->adapter.data.scsi_host.name); + } else { + virPCIDeviceAddress addr; + virBufferAddLit(buf, ">\n"); + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "<parentaddr unique_id='%d'>\n", + src->adapter.data.scsi_host.unique_id); + virBufferAdjustIndent(buf, 2); + addr = src->adapter.data.scsi_host.parentaddr; + ignore_value(virPCIDeviceAddressFormat(buf, addr, false)); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</parentaddr>\n"); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</adapter>\n"); + } +} + + void virStorageAdapterFormat(virBufferPtr buf, virStoragePoolSourcePtr src) @@ -299,26 +353,9 @@ virStorageAdapterFormat(virBufferPtr buf, virBufferAsprintf(buf, "<adapter type='%s'", virStoragePoolSourceAdapterTypeToString(src->adapter.type));
- if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) virStorageAdapterFCHostFormat(buf, src); - } else if (src->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (src->adapter.data.scsi_host.name) { - virBufferAsprintf(buf, " name='%s'/>\n", - src->adapter.data.scsi_host.name); - } else { - virPCIDeviceAddress addr; - virBufferAddLit(buf, ">\n"); - virBufferAdjustIndent(buf, 2); - virBufferAsprintf(buf, "<parentaddr unique_id='%d'>\n", - src->adapter.data.scsi_host.unique_id); - virBufferAdjustIndent(buf, 2); - addr = src->adapter.data.scsi_host.parentaddr; - ignore_value(virPCIDeviceAddressFormat(buf, addr, false)); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</parentaddr>\n"); - virBufferAdjustIndent(buf, -2); - virBufferAddLit(buf, "</adapter>\n"); - } - } + + if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) + virStorageAdapterSCSIHostFormat(buf, src); }
I think this patch is okay if the args are changed to virStoragePoolSourceAdapterPtr, "Parse" is removed from the Validate function's name, and the use of "Legacy" in the one function is explained in a comment.

On 03/14/2017 07:05 PM, John Ferlan wrote:
On 03/11/2017 10:14 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
Rather than have lots of ugly inline code create helpers to try and make things more readable. While creating the helpers realign the code as necessary. [same opinionated commentary about this being semi-pointless code churn :-P]
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 239 +++++++++++++++++++++++----------------- 1 file changed, 138 insertions(+), 101 deletions(-)
diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index a2d4a3a..a361c34 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -52,12 +52,11 @@ virStorageAdapterFCHostClear(virStoragePoolSourceAdapterPtr adapter) void virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) { - if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) virStorageAdapterFCHostClear(adapter); - } else if (adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + + if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) VIR_FREE(adapter->data.scsi_host.name); That works fine as long as virStorageAdapterFCHostClear() doesn't modify adapter->type ;-) Yeah, I'm sure it doesn't and that it never will. I just wanted to point out the theoretical danger of changing the logic of code just to make a line shorter so you can eliminate the braces :-P
True... Of course this could become a switch too right?
With a typecast in the switch. Don't forget the typecast in the switch!
- } }
@@ -95,6 +94,83 @@ virStorageAdapterFCHostParseXML(xmlNodePtr node, }
+static int +virStorageAdapterSCSIHostParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt, + virStoragePoolSourcePtr source) This should take a virStoragePoolSourceAdapterPtr (since "scsi" is an anonymous struct inside and anonymous union inside .... [see Path 07/18].
As you found out - that was later.
+{ + source->adapter.data.scsi_host.name = + virXMLPropString(node, "name"); + if (virXPathNode("./parentaddr", ctxt)) { + xmlNodePtr addrnode = virXPathNode("./parentaddr/address", ctxt); + virPCIDeviceAddressPtr addr = + &source->adapter.data.scsi_host.parentaddr; + + if (!addrnode) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing scsi_host PCI address element")); + return -1; + } + source->adapter.data.scsi_host.has_parent = true; + if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) + return -1; + if ((virXPathInt("string(./parentaddr/@unique_id)", + ctxt, + &source->adapter.data.scsi_host.unique_id) < 0) || + (source->adapter.data.scsi_host.unique_id < 0)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("Missing or invalid scsi adapter " + "'unique_id' value")); + return -1; + } + } + + return 0; +} + + +static int +virStorageAdapterLegacyParseXML(xmlNodePtr node, ?Legacy?
Well the "old" format for SCSI parsed only "name" - I had no better idea other than legacy
Okay, some sort of comment about that would be appreciated. Looks like I hadn't actually said the magic word anywhere in my original response. Now that I know the argument types are heading somewhere in later patches, I can say "ACK with the *ParseValidate* name 'fixed', and a short comment added stating what is the "Legacy" being accounted for".

Create typedef'd substructures and rework typedef to utilize. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.h | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 1723afc..1012e74 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -179,27 +179,35 @@ typedef enum { } virStoragePoolSourceAdapterType; VIR_ENUM_DECL(virStoragePoolSourceAdapter) +typedef struct _virStorageAdapterSCSIHost virStorageAdapterSCSIHost; +typedef virStorageAdapterSCSIHost *virStorageAdapterSCSIHostPtr; +struct _virStorageAdapterSCSIHost { + char *name; + virPCIDeviceAddress parentaddr; /* host address */ + int unique_id; + bool has_parent; +}; + +typedef struct _virStorageAdapterFCHost virStorageAdapterFCHost; +typedef virStorageAdapterFCHost *virStorageAdapterFCHostPtr; +struct _virStorageAdapterFCHost { + char *parent; + char *parent_wwnn; + char *parent_wwpn; + char *parent_fabric_wwn; + char *wwnn; + char *wwpn; + int managed; /* enum virTristateSwitch */ +}; + typedef struct _virStoragePoolSourceAdapter virStoragePoolSourceAdapter; typedef virStoragePoolSourceAdapter *virStoragePoolSourceAdapterPtr; struct _virStoragePoolSourceAdapter { int type; /* virStoragePoolSourceAdapterType */ union { - struct { - char *name; - virPCIDeviceAddress parentaddr; /* host address */ - int unique_id; - bool has_parent; - } scsi_host; - struct { - char *parent; - char *parent_wwnn; - char *parent_wwpn; - char *parent_fabric_wwn; - char *wwnn; - char *wwpn; - int managed; /* enum virTristateSwitch */ - } fchost; + virStorageAdapterSCSIHost scsi_host; + virStorageAdapterFCHost fchost; } data; }; -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Create typedef'd substructures and rework typedef to utilize.
Oh, sure. After I spewed all the passive-aggressive-critique about the anonymous structs, *NOW* you fix it :-P ACK!

Rework the helpers/APIs to use the FCHost and SCSIHost adapter types. Continue to realign the code for shorter lines. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 140 ++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 83 deletions(-) diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index a361c34..6efe5ae 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -38,14 +38,14 @@ VIR_ENUM_IMPL(virStoragePoolSourceAdapter, static void -virStorageAdapterFCHostClear(virStoragePoolSourceAdapterPtr adapter) +virStorageAdapterFCHostClear(virStorageAdapterFCHostPtr fchost) { - VIR_FREE(adapter->data.fchost.wwnn); - VIR_FREE(adapter->data.fchost.wwpn); - VIR_FREE(adapter->data.fchost.parent); - VIR_FREE(adapter->data.fchost.parent_wwnn); - VIR_FREE(adapter->data.fchost.parent_wwpn); - VIR_FREE(adapter->data.fchost.parent_fabric_wwn); + VIR_FREE(fchost->wwnn); + VIR_FREE(fchost->wwpn); + VIR_FREE(fchost->parent); + VIR_FREE(fchost->parent_wwnn); + VIR_FREE(fchost->parent_wwpn); + VIR_FREE(fchost->parent_fabric_wwn); } @@ -53,7 +53,7 @@ void virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) { if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) - virStorageAdapterFCHostClear(adapter); + virStorageAdapterFCHostClear(&adapter->data.fchost); if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) VIR_FREE(adapter->data.scsi_host.name); @@ -62,15 +62,13 @@ virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) static int virStorageAdapterFCHostParseXML(xmlNodePtr node, - virStoragePoolSourcePtr source) + virStorageAdapterFCHostPtr fchost) { char *managed = NULL; - source->adapter.data.fchost.parent = virXMLPropString(node, "parent"); + fchost->parent = virXMLPropString(node, "parent"); if ((managed = virXMLPropString(node, "managed"))) { - source->adapter.data.fchost.managed = - virTristateBoolTypeFromString(managed); - if (source->adapter.data.fchost.managed < 0) { + if ((fchost->managed = virTristateBoolTypeFromString(managed)) < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("unknown fc_host managed setting '%s'"), managed); @@ -79,15 +77,11 @@ virStorageAdapterFCHostParseXML(xmlNodePtr node, } } - source->adapter.data.fchost.parent_wwnn = - virXMLPropString(node, "parent_wwnn"); - source->adapter.data.fchost.parent_wwpn = - virXMLPropString(node, "parent_wwpn"); - source->adapter.data.fchost.parent_fabric_wwn = - virXMLPropString(node, "parent_fabric_wwn"); - - source->adapter.data.fchost.wwpn = virXMLPropString(node, "wwpn"); - source->adapter.data.fchost.wwnn = virXMLPropString(node, "wwnn"); + fchost->parent_wwnn = virXMLPropString(node, "parent_wwnn"); + fchost->parent_wwpn = virXMLPropString(node, "parent_wwpn"); + fchost->parent_fabric_wwn = virXMLPropString(node, "parent_fabric_wwn"); + fchost->wwpn = virXMLPropString(node, "wwpn"); + fchost->wwnn = virXMLPropString(node, "wwnn"); VIR_FREE(managed); return 0; @@ -97,27 +91,24 @@ virStorageAdapterFCHostParseXML(xmlNodePtr node, static int virStorageAdapterSCSIHostParseXML(xmlNodePtr node, xmlXPathContextPtr ctxt, - virStoragePoolSourcePtr source) + virStorageAdapterSCSIHostPtr scsi_host) { - source->adapter.data.scsi_host.name = - virXMLPropString(node, "name"); + scsi_host->name = virXMLPropString(node, "name"); if (virXPathNode("./parentaddr", ctxt)) { xmlNodePtr addrnode = virXPathNode("./parentaddr/address", ctxt); - virPCIDeviceAddressPtr addr = - &source->adapter.data.scsi_host.parentaddr; if (!addrnode) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing scsi_host PCI address element")); return -1; } - source->adapter.data.scsi_host.has_parent = true; - if (virPCIDeviceAddressParseXML(addrnode, addr) < 0) + scsi_host->has_parent = true; + if (virPCIDeviceAddressParseXML(addrnode, &scsi_host->parentaddr) < 0) return -1; if ((virXPathInt("string(./parentaddr/@unique_id)", ctxt, - &source->adapter.data.scsi_host.unique_id) < 0) || - (source->adapter.data.scsi_host.unique_id < 0)) { + &scsi_host->unique_id) < 0) || + (scsi_host->unique_id < 0)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Missing or invalid scsi adapter " "'unique_id' value")); @@ -132,7 +123,7 @@ virStorageAdapterSCSIHostParseXML(xmlNodePtr node, static int virStorageAdapterLegacyParseXML(xmlNodePtr node, xmlXPathContextPtr ctxt, - virStoragePoolSourcePtr source) + virStoragePoolSourceAdapterPtr adapter) { char *wwnn = virXMLPropString(node, "wwnn"); char *wwpn = virXMLPropString(node, "wwpn"); @@ -162,10 +153,8 @@ virStorageAdapterLegacyParseXML(xmlNodePtr node, /* To keep back-compat, 'type' is not required to specify * for scsi_host adapter. */ - if ((source->adapter.data.scsi_host.name = - virXMLPropString(node, "name"))) - source->adapter.type = - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; + if ((adapter->data.scsi_host.name = virXMLPropString(node, "name"))) + adapter->type = VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; return 0; } @@ -193,16 +182,16 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, if (source->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (virStorageAdapterFCHostParseXML(node, source) < 0) + if (virStorageAdapterFCHostParseXML(node, &source->adapter.data.fchost) < 0) goto cleanup; } else if (source->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (virStorageAdapterSCSIHostParseXML(node, ctxt, source) < 0) + if (virStorageAdapterSCSIHostParseXML(node, ctxt, &source->adapter.data.scsi_host) < 0) goto cleanup; } } else { - if (virStorageAdapterLegacyParseXML(node, ctxt, source) < 0) + if (virStorageAdapterLegacyParseXML(node, ctxt, &source->adapter) < 0) goto cleanup; } @@ -216,40 +205,33 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, static int -virStorageAdapterFCHostParseValidate(virStoragePoolDefPtr ret) +virStorageAdapterFCHostParseValidate(virStorageAdapterFCHostPtr fchost) { - if (!ret->source.adapter.data.fchost.wwnn || - !ret->source.adapter.data.fchost.wwpn) { + if (!fchost->wwnn || !fchost->wwpn) { virReportError(VIR_ERR_XML_ERROR, "%s", _("'wwnn' and 'wwpn' must be specified for adapter " "type 'fchost'")); return -1; } - if (!virValidateWWN(ret->source.adapter.data.fchost.wwnn) || - !virValidateWWN(ret->source.adapter.data.fchost.wwpn)) + if (!virValidateWWN(fchost->wwnn) || !virValidateWWN(fchost->wwpn)) return -1; - if ((ret->source.adapter.data.fchost.parent_wwnn && - !ret->source.adapter.data.fchost.parent_wwpn) || - (!ret->source.adapter.data.fchost.parent_wwnn && - ret->source.adapter.data.fchost.parent_wwpn)) { + if ((fchost->parent_wwnn && !fchost->parent_wwpn) || + (!fchost->parent_wwnn && fchost->parent_wwpn)) { virReportError(VIR_ERR_XML_ERROR, "%s", _("must supply both parent_wwnn and " "parent_wwpn not just one or the other")); return -1; } - if (ret->source.adapter.data.fchost.parent_wwnn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_wwnn)) + if (fchost->parent_wwnn && !virValidateWWN(fchost->parent_wwnn)) return -1; - if (ret->source.adapter.data.fchost.parent_wwpn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_wwpn)) + if (fchost->parent_wwpn && !virValidateWWN(fchost->parent_wwpn)) return -1; - if (ret->source.adapter.data.fchost.parent_fabric_wwn && - !virValidateWWN(ret->source.adapter.data.fchost.parent_fabric_wwn)) + if (fchost->parent_fabric_wwn && !virValidateWWN(fchost->parent_fabric_wwn)) return -1; return 0; @@ -257,18 +239,16 @@ virStorageAdapterFCHostParseValidate(virStoragePoolDefPtr ret) static int -virStorageAdapterSCSIHostParseValidate(virStoragePoolDefPtr ret) +virStorageAdapterSCSIHostParseValidate(virStorageAdapterSCSIHostPtr scsi_host) { - if (!ret->source.adapter.data.scsi_host.name && - !ret->source.adapter.data.scsi_host.has_parent) { + if (!scsi_host->name && !scsi_host->has_parent) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Either 'name' or 'parent' must be specified " "for the 'scsi_host' adapter")); return -1; } - if (ret->source.adapter.data.scsi_host.name && - ret->source.adapter.data.scsi_host.has_parent) { + if (scsi_host->name && scsi_host->has_parent) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Both 'name' and 'parent' cannot be specified " "for the 'scsi_host' adapter")); @@ -290,11 +270,11 @@ virStorageAdapterParseValidate(virStoragePoolDefPtr ret) if (ret->source.adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) - return virStorageAdapterFCHostParseValidate(ret); + return virStorageAdapterFCHostParseValidate(&ret->source.adapter.data.fchost); if (ret->source.adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) - return virStorageAdapterSCSIHostParseValidate(ret); + return virStorageAdapterSCSIHostParseValidate(&ret->source.adapter.data.scsi_host); return 0; } @@ -302,42 +282,36 @@ virStorageAdapterParseValidate(virStoragePoolDefPtr ret) static void virStorageAdapterFCHostFormat(virBufferPtr buf, - virStoragePoolSourcePtr src) + virStorageAdapterFCHostPtr fchost) { - virBufferEscapeString(buf, " parent='%s'", - src->adapter.data.fchost.parent); - if (src->adapter.data.fchost.managed) + virBufferEscapeString(buf, " parent='%s'", fchost->parent); + if (fchost->managed) virBufferAsprintf(buf, " managed='%s'", - virTristateBoolTypeToString(src->adapter.data.fchost.managed)); - virBufferEscapeString(buf, " parent_wwnn='%s'", - src->adapter.data.fchost.parent_wwnn); - virBufferEscapeString(buf, " parent_wwpn='%s'", - src->adapter.data.fchost.parent_wwpn); + virTristateBoolTypeToString(fchost->managed)); + virBufferEscapeString(buf, " parent_wwnn='%s'", fchost->parent_wwnn); + virBufferEscapeString(buf, " parent_wwpn='%s'", fchost->parent_wwpn); virBufferEscapeString(buf, " parent_fabric_wwn='%s'", - src->adapter.data.fchost.parent_fabric_wwn); + fchost->parent_fabric_wwn); virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", - src->adapter.data.fchost.wwnn, - src->adapter.data.fchost.wwpn); + fchost->wwnn, fchost->wwpn); } static void virStorageAdapterSCSIHostFormat(virBufferPtr buf, - virStoragePoolSourcePtr src) + virStorageAdapterSCSIHostPtr scsi_host) { - if (src->adapter.data.scsi_host.name) { - virBufferAsprintf(buf, " name='%s'/>\n", - src->adapter.data.scsi_host.name); + if (scsi_host->name) { + virBufferAsprintf(buf, " name='%s'/>\n", scsi_host->name); } else { - virPCIDeviceAddress addr; virBufferAddLit(buf, ">\n"); virBufferAdjustIndent(buf, 2); virBufferAsprintf(buf, "<parentaddr unique_id='%d'>\n", - src->adapter.data.scsi_host.unique_id); + scsi_host->unique_id); virBufferAdjustIndent(buf, 2); - addr = src->adapter.data.scsi_host.parentaddr; - ignore_value(virPCIDeviceAddressFormat(buf, addr, false)); + ignore_value(virPCIDeviceAddressFormat(buf, scsi_host->parentaddr, + false)); virBufferAdjustIndent(buf, -2); virBufferAddLit(buf, "</parentaddr>\n"); virBufferAdjustIndent(buf, -2); @@ -354,8 +328,8 @@ virStorageAdapterFormat(virBufferPtr buf, virStoragePoolSourceAdapterTypeToString(src->adapter.type)); if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) - virStorageAdapterFCHostFormat(buf, src); + virStorageAdapterFCHostFormat(buf, &src->adapter.data.fchost); if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) - virStorageAdapterSCSIHostFormat(buf, src); + virStorageAdapterSCSIHostFormat(buf, &src->adapter.data.scsi_host); } -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Rework the helpers/APIs to use the FCHost and SCSIHost adapter types. Continue to realign the code for shorter lines.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 140 ++++++++++++++++------------------------ 1 file changed, 57 insertions(+), 83 deletions(-)
ACK. Yay! My faith in the order of the world is being restored! :-) (I guess I should have skimmed through all the patches before commenting on any of them.)

Rework the helpers/APIs to use the FCHost and SCSIHost adapter types. Continue to realign the code for shorter lines. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 112 ++++++++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 51 deletions(-) diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 8709101..45dc860 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -2085,16 +2085,16 @@ virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools, static int -getSCSIHostNumber(virStoragePoolSourceAdapter adapter, +getSCSIHostNumber(virStorageAdapterSCSIHostPtr scsi_host, unsigned int *hostnum) { int ret = -1; unsigned int num; char *name = NULL; - if (adapter.data.scsi_host.has_parent) { - virPCIDeviceAddress addr = adapter.data.scsi_host.parentaddr; - unsigned int unique_id = adapter.data.scsi_host.unique_id; + if (scsi_host->has_parent) { + virPCIDeviceAddress addr = scsi_host->parentaddr; + unsigned int unique_id = scsi_host->unique_id; if (!(name = virSCSIHostGetNameByParentaddr(addr.domain, addr.bus, @@ -2105,7 +2105,7 @@ getSCSIHostNumber(virStoragePoolSourceAdapter adapter, if (virSCSIHostGetNumber(name, &num) < 0) goto cleanup; } else { - if (virSCSIHostGetNumber(adapter.data.scsi_host.name, &num) < 0) + if (virSCSIHostGetNumber(scsi_host->name, &num) < 0) goto cleanup; } @@ -2136,7 +2136,7 @@ virStorageIsSameHostnum(const char *name, * matchFCHostToSCSIHost: * * @conn: Connection pointer - * @fc_adapter: fc_host adapter (either def or pool->def) + * @fchost: fc_host adapter ptr (either def or pool->def) * @scsi_hostnum: Already determined "scsi_pool" hostnum * * Returns true/false whether there is a match between the incoming @@ -2144,7 +2144,7 @@ virStorageIsSameHostnum(const char *name, */ static bool matchFCHostToSCSIHost(virConnectPtr conn, - virStoragePoolSourceAdapter fc_adapter, + virStorageAdapterFCHostPtr fchost, unsigned int scsi_hostnum) { bool ret = false; @@ -2155,15 +2155,14 @@ matchFCHostToSCSIHost(virConnectPtr conn, /* If we have a parent defined, get its hostnum, and compare to the * scsi_hostnum. If they are the same, then we have a match */ - if (fc_adapter.data.fchost.parent && - virStorageIsSameHostnum(fc_adapter.data.fchost.parent, scsi_hostnum)) + if (fchost->parent && + virStorageIsSameHostnum(fchost->parent, scsi_hostnum)) return true; - /* If we find an fc_adapter name, then either libvirt created a vHBA + /* If we find an fc adapter name, then either libvirt created a vHBA * for this fc_host or a 'virsh nodedev-create' generated a vHBA. */ - if ((name = virVHBAGetHostByWWN(NULL, fc_adapter.data.fchost.wwnn, - fc_adapter.data.fchost.wwpn))) { + if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { /* Get the scsi_hostN for the vHBA in order to see if it * matches our scsi_hostnum @@ -2178,7 +2177,7 @@ matchFCHostToSCSIHost(virConnectPtr conn, * If the parent fc_hostnum is the same as the scsi_hostnum, we * have a match. */ - if (conn && !fc_adapter.data.fchost.parent) { + if (conn && !fchost->parent) { if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) goto cleanup; if ((parent_name = virNodeDeviceGetParentName(conn, @@ -2210,25 +2209,21 @@ matchFCHostToSCSIHost(virConnectPtr conn, return ret; } + static bool -matchSCSIAdapterParent(virStoragePoolObjPtr pool, - virStoragePoolDefPtr def) +matchSCSIAdapterParent(virStorageAdapterSCSIHostPtr pool_scsi_host, + virStorageAdapterSCSIHostPtr def_scsi_host) { - virPCIDeviceAddressPtr pooladdr = - &pool->def->source.adapter.data.scsi_host.parentaddr; - virPCIDeviceAddressPtr defaddr = - &def->source.adapter.data.scsi_host.parentaddr; - int pool_unique_id = - pool->def->source.adapter.data.scsi_host.unique_id; - int def_unique_id = - def->source.adapter.data.scsi_host.unique_id; + virPCIDeviceAddressPtr pooladdr = &pool_scsi_host->parentaddr; + virPCIDeviceAddressPtr defaddr = &def_scsi_host->parentaddr; + if (pooladdr->domain == defaddr->domain && pooladdr->bus == defaddr->bus && pooladdr->slot == defaddr->slot && pooladdr->function == defaddr->function && - pool_unique_id == def_unique_id) { + pool_scsi_host->unique_id == def_scsi_host->unique_id) return true; - } + return false; } @@ -2271,6 +2266,8 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, int ret = 1; virStoragePoolObjPtr pool = NULL; virStoragePoolObjPtr matchpool = NULL; + virStoragePoolSourceAdapterPtr pool_adapter; + virStoragePoolSourceAdapterPtr def_adapter; /* Check the pool list for duplicate underlying storage */ for (i = 0; i < pools->count; i++) { @@ -2306,63 +2303,76 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, break; case VIR_STORAGE_POOL_SCSI: - if (pool->def->source.adapter.type == + pool_adapter = &pool->def->source.adapter; + def_adapter = &def->source.adapter; + + if (pool_adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST && - def->source.adapter.type == + def_adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (STREQ(pool->def->source.adapter.data.fchost.wwnn, - def->source.adapter.data.fchost.wwnn) && - STREQ(pool->def->source.adapter.data.fchost.wwpn, - def->source.adapter.data.fchost.wwpn)) + virStorageAdapterFCHostPtr pool_fchost = + &pool_adapter->data.fchost; + virStorageAdapterFCHostPtr def_fchost = + &def_adapter->data.fchost; + + if (STREQ(pool_fchost->wwnn, def_fchost->wwnn) && + STREQ(pool_fchost->wwpn, def_fchost->wwpn)) matchpool = pool; - } else if (pool->def->source.adapter.type == + } else if (pool_adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST && - def->source.adapter.type == + def_adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + virStorageAdapterSCSIHostPtr pool_scsi_host = + &pool_adapter->data.scsi_host; + virStorageAdapterSCSIHostPtr def_scsi_host = + &def_adapter->data.scsi_host; unsigned int pool_hostnum, def_hostnum; - if (pool->def->source.adapter.data.scsi_host.has_parent && - def->source.adapter.data.scsi_host.has_parent && - matchSCSIAdapterParent(pool, def)) { + if (pool_scsi_host->has_parent && + def_scsi_host->has_parent && + matchSCSIAdapterParent(pool_scsi_host, def_scsi_host)) { matchpool = pool; break; } - if (getSCSIHostNumber(pool->def->source.adapter, - &pool_hostnum) < 0 || - getSCSIHostNumber(def->source.adapter, &def_hostnum) < 0) + if (getSCSIHostNumber(pool_scsi_host, &pool_hostnum) < 0 || + getSCSIHostNumber(def_scsi_host, &def_hostnum) < 0) break; if (pool_hostnum == def_hostnum) matchpool = pool; - } else if (pool->def->source.adapter.type == + } else if (pool_adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST && - def->source.adapter.type == + def_adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + virStorageAdapterFCHostPtr pool_fchost = + &pool_adapter->data.fchost; + virStorageAdapterSCSIHostPtr def_scsi_host = + &def_adapter->data.scsi_host; unsigned int scsi_hostnum; /* Get the scsi_hostN for the scsi_host source adapter def */ - if (getSCSIHostNumber(def->source.adapter, - &scsi_hostnum) < 0) + if (getSCSIHostNumber(def_scsi_host, &scsi_hostnum) < 0) break; - if (matchFCHostToSCSIHost(conn, pool->def->source.adapter, - scsi_hostnum)) { + if (matchFCHostToSCSIHost(conn, pool_fchost, scsi_hostnum)) { matchpool = pool; break; } - } else if (pool->def->source.adapter.type == + } else if (pool_adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST && - def->source.adapter.type == + def_adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + virStorageAdapterSCSIHostPtr pool_scsi_host = + &pool_adapter->data.scsi_host; + virStorageAdapterFCHostPtr def_fchost = + &def_adapter->data.fchost; unsigned int scsi_hostnum; - if (getSCSIHostNumber(pool->def->source.adapter, - &scsi_hostnum) < 0) + if (getSCSIHostNumber(pool_scsi_host, &scsi_hostnum) < 0) break; - if (matchFCHostToSCSIHost(conn, def->source.adapter, - scsi_hostnum)) { + if (matchFCHostToSCSIHost(conn, def_fchost, scsi_hostnum)) { matchpool = pool; break; } -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Rework the helpers/APIs to use the FCHost and SCSIHost adapter types. Continue to realign the code for shorter lines.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_conf.c | 112 ++++++++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 51 deletions(-)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 8709101..45dc860 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -2085,16 +2085,16 @@ virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools,
static int -getSCSIHostNumber(virStoragePoolSourceAdapter adapter,
Eww! This function passed a full copy of an object on the stack rather than a pointer to the object??
+getSCSIHostNumber(virStorageAdapterSCSIHostPtr scsi_host, unsigned int *hostnum) { int ret = -1; unsigned int num; char *name = NULL;
- if (adapter.data.scsi_host.has_parent) { - virPCIDeviceAddress addr = adapter.data.scsi_host.parentaddr; - unsigned int unique_id = adapter.data.scsi_host.unique_id; + if (scsi_host->has_parent) { + virPCIDeviceAddress addr = scsi_host->parentaddr;
And again it's copying an object rather than referencing it. Why? As long as you're eliminating the unnecessary copy of the larger object when calling this function, you may as well make addr a virPCIDeviceAddressPtr too (although I'm sure someone will insist that you do it in a separate patch :-P)
+ unsigned int unique_id = scsi_host->unique_id;
if (!(name = virSCSIHostGetNameByParentaddr(addr.domain, addr.bus, @@ -2105,7 +2105,7 @@ getSCSIHostNumber(virStoragePoolSourceAdapter adapter, if (virSCSIHostGetNumber(name, &num) < 0) goto cleanup; } else { - if (virSCSIHostGetNumber(adapter.data.scsi_host.name, &num) < 0) + if (virSCSIHostGetNumber(scsi_host->name, &num) < 0) goto cleanup; }
@@ -2136,7 +2136,7 @@ virStorageIsSameHostnum(const char *name, * matchFCHostToSCSIHost: * * @conn: Connection pointer - * @fc_adapter: fc_host adapter (either def or pool->def) + * @fchost: fc_host adapter ptr (either def or pool->def) * @scsi_hostnum: Already determined "scsi_pool" hostnum * * Returns true/false whether there is a match between the incoming @@ -2144,7 +2144,7 @@ virStorageIsSameHostnum(const char *name, */ static bool matchFCHostToSCSIHost(virConnectPtr conn, - virStoragePoolSourceAdapter fc_adapter, + virStorageAdapterFCHostPtr fchost,
Thank God! Where did all this pass-by-value come from anyway??? Meanwhile - ACK.

Use the FCHost and SCSIHost adapter specific typedefs Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/storage/storage_backend_scsi.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index 642e795..6c8875c 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -176,15 +176,17 @@ virStoragePoolFCRefreshThread(void *opaque) } static char * -getAdapterName(virStoragePoolSourceAdapter adapter) +getAdapterName(virStoragePoolSourceAdapterPtr adapter) { char *name = NULL; char *parentaddr = NULL; - if (adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (adapter.data.scsi_host.has_parent) { - virPCIDeviceAddress addr = adapter.data.scsi_host.parentaddr; - unsigned int unique_id = adapter.data.scsi_host.unique_id; + if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + virStorageAdapterSCSIHostPtr scsi_host = &adapter->data.scsi_host; + + if (scsi_host->has_parent) { + virPCIDeviceAddress addr = scsi_host->parentaddr; + unsigned int unique_id = scsi_host->unique_id; if (!(name = virSCSIHostGetNameByParentaddr(addr.domain, addr.bus, @@ -193,16 +195,15 @@ getAdapterName(virStoragePoolSourceAdapter adapter) unique_id))) goto cleanup; } else { - ignore_value(VIR_STRDUP(name, adapter.data.scsi_host.name)); + ignore_value(VIR_STRDUP(name, scsi_host->name)); } - } else if (adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (!(name = virVHBAGetHostByWWN(NULL, - adapter.data.fchost.wwnn, - adapter.data.fchost.wwpn))) { + } else if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + virStorageAdapterFCHostPtr fchost = &adapter->data.fchost; + + if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { virReportError(VIR_ERR_XML_ERROR, _("Failed to find SCSI host with wwnn='%s', " - "wwpn='%s'"), adapter.data.fchost.wwnn, - adapter.data.fchost.wwpn); + "wwpn='%s'"), fchost->wwnn, fchost->wwpn); } } @@ -458,7 +459,7 @@ virStorageBackendSCSICheckPool(virStoragePoolObjPtr pool, *isActive = false; - if (!(name = getAdapterName(pool->def->source.adapter))) { + if (!(name = getAdapterName(&pool->def->source.adapter))) { /* It's normal for the pool with "fc_host" type source * adapter fails to get the adapter name, since the vHBA * the adapter based on might be not created yet. @@ -498,7 +499,7 @@ virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, pool->def->allocation = pool->def->capacity = pool->def->available = 0; - if (!(name = getAdapterName(pool->def->source.adapter))) + if (!(name = getAdapterName(&pool->def->source.adapter))) return -1; if (virSCSIHostGetNumber(name, &host) < 0) -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Use the FCHost and SCSIHost adapter specific typedefs
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/storage/storage_backend_scsi.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-)
diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index 642e795..6c8875c 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -176,15 +176,17 @@ virStoragePoolFCRefreshThread(void *opaque) }
static char * -getAdapterName(virStoragePoolSourceAdapter adapter) +getAdapterName(virStoragePoolSourceAdapterPtr adapter)
Wow. How did all of these get in?
{ char *name = NULL; char *parentaddr = NULL;
- if (adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (adapter.data.scsi_host.has_parent) { - virPCIDeviceAddress addr = adapter.data.scsi_host.parentaddr; - unsigned int unique_id = adapter.data.scsi_host.unique_id; + if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + virStorageAdapterSCSIHostPtr scsi_host = &adapter->data.scsi_host; + + if (scsi_host->has_parent) { + virPCIDeviceAddress addr = scsi_host->parentaddr;
As with the previous patch that did this - how about changing it into virPCIDeviceAddressPtr to avoid the copy?
+ unsigned int unique_id = scsi_host->unique_id;
if (!(name = virSCSIHostGetNameByParentaddr(addr.domain, addr.bus, @@ -193,16 +195,15 @@ getAdapterName(virStoragePoolSourceAdapter adapter) unique_id))) goto cleanup; } else { - ignore_value(VIR_STRDUP(name, adapter.data.scsi_host.name)); + ignore_value(VIR_STRDUP(name, scsi_host->name)); } - } else if (adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (!(name = virVHBAGetHostByWWN(NULL, - adapter.data.fchost.wwnn, - adapter.data.fchost.wwpn))) { + } else if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + virStorageAdapterFCHostPtr fchost = &adapter->data.fchost; + + if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { virReportError(VIR_ERR_XML_ERROR, _("Failed to find SCSI host with wwnn='%s', " - "wwpn='%s'"), adapter.data.fchost.wwnn, - adapter.data.fchost.wwpn); + "wwpn='%s'"), fchost->wwnn, fchost->wwpn); } }
@@ -458,7 +459,7 @@ virStorageBackendSCSICheckPool(virStoragePoolObjPtr pool,
*isActive = false;
- if (!(name = getAdapterName(pool->def->source.adapter))) { + if (!(name = getAdapterName(&pool->def->source.adapter))) { /* It's normal for the pool with "fc_host" type source * adapter fails to get the adapter name, since the vHBA * the adapter based on might be not created yet. @@ -498,7 +499,7 @@ virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED,
pool->def->allocation = pool->def->capacity = pool->def->available = 0;
- if (!(name = getAdapterName(pool->def->source.adapter))) + if (!(name = getAdapterName(&pool->def->source.adapter))) return -1;
if (virSCSIHostGetNumber(name, &host) < 0)
ACK (and ACK to change the virPCIDeviceAddress to a * while you're at it.)

Rework the code to use the new FCHost specific adapter structures. Also rework the parameters to only pass what's need and leave logic in the caller for the adapter type and the need to call the helpers. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/storage/storage_backend_scsi.c | 96 ++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 51 deletions(-) diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index 6c8875c..77a51ff 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -255,10 +255,10 @@ checkParent(virConnectPtr conn, static int createVport(virConnectPtr conn, - virStoragePoolObjPtr pool) + virStoragePoolDefPtr def, + const char *configFile, + virStorageAdapterFCHostPtr fchost) { - const char *configFile = pool->configFile; - virStoragePoolSourceAdapterPtr adapter = &pool->def->source.adapter; unsigned int parent_host; char *name = NULL; char *parent_hoststr = NULL; @@ -267,45 +267,37 @@ createVport(virConnectPtr conn, virThread thread; int ret = -1; - if (adapter->type != VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) - return 0; - VIR_DEBUG("conn=%p, configFile='%s' parent='%s', wwnn='%s' wwpn='%s'", - conn, NULLSTR(configFile), NULLSTR(adapter->data.fchost.parent), - adapter->data.fchost.wwnn, adapter->data.fchost.wwpn); + conn, NULLSTR(configFile), NULLSTR(fchost->parent), + fchost->wwnn, fchost->wwpn); /* If we find an existing HBA/vHBA within the fc_host sysfs * using the wwnn/wwpn, then a nodedev is already created for * this pool and we don't have to create the vHBA */ - if ((name = virVHBAGetHostByWWN(NULL, adapter->data.fchost.wwnn, - adapter->data.fchost.wwpn))) { + if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { /* If a parent was provided, let's make sure the 'name' we've * retrieved has the same parent */ - if (adapter->data.fchost.parent && - checkParent(conn, name, adapter->data.fchost.parent)) + if (fchost->parent && checkParent(conn, name, fchost->parent)) ret = 0; goto cleanup; } - if (adapter->data.fchost.parent) { - if (VIR_STRDUP(parent_hoststr, adapter->data.fchost.parent) < 0) + if (fchost->parent) { + if (VIR_STRDUP(parent_hoststr, fchost->parent) < 0) goto cleanup; - } else if (adapter->data.fchost.parent_wwnn && - adapter->data.fchost.parent_wwpn) { - if (!(parent_hoststr = - virVHBAGetHostByWWN(NULL, adapter->data.fchost.parent_wwnn, - adapter->data.fchost.parent_wwpn))) { + } else if (fchost->parent_wwnn && fchost->parent_wwpn) { + if (!(parent_hoststr = virVHBAGetHostByWWN(NULL, fchost->parent_wwnn, + fchost->parent_wwpn))) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot find parent using provided wwnn/wwpn")); goto cleanup; } - } else if (adapter->data.fchost.parent_fabric_wwn) { + } else if (fchost->parent_fabric_wwn) { if (!(parent_hoststr = - virVHBAGetHostByFabricWWN(NULL, - adapter->data.fchost.parent_fabric_wwn))) { + virVHBAGetHostByFabricWWN(NULL, fchost->parent_fabric_wwn))) { virReportError(VIR_ERR_XML_ERROR, "%s", _("cannot find parent using provided fabric_wwn")); goto cleanup; @@ -324,8 +316,8 @@ createVport(virConnectPtr conn, goto cleanup; /* NOTE: - * We do not save the parent_hoststr in adapter->data.fchost.parent - * since we could be writing out the 'def' to the saved XML config. + * We do not save the parent_hoststr in fchost->parent since + * we could be writing out the 'def' to the saved XML config. * If we wrote out the name in the XML, then future starts would * always use the same parent rather than finding the "best available" * parent. Besides we have a way to determine the parent based on @@ -343,16 +335,16 @@ createVport(virConnectPtr conn, * restart, we need to save the persistent configuration. So if not * already defined as YES, then force the issue. */ - if (adapter->data.fchost.managed != VIR_TRISTATE_BOOL_YES) { - adapter->data.fchost.managed = VIR_TRISTATE_BOOL_YES; + if (fchost->managed != VIR_TRISTATE_BOOL_YES) { + fchost->managed = VIR_TRISTATE_BOOL_YES; if (configFile) { - if (virStoragePoolSaveConfig(configFile, pool->def) < 0) + if (virStoragePoolSaveConfig(configFile, def) < 0) goto cleanup; } } - if (virVHBAManageVport(parent_host, adapter->data.fchost.wwpn, - adapter->data.fchost.wwnn, VPORT_CREATE) < 0) + if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, + VPORT_CREATE) < 0) goto cleanup; virFileWaitForDevices(); @@ -362,10 +354,9 @@ createVport(virConnectPtr conn, * retry logic set to true. If the thread isn't created, then no big * deal since it's still possible to refresh the pool later. */ - if ((name = virVHBAGetHostByWWN(NULL, adapter->data.fchost.wwnn, - adapter->data.fchost.wwpn))) { + if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { if (VIR_ALLOC(cbdata) == 0) { - memcpy(cbdata->pool_uuid, pool->def->uuid, VIR_UUID_BUFLEN); + memcpy(cbdata->pool_uuid, def->uuid, VIR_UUID_BUFLEN); VIR_STEAL_PTR(cbdata->fchost_name, name); if (virThreadCreate(&thread, false, virStoragePoolFCRefreshThread, @@ -385,9 +376,10 @@ createVport(virConnectPtr conn, return ret; } + static int deleteVport(virConnectPtr conn, - virStoragePoolSourceAdapter adapter) + virStorageAdapterFCHostPtr fchost) { unsigned int parent_host; char *name = NULL; @@ -395,25 +387,19 @@ deleteVport(virConnectPtr conn, char *vhba_parent = NULL; int ret = -1; - if (adapter.type != VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) - return 0; - VIR_DEBUG("conn=%p parent='%s', managed='%d' wwnn='%s' wwpn='%s'", - conn, NULLSTR(adapter.data.fchost.parent), - adapter.data.fchost.managed, - adapter.data.fchost.wwnn, - adapter.data.fchost.wwpn); + conn, NULLSTR(fchost->parent), fchost->managed, + fchost->wwnn, fchost->wwpn); /* If we're not managing the deletion of the vHBA, then just return */ - if (adapter.data.fchost.managed != VIR_TRISTATE_BOOL_YES) + if (fchost->managed != VIR_TRISTATE_BOOL_YES) return 0; /* Find our vHBA by searching the fc_host sysfs tree for our wwnn/wwpn */ - if (!(name = virVHBAGetHostByWWN(NULL, adapter.data.fchost.wwnn, - adapter.data.fchost.wwpn))) { + if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to find fc_host for wwnn='%s' and wwpn='%s'"), - adapter.data.fchost.wwnn, adapter.data.fchost.wwpn); + fchost->wwnn, fchost->wwpn); goto cleanup; } @@ -421,8 +407,8 @@ deleteVport(virConnectPtr conn, * get the parent_host value; otherwise, we have to determine * the parent scsi_host which we did not save at startup time */ - if (adapter.data.fchost.parent) { - if (virSCSIHostGetNumber(adapter.data.fchost.parent, &parent_host) < 0) + if (fchost->parent) { + if (virSCSIHostGetNumber(fchost->parent, &parent_host) < 0) goto cleanup; } else { if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) @@ -435,8 +421,8 @@ deleteVport(virConnectPtr conn, goto cleanup; } - if (virVHBAManageVport(parent_host, adapter.data.fchost.wwpn, - adapter.data.fchost.wwnn, VPORT_DELETE) < 0) + if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, + VPORT_DELETE) < 0) goto cleanup; ret = 0; @@ -523,15 +509,23 @@ static int virStorageBackendSCSIStartPool(virConnectPtr conn, virStoragePoolObjPtr pool) { - return createVport(conn, pool); + if (pool->def->source.adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) + return createVport(conn, pool->def, pool->configFile, + &pool->def->source.adapter.data.fchost); + + return 0; } static int virStorageBackendSCSIStopPool(virConnectPtr conn, virStoragePoolObjPtr pool) { - virStoragePoolSourceAdapter adapter = pool->def->source.adapter; - return deleteVport(conn, adapter); + if (pool->def->source.adapter.type == + VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) + return deleteVport(conn, &pool->def->source.adapter.data.fchost); + + return 0; } virStorageBackend virStorageBackendSCSI = { -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Rework the code to use the new FCHost specific adapter structures.
Also rework the parameters to only pass what's need and leave logic in the caller for the adapter type and the need to call the helpers.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/storage/storage_backend_scsi.c | 96 ++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 51 deletions(-)
ACK.

Move the virStoragePoolSourceAdapter from storage_conf.h and rename to virStorageAdapter. Continue with code realignment for brevity and flow. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 71 ++++++++++++++++++-------------------- src/conf/storage_adapter_conf.h | 51 ++++++++++++++++++++++++--- src/conf/storage_conf.c | 32 ++++++++--------- src/conf/storage_conf.h | 44 ++--------------------- src/libvirt_private.syms | 2 -- src/phyp/phyp_driver.c | 3 +- src/storage/storage_backend_scsi.c | 18 +++++----- src/test/test_driver.c | 5 ++- 8 files changed, 109 insertions(+), 117 deletions(-) diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index 6efe5ae..53c07c7 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -19,7 +19,7 @@ #include <config.h> -#include "storage_adapter_conf.h" +#include "storage_conf.h" #include "viralloc.h" #include "virerror.h" @@ -32,11 +32,10 @@ VIR_LOG_INIT("conf.storage_adapter_conf"); -VIR_ENUM_IMPL(virStoragePoolSourceAdapter, - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_LAST, +VIR_ENUM_IMPL(virStorageAdapter, + VIR_STORAGE_ADAPTER_TYPE_LAST, "default", "scsi_host", "fc_host") - static void virStorageAdapterFCHostClear(virStorageAdapterFCHostPtr fchost) { @@ -50,12 +49,12 @@ virStorageAdapterFCHostClear(virStorageAdapterFCHostPtr fchost) void -virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) +virStorageAdapterClear(virStorageAdapterPtr adapter) { - if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) virStorageAdapterFCHostClear(&adapter->data.fchost); - if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) VIR_FREE(adapter->data.scsi_host.name); } @@ -123,7 +122,7 @@ virStorageAdapterSCSIHostParseXML(xmlNodePtr node, static int virStorageAdapterLegacyParseXML(xmlNodePtr node, xmlXPathContextPtr ctxt, - virStoragePoolSourceAdapterPtr adapter) + virStorageAdapterPtr adapter) { char *wwnn = virXMLPropString(node, "wwnn"); char *wwpn = virXMLPropString(node, "wwpn"); @@ -154,14 +153,14 @@ virStorageAdapterLegacyParseXML(xmlNodePtr node, * for scsi_host adapter. */ if ((adapter->data.scsi_host.name = virXMLPropString(node, "name"))) - adapter->type = VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; + adapter->type = VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST; return 0; } int -virStorageAdapterParseXML(virStoragePoolSourcePtr source, +virStorageAdapterParseXML(virStorageAdapterPtr adapter, xmlNodePtr node, xmlXPathContextPtr ctxt) { @@ -172,26 +171,24 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, ctxt->node = node; if ((adapter_type = virXMLPropString(node, "type"))) { - if ((source->adapter.type = - virStoragePoolSourceAdapterTypeFromString(adapter_type)) <= 0) { + if ((adapter->type = + virStorageAdapterTypeFromString(adapter_type)) <= 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unknown pool adapter type '%s'"), adapter_type); goto cleanup; } - if (source->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (virStorageAdapterFCHostParseXML(node, &source->adapter.data.fchost) < 0) - goto cleanup; - } else if (source->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (virStorageAdapterSCSIHostParseXML(node, ctxt, &source->adapter.data.scsi_host) < 0) + if ((adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) && + (virStorageAdapterFCHostParseXML(node, &adapter->data.fchost)) < 0) goto cleanup; - } + if ((adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) && + (virStorageAdapterSCSIHostParseXML(node, ctxt, + &adapter->data.scsi_host)) < 0) + goto cleanup; } else { - if (virStorageAdapterLegacyParseXML(node, ctxt, &source->adapter) < 0) + if (virStorageAdapterLegacyParseXML(node, ctxt, adapter) < 0) goto cleanup; } @@ -260,21 +257,19 @@ virStorageAdapterSCSIHostParseValidate(virStorageAdapterSCSIHostPtr scsi_host) int -virStorageAdapterParseValidate(virStoragePoolDefPtr ret) +virStorageAdapterParseValidate(virStorageAdapterPtr adapter) { - if (!ret->source.adapter.type) { + if (!adapter->type) { virReportError(VIR_ERR_XML_ERROR, "%s", _("missing storage pool source adapter")); return -1; } - if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) - return virStorageAdapterFCHostParseValidate(&ret->source.adapter.data.fchost); + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) + return virStorageAdapterFCHostParseValidate(&adapter->data.fchost); - if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) - return virStorageAdapterSCSIHostParseValidate(&ret->source.adapter.data.scsi_host); + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) + return virStorageAdapterSCSIHostParseValidate(&adapter->data.scsi_host); return 0; } @@ -285,13 +280,13 @@ virStorageAdapterFCHostFormat(virBufferPtr buf, virStorageAdapterFCHostPtr fchost) { virBufferEscapeString(buf, " parent='%s'", fchost->parent); - if (fchost->managed) - virBufferAsprintf(buf, " managed='%s'", - virTristateBoolTypeToString(fchost->managed)); virBufferEscapeString(buf, " parent_wwnn='%s'", fchost->parent_wwnn); virBufferEscapeString(buf, " parent_wwpn='%s'", fchost->parent_wwpn); virBufferEscapeString(buf, " parent_fabric_wwn='%s'", fchost->parent_fabric_wwn); + if (fchost->managed != VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, " managed='%s'", + virTristateBoolTypeToString(fchost->managed)); virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", fchost->wwnn, fchost->wwpn); @@ -322,14 +317,14 @@ virStorageAdapterSCSIHostFormat(virBufferPtr buf, void virStorageAdapterFormat(virBufferPtr buf, - virStoragePoolSourcePtr src) + virStorageAdapterPtr adapter) { virBufferAsprintf(buf, "<adapter type='%s'", - virStoragePoolSourceAdapterTypeToString(src->adapter.type)); + virStorageAdapterTypeToString(adapter->type)); - if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) - virStorageAdapterFCHostFormat(buf, &src->adapter.data.fchost); + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) + virStorageAdapterFCHostFormat(buf, &adapter->data.fchost); - if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) - virStorageAdapterSCSIHostFormat(buf, &src->adapter.data.scsi_host); + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) + virStorageAdapterSCSIHostFormat(buf, &adapter->data.scsi_host); } diff --git a/src/conf/storage_adapter_conf.h b/src/conf/storage_adapter_conf.h index ec812a1..730a3ca 100644 --- a/src/conf/storage_adapter_conf.h +++ b/src/conf/storage_adapter_conf.h @@ -23,21 +23,62 @@ # include "virpci.h" # include "virxml.h" -# include "storage_conf.h" + +typedef enum { + VIR_STORAGE_ADAPTER_TYPE_DEFAULT = 0, + VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST, + VIR_STORAGE_ADAPTER_TYPE_FC_HOST, + + VIR_STORAGE_ADAPTER_TYPE_LAST, +} virStorageAdapterType; +VIR_ENUM_DECL(virStorageAdapter) + +typedef struct _virStorageAdapterSCSIHost virStorageAdapterSCSIHost; +typedef virStorageAdapterSCSIHost *virStorageAdapterSCSIHostPtr; +struct _virStorageAdapterSCSIHost { + char *name; + virPCIDeviceAddress parentaddr; /* host address */ + int unique_id; + bool has_parent; +}; + +typedef struct _virStorageAdapterFCHost virStorageAdapterFCHost; +typedef virStorageAdapterFCHost *virStorageAdapterFCHostPtr; +struct _virStorageAdapterFCHost { + char *parent; + char *parent_wwnn; + char *parent_wwpn; + char *parent_fabric_wwn; + char *wwnn; + char *wwpn; + int managed; /* enum virTristateSwitch */ +}; + +typedef struct _virStorageAdapter virStorageAdapter; +typedef virStorageAdapter *virStorageAdapterPtr; +struct _virStorageAdapter { + int type; /* virStorageAdapterType */ + + union { + virStorageAdapterSCSIHost scsi_host; + virStorageAdapterFCHost fchost; + } data; +}; + void -virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter); +virStorageAdapterClear(virStorageAdapterPtr adapter); int -virStorageAdapterParseXML(virStoragePoolSourcePtr source, +virStorageAdapterParseXML(virStorageAdapterPtr adapter, xmlNodePtr node, xmlXPathContextPtr ctxt); int -virStorageAdapterParseValidate(virStoragePoolDefPtr ret); +virStorageAdapterParseValidate(virStorageAdapterPtr adapter); void virStorageAdapterFormat(virBufferPtr buf, - virStoragePoolSourcePtr src); + virStorageAdapterPtr adapter); #endif /* __VIR_STORAGE_ADAPTER_CONF_H__ */ diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 45dc860..7207605 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -565,7 +565,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, goto cleanup; if ((adapternode = virXPathNode("./adapter", ctxt))) { - if (virStorageAdapterParseXML(source, adapternode, ctxt) < 0) + if (virStorageAdapterParseXML(&source->adapter, adapternode, ctxt) < 0) goto cleanup; } @@ -802,7 +802,7 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) } if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) && - (virStorageAdapterParseValidate(ret)) < 0) + (virStorageAdapterParseValidate(&ret->source.adapter)) < 0) goto error; /* If DEVICE is the only source type, then its required */ @@ -958,9 +958,9 @@ virStoragePoolSourceFormat(virBufferPtr buf, virBufferEscapeString(buf, "<dir path='%s'/>\n", src->dir); if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) && - (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST || - src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST)) - virStorageAdapterFormat(buf, src); + (src->adapter.type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST || + src->adapter.type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST)) + virStorageAdapterFormat(buf, &src->adapter); if (options->flags & VIR_STORAGE_POOL_SOURCE_NAME) virBufferEscapeString(buf, "<name>%s</name>\n", src->name); @@ -2266,8 +2266,8 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, int ret = 1; virStoragePoolObjPtr pool = NULL; virStoragePoolObjPtr matchpool = NULL; - virStoragePoolSourceAdapterPtr pool_adapter; - virStoragePoolSourceAdapterPtr def_adapter; + virStorageAdapterPtr pool_adapter; + virStorageAdapterPtr def_adapter; /* Check the pool list for duplicate underlying storage */ for (i = 0; i < pools->count; i++) { @@ -2306,10 +2306,8 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, pool_adapter = &pool->def->source.adapter; def_adapter = &def->source.adapter; - if (pool_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST && - def_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (pool_adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST && + def_adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { virStorageAdapterFCHostPtr pool_fchost = &pool_adapter->data.fchost; virStorageAdapterFCHostPtr def_fchost = @@ -2319,9 +2317,9 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, STREQ(pool_fchost->wwpn, def_fchost->wwpn)) matchpool = pool; } else if (pool_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST && + VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST && def_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { virStorageAdapterSCSIHostPtr pool_scsi_host = &pool_adapter->data.scsi_host; virStorageAdapterSCSIHostPtr def_scsi_host = @@ -2341,9 +2339,9 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, if (pool_hostnum == def_hostnum) matchpool = pool; } else if (pool_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST && + VIR_STORAGE_ADAPTER_TYPE_FC_HOST && def_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { virStorageAdapterFCHostPtr pool_fchost = &pool_adapter->data.fchost; virStorageAdapterSCSIHostPtr def_scsi_host = @@ -2360,9 +2358,9 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, } } else if (pool_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST && + VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST && def_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { virStorageAdapterSCSIHostPtr pool_scsi_host = &pool_adapter->data.scsi_host; virStorageAdapterFCHostPtr def_fchost = diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 1012e74..6f20111 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -31,6 +31,7 @@ # include "virthread.h" # include "device_conf.h" # include "object_event.h" +# include "storage_adapter_conf.h" # include <libxml/tree.h> @@ -170,47 +171,6 @@ struct _virStoragePoolSourceDevice { } geometry; }; -typedef enum { - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_DEFAULT = 0, - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST, - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST, - - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_LAST, -} virStoragePoolSourceAdapterType; -VIR_ENUM_DECL(virStoragePoolSourceAdapter) - -typedef struct _virStorageAdapterSCSIHost virStorageAdapterSCSIHost; -typedef virStorageAdapterSCSIHost *virStorageAdapterSCSIHostPtr; -struct _virStorageAdapterSCSIHost { - char *name; - virPCIDeviceAddress parentaddr; /* host address */ - int unique_id; - bool has_parent; -}; - -typedef struct _virStorageAdapterFCHost virStorageAdapterFCHost; -typedef virStorageAdapterFCHost *virStorageAdapterFCHostPtr; -struct _virStorageAdapterFCHost { - char *parent; - char *parent_wwnn; - char *parent_wwpn; - char *parent_fabric_wwn; - char *wwnn; - char *wwpn; - int managed; /* enum virTristateSwitch */ -}; - -typedef struct _virStoragePoolSourceAdapter virStoragePoolSourceAdapter; -typedef virStoragePoolSourceAdapter *virStoragePoolSourceAdapterPtr; -struct _virStoragePoolSourceAdapter { - int type; /* virStoragePoolSourceAdapterType */ - - union { - virStorageAdapterSCSIHost scsi_host; - virStorageAdapterFCHost fchost; - } data; -}; - typedef struct _virStoragePoolSource virStoragePoolSource; typedef virStoragePoolSource *virStoragePoolSourcePtr; struct _virStoragePoolSource { @@ -226,7 +186,7 @@ struct _virStoragePoolSource { char *dir; /* Or an adapter */ - virStoragePoolSourceAdapter adapter; + virStorageAdapter adapter; /* Or a name */ char *name; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6a2bdf2..8a9e71b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -883,8 +883,6 @@ virStoragePoolObjSaveDef; virStoragePoolObjUnlock; virStoragePoolSaveConfig; virStoragePoolSaveState; -virStoragePoolSourceAdapterTypeFromString; -virStoragePoolSourceAdapterTypeToString; virStoragePoolSourceClear; virStoragePoolSourceDeviceClear; virStoragePoolSourceFindDuplicate; diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index 7a5df3f..39fa026 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -2467,8 +2467,7 @@ phypBuildStoragePool(virConnectPtr conn, virStoragePoolDefPtr def) int exit_status = 0; virBuffer buf = VIR_BUFFER_INITIALIZER; - if (source.adapter.type != - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + if (source.adapter.type != VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Only 'scsi_host' adapter is supported")); goto cleanup; diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index 77a51ff..ff17409 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -176,12 +176,12 @@ virStoragePoolFCRefreshThread(void *opaque) } static char * -getAdapterName(virStoragePoolSourceAdapterPtr adapter) +getAdapterName(virStorageAdapterPtr adapter) { char *name = NULL; char *parentaddr = NULL; - if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { virStorageAdapterSCSIHostPtr scsi_host = &adapter->data.scsi_host; if (scsi_host->has_parent) { @@ -197,7 +197,9 @@ getAdapterName(virStoragePoolSourceAdapterPtr adapter) } else { ignore_value(VIR_STRDUP(name, scsi_host->name)); } - } else if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + } + + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { virStorageAdapterFCHostPtr fchost = &adapter->data.fchost; if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { @@ -451,7 +453,7 @@ virStorageBackendSCSICheckPool(virStoragePoolObjPtr pool, * the adapter based on might be not created yet. */ if (pool->def->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { virResetLastError(); return 0; } else { @@ -505,24 +507,24 @@ virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, return ret; } + static int virStorageBackendSCSIStartPool(virConnectPtr conn, virStoragePoolObjPtr pool) { - if (pool->def->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) + if (pool->def->source.adapter.type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) return createVport(conn, pool->def, pool->configFile, &pool->def->source.adapter.data.fchost); return 0; } + static int virStorageBackendSCSIStopPool(virConnectPtr conn, virStoragePoolObjPtr pool) { - if (pool->def->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) + if (pool->def->source.adapter.type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) return deleteVport(conn, &pool->def->source.adapter.data.fchost); return 0; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index cf7820a..18792bc 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -4420,8 +4420,7 @@ testStoragePoolCreateXML(virConnectPtr conn, goto cleanup; def = NULL; - if (pool->def->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (pool->def->source.adapter.type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { /* 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. The mock routine will copy an existing vHBA and @@ -4623,7 +4622,7 @@ testStoragePoolDestroy(virStoragePoolPtr pool) privpool->active = 0; if (privpool->def->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { if (testDestroyVport(privconn, privpool->def->source.adapter.data.fchost.wwnn, privpool->def->source.adapter.data.fchost.wwpn) < 0) -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Move the virStoragePoolSourceAdapter from storage_conf.h and rename to virStorageAdapter.
Continue with code realignment for brevity and flow.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 71 ++++++++++++++++++-------------------- src/conf/storage_adapter_conf.h | 51 ++++++++++++++++++++++++--- src/conf/storage_conf.c | 32 ++++++++--------- src/conf/storage_conf.h | 44 ++--------------------- src/libvirt_private.syms | 2 -- src/phyp/phyp_driver.c | 3 +- src/storage/storage_backend_scsi.c | 18 +++++----- src/test/test_driver.c | 5 ++- 8 files changed, 109 insertions(+), 117 deletions(-)
diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index 6efe5ae..53c07c7 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -19,7 +19,7 @@
#include <config.h>
-#include "storage_adapter_conf.h" +#include "storage_conf.h"
#include "viralloc.h" #include "virerror.h" @@ -32,11 +32,10 @@
VIR_LOG_INIT("conf.storage_adapter_conf");
-VIR_ENUM_IMPL(virStoragePoolSourceAdapter, - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_LAST, +VIR_ENUM_IMPL(virStorageAdapter, + VIR_STORAGE_ADAPTER_TYPE_LAST, "default", "scsi_host", "fc_host")
- static void virStorageAdapterFCHostClear(virStorageAdapterFCHostPtr fchost) { @@ -50,12 +49,12 @@ virStorageAdapterFCHostClear(virStorageAdapterFCHostPtr fchost)
void -virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter) +virStorageAdapterClear(virStorageAdapterPtr adapter) { - if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) virStorageAdapterFCHostClear(&adapter->data.fchost);
- if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) VIR_FREE(adapter->data.scsi_host.name); }
@@ -123,7 +122,7 @@ virStorageAdapterSCSIHostParseXML(xmlNodePtr node, static int virStorageAdapterLegacyParseXML(xmlNodePtr node, xmlXPathContextPtr ctxt, - virStoragePoolSourceAdapterPtr adapter) + virStorageAdapterPtr adapter) { char *wwnn = virXMLPropString(node, "wwnn"); char *wwpn = virXMLPropString(node, "wwpn"); @@ -154,14 +153,14 @@ virStorageAdapterLegacyParseXML(xmlNodePtr node, * for scsi_host adapter. */ if ((adapter->data.scsi_host.name = virXMLPropString(node, "name"))) - adapter->type = VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST; + adapter->type = VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST;
return 0; }
int -virStorageAdapterParseXML(virStoragePoolSourcePtr source, +virStorageAdapterParseXML(virStorageAdapterPtr adapter, xmlNodePtr node, xmlXPathContextPtr ctxt) { @@ -172,26 +171,24 @@ virStorageAdapterParseXML(virStoragePoolSourcePtr source, ctxt->node = node;
if ((adapter_type = virXMLPropString(node, "type"))) { - if ((source->adapter.type = - virStoragePoolSourceAdapterTypeFromString(adapter_type)) <= 0) { + if ((adapter->type = + virStorageAdapterTypeFromString(adapter_type)) <= 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Unknown pool adapter type '%s'"), adapter_type); goto cleanup; }
- if (source->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { - if (virStorageAdapterFCHostParseXML(node, &source->adapter.data.fchost) < 0) - goto cleanup; - } else if (source->adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { - if (virStorageAdapterSCSIHostParseXML(node, ctxt, &source->adapter.data.scsi_host) < 0) + if ((adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) && + (virStorageAdapterFCHostParseXML(node, &adapter->data.fchost)) < 0) goto cleanup;
- } + if ((adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) && + (virStorageAdapterSCSIHostParseXML(node, ctxt, + &adapter->data.scsi_host)) < 0) + goto cleanup; } else { - if (virStorageAdapterLegacyParseXML(node, ctxt, &source->adapter) < 0) + if (virStorageAdapterLegacyParseXML(node, ctxt, adapter) < 0) goto cleanup; }
@@ -260,21 +257,19 @@ virStorageAdapterSCSIHostParseValidate(virStorageAdapterSCSIHostPtr scsi_host)
int -virStorageAdapterParseValidate(virStoragePoolDefPtr ret) +virStorageAdapterParseValidate(virStorageAdapterPtr adapter) { - if (!ret->source.adapter.type) { + if (!adapter->type) { virReportError(VIR_ERR_XML_ERROR, "%s", _("missing storage pool source adapter")); return -1; }
- if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) - return virStorageAdapterFCHostParseValidate(&ret->source.adapter.data.fchost); + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) + return virStorageAdapterFCHostParseValidate(&adapter->data.fchost);
- if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) - return virStorageAdapterSCSIHostParseValidate(&ret->source.adapter.data.scsi_host); + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) + return virStorageAdapterSCSIHostParseValidate(&adapter->data.scsi_host);
return 0; } @@ -285,13 +280,13 @@ virStorageAdapterFCHostFormat(virBufferPtr buf, virStorageAdapterFCHostPtr fchost) { virBufferEscapeString(buf, " parent='%s'", fchost->parent); - if (fchost->managed) - virBufferAsprintf(buf, " managed='%s'", - virTristateBoolTypeToString(fchost->managed)); virBufferEscapeString(buf, " parent_wwnn='%s'", fchost->parent_wwnn); virBufferEscapeString(buf, " parent_wwpn='%s'", fchost->parent_wwpn); virBufferEscapeString(buf, " parent_fabric_wwn='%s'", fchost->parent_fabric_wwn); + if (fchost->managed != VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, " managed='%s'", + virTristateBoolTypeToString(fchost->managed));
No test cases that are tripped up by this change in order? (Not saying there need to be, just wondering...)
virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", fchost->wwnn, fchost->wwpn); @@ -322,14 +317,14 @@ virStorageAdapterSCSIHostFormat(virBufferPtr buf,
void virStorageAdapterFormat(virBufferPtr buf, - virStoragePoolSourcePtr src) + virStorageAdapterPtr adapter) { virBufferAsprintf(buf, "<adapter type='%s'", - virStoragePoolSourceAdapterTypeToString(src->adapter.type)); + virStorageAdapterTypeToString(adapter->type));
- if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) - virStorageAdapterFCHostFormat(buf, &src->adapter.data.fchost); + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) + virStorageAdapterFCHostFormat(buf, &adapter->data.fchost);
- if (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) - virStorageAdapterSCSIHostFormat(buf, &src->adapter.data.scsi_host); + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) + virStorageAdapterSCSIHostFormat(buf, &adapter->data.scsi_host); } diff --git a/src/conf/storage_adapter_conf.h b/src/conf/storage_adapter_conf.h index ec812a1..730a3ca 100644 --- a/src/conf/storage_adapter_conf.h +++ b/src/conf/storage_adapter_conf.h @@ -23,21 +23,62 @@ # include "virpci.h" # include "virxml.h"
-# include "storage_conf.h" + +typedef enum { + VIR_STORAGE_ADAPTER_TYPE_DEFAULT = 0, + VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST, + VIR_STORAGE_ADAPTER_TYPE_FC_HOST, + + VIR_STORAGE_ADAPTER_TYPE_LAST, +} virStorageAdapterType; +VIR_ENUM_DECL(virStorageAdapter) + +typedef struct _virStorageAdapterSCSIHost virStorageAdapterSCSIHost; +typedef virStorageAdapterSCSIHost *virStorageAdapterSCSIHostPtr; +struct _virStorageAdapterSCSIHost { + char *name; + virPCIDeviceAddress parentaddr; /* host address */ + int unique_id; + bool has_parent; +}; + +typedef struct _virStorageAdapterFCHost virStorageAdapterFCHost; +typedef virStorageAdapterFCHost *virStorageAdapterFCHostPtr; +struct _virStorageAdapterFCHost { + char *parent; + char *parent_wwnn; + char *parent_wwpn; + char *parent_fabric_wwn; + char *wwnn; + char *wwpn; + int managed; /* enum virTristateSwitch */ +}; + +typedef struct _virStorageAdapter virStorageAdapter; +typedef virStorageAdapter *virStorageAdapterPtr; +struct _virStorageAdapter { + int type; /* virStorageAdapterType */ + + union { + virStorageAdapterSCSIHost scsi_host; + virStorageAdapterFCHost fchost; + } data; +}; +
void -virStorageAdapterClear(virStoragePoolSourceAdapterPtr adapter); +virStorageAdapterClear(virStorageAdapterPtr adapter);
int -virStorageAdapterParseXML(virStoragePoolSourcePtr source, +virStorageAdapterParseXML(virStorageAdapterPtr adapter, xmlNodePtr node, xmlXPathContextPtr ctxt);
int -virStorageAdapterParseValidate(virStoragePoolDefPtr ret); +virStorageAdapterParseValidate(virStorageAdapterPtr adapter);
void virStorageAdapterFormat(virBufferPtr buf, - virStoragePoolSourcePtr src); + virStorageAdapterPtr adapter);
#endif /* __VIR_STORAGE_ADAPTER_CONF_H__ */ diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 45dc860..7207605 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -565,7 +565,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, goto cleanup;
if ((adapternode = virXPathNode("./adapter", ctxt))) { - if (virStorageAdapterParseXML(source, adapternode, ctxt) < 0) + if (virStorageAdapterParseXML(&source->adapter, adapternode, ctxt) < 0) goto cleanup; }
@@ -802,7 +802,7 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) }
if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) && - (virStorageAdapterParseValidate(ret)) < 0) + (virStorageAdapterParseValidate(&ret->source.adapter)) < 0) goto error;
/* If DEVICE is the only source type, then its required */ @@ -958,9 +958,9 @@ virStoragePoolSourceFormat(virBufferPtr buf, virBufferEscapeString(buf, "<dir path='%s'/>\n", src->dir);
if ((options->flags & VIR_STORAGE_POOL_SOURCE_ADAPTER) && - (src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST || - src->adapter.type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST)) - virStorageAdapterFormat(buf, src); + (src->adapter.type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST || + src->adapter.type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST)) + virStorageAdapterFormat(buf, &src->adapter);
if (options->flags & VIR_STORAGE_POOL_SOURCE_NAME) virBufferEscapeString(buf, "<name>%s</name>\n", src->name); @@ -2266,8 +2266,8 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, int ret = 1; virStoragePoolObjPtr pool = NULL; virStoragePoolObjPtr matchpool = NULL; - virStoragePoolSourceAdapterPtr pool_adapter; - virStoragePoolSourceAdapterPtr def_adapter; + virStorageAdapterPtr pool_adapter; + virStorageAdapterPtr def_adapter;
/* Check the pool list for duplicate underlying storage */ for (i = 0; i < pools->count; i++) { @@ -2306,10 +2306,8 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, pool_adapter = &pool->def->source.adapter; def_adapter = &def->source.adapter;
- if (pool_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST && - def_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (pool_adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST && + def_adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { virStorageAdapterFCHostPtr pool_fchost = &pool_adapter->data.fchost; virStorageAdapterFCHostPtr def_fchost = @@ -2319,9 +2317,9 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, STREQ(pool_fchost->wwpn, def_fchost->wwpn)) matchpool = pool; } else if (pool_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST && + VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST && def_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { virStorageAdapterSCSIHostPtr pool_scsi_host = &pool_adapter->data.scsi_host; virStorageAdapterSCSIHostPtr def_scsi_host = @@ -2341,9 +2339,9 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, if (pool_hostnum == def_hostnum) matchpool = pool; } else if (pool_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST && + VIR_STORAGE_ADAPTER_TYPE_FC_HOST && def_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { virStorageAdapterFCHostPtr pool_fchost = &pool_adapter->data.fchost; virStorageAdapterSCSIHostPtr def_scsi_host = @@ -2360,9 +2358,9 @@ virStoragePoolSourceFindDuplicate(virConnectPtr conn, }
} else if (pool_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST && + VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST && def_adapter->type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { virStorageAdapterSCSIHostPtr pool_scsi_host = &pool_adapter->data.scsi_host; virStorageAdapterFCHostPtr def_fchost = diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index 1012e74..6f20111 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -31,6 +31,7 @@ # include "virthread.h" # include "device_conf.h" # include "object_event.h" +# include "storage_adapter_conf.h"
# include <libxml/tree.h>
@@ -170,47 +171,6 @@ struct _virStoragePoolSourceDevice { } geometry; };
-typedef enum { - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_DEFAULT = 0, - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST, - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST, - - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_LAST, -} virStoragePoolSourceAdapterType; -VIR_ENUM_DECL(virStoragePoolSourceAdapter) - -typedef struct _virStorageAdapterSCSIHost virStorageAdapterSCSIHost; -typedef virStorageAdapterSCSIHost *virStorageAdapterSCSIHostPtr; -struct _virStorageAdapterSCSIHost { - char *name; - virPCIDeviceAddress parentaddr; /* host address */ - int unique_id; - bool has_parent; -}; - -typedef struct _virStorageAdapterFCHost virStorageAdapterFCHost; -typedef virStorageAdapterFCHost *virStorageAdapterFCHostPtr; -struct _virStorageAdapterFCHost { - char *parent; - char *parent_wwnn; - char *parent_wwpn; - char *parent_fabric_wwn; - char *wwnn; - char *wwpn; - int managed; /* enum virTristateSwitch */ -}; - -typedef struct _virStoragePoolSourceAdapter virStoragePoolSourceAdapter; -typedef virStoragePoolSourceAdapter *virStoragePoolSourceAdapterPtr; -struct _virStoragePoolSourceAdapter { - int type; /* virStoragePoolSourceAdapterType */ - - union { - virStorageAdapterSCSIHost scsi_host; - virStorageAdapterFCHost fchost; - } data; -}; - typedef struct _virStoragePoolSource virStoragePoolSource; typedef virStoragePoolSource *virStoragePoolSourcePtr; struct _virStoragePoolSource { @@ -226,7 +186,7 @@ struct _virStoragePoolSource { char *dir;
/* Or an adapter */ - virStoragePoolSourceAdapter adapter; + virStorageAdapter adapter;
/* Or a name */ char *name; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6a2bdf2..8a9e71b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -883,8 +883,6 @@ virStoragePoolObjSaveDef; virStoragePoolObjUnlock; virStoragePoolSaveConfig; virStoragePoolSaveState; -virStoragePoolSourceAdapterTypeFromString; -virStoragePoolSourceAdapterTypeToString;
These are no longer used globally? (Just making sure)
virStoragePoolSourceClear; virStoragePoolSourceDeviceClear; virStoragePoolSourceFindDuplicate; diff --git a/src/phyp/phyp_driver.c b/src/phyp/phyp_driver.c index 7a5df3f..39fa026 100644 --- a/src/phyp/phyp_driver.c +++ b/src/phyp/phyp_driver.c @@ -2467,8 +2467,7 @@ phypBuildStoragePool(virConnectPtr conn, virStoragePoolDefPtr def) int exit_status = 0; virBuffer buf = VIR_BUFFER_INITIALIZER;
- if (source.adapter.type != - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + if (source.adapter.type != VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Only 'scsi_host' adapter is supported")); goto cleanup; diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index 77a51ff..ff17409 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -176,12 +176,12 @@ virStoragePoolFCRefreshThread(void *opaque) }
static char * -getAdapterName(virStoragePoolSourceAdapterPtr adapter) +getAdapterName(virStorageAdapterPtr adapter) { char *name = NULL; char *parentaddr = NULL;
- if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { virStorageAdapterSCSIHostPtr scsi_host = &adapter->data.scsi_host;
if (scsi_host->has_parent) { @@ -197,7 +197,9 @@ getAdapterName(virStoragePoolSourceAdapterPtr adapter) } else { ignore_value(VIR_STRDUP(name, scsi_host->name)); } - } else if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + } + + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) {
If you're just getting rid of the "} else" in order to shorten the line, then I'd say leave it in...
virStorageAdapterFCHostPtr fchost = &adapter->data.fchost;
if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { @@ -451,7 +453,7 @@ virStorageBackendSCSICheckPool(virStoragePoolObjPtr pool, * the adapter based on might be not created yet. */ if (pool->def->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { virResetLastError(); return 0; } else { @@ -505,24 +507,24 @@ virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, return ret; }
+ static int virStorageBackendSCSIStartPool(virConnectPtr conn, virStoragePoolObjPtr pool) { - if (pool->def->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) + if (pool->def->source.adapter.type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) return createVport(conn, pool->def, pool->configFile, &pool->def->source.adapter.data.fchost);
return 0; }
+ static int virStorageBackendSCSIStopPool(virConnectPtr conn, virStoragePoolObjPtr pool) { - if (pool->def->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) + if (pool->def->source.adapter.type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) return deleteVport(conn, &pool->def->source.adapter.data.fchost);
return 0; diff --git a/src/test/test_driver.c b/src/test/test_driver.c index cf7820a..18792bc 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -4420,8 +4420,7 @@ testStoragePoolCreateXML(virConnectPtr conn, goto cleanup; def = NULL;
- if (pool->def->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + if (pool->def->source.adapter.type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { /* 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. The mock routine will copy an existing vHBA and @@ -4623,7 +4622,7 @@ testStoragePoolDestroy(virStoragePoolPtr pool) privpool->active = 0;
if (privpool->def->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { if (testDestroyVport(privconn, privpool->def->source.adapter.data.fchost.wwnn, privpool->def->source.adapter.data.fchost.wwpn) < 0)
ACK.

On 03/12/2017 05:53 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
Move the virStoragePoolSourceAdapter from storage_conf.h and rename to virStorageAdapter.
Continue with code realignment for brevity and flow.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 71 ++++++++++++++++++-------------------- src/conf/storage_adapter_conf.h | 51 ++++++++++++++++++++++++--- src/conf/storage_conf.c | 32 ++++++++--------- src/conf/storage_conf.h | 44 ++--------------------- src/libvirt_private.syms | 2 -- src/phyp/phyp_driver.c | 3 +- src/storage/storage_backend_scsi.c | 18 +++++----- src/test/test_driver.c | 5 ++- 8 files changed, 109 insertions(+), 117 deletions(-)
diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index 6efe5ae..53c07c7 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -19,7 +19,7 @@
[...]
int -virStorageAdapterParseValidate(virStoragePoolDefPtr ret) +virStorageAdapterParseValidate(virStorageAdapterPtr adapter) { - if (!ret->source.adapter.type) { + if (!adapter->type) { virReportError(VIR_ERR_XML_ERROR, "%s", _("missing storage pool source adapter")); return -1; }
- if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) - return virStorageAdapterFCHostParseValidate(&ret->source.adapter.data.fchost); + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) + return virStorageAdapterFCHostParseValidate(&adapter->data.fchost);
- if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) - return virStorageAdapterSCSIHostParseValidate(&ret->source.adapter.data.scsi_host); + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) + return virStorageAdapterSCSIHostParseValidate(&adapter->data.scsi_host);
return 0; } @@ -285,13 +280,13 @@ virStorageAdapterFCHostFormat(virBufferPtr buf, virStorageAdapterFCHostPtr fchost) { virBufferEscapeString(buf, " parent='%s'", fchost->parent); - if (fchost->managed) - virBufferAsprintf(buf, " managed='%s'", - virTristateBoolTypeToString(fchost->managed)); virBufferEscapeString(buf, " parent_wwnn='%s'", fchost->parent_wwnn); virBufferEscapeString(buf, " parent_wwpn='%s'", fchost->parent_wwpn); virBufferEscapeString(buf, " parent_fabric_wwn='%s'", fchost->parent_fabric_wwn); + if (fchost->managed != VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, " managed='%s'", + virTristateBoolTypeToString(fchost->managed));
No test cases that are tripped up by this change in order? (Not saying there need to be, just wondering...)
No - the managed would probably only appear as "managed='no'", although managed='yes' is the de facto default and essentially determines whether or not to destroy the vHBA when the pool is destroyed. I can move it if really desired/required - I guess I saw it as something "after" defining parent, parent_wwnn/wwpn, or parent_fabric_wwn - when adding those I should have put them after parent. Yeah, I know could have been a separate patch.
virBufferAsprintf(buf, " wwnn='%s' wwpn='%s'/>\n", fchost->wwnn, fchost->wwpn); @@ -322,14 +317,14 @@ virStorageAdapterSCSIHostFormat(virBufferPtr buf,
[...]
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6a2bdf2..8a9e71b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -883,8 +883,6 @@ virStoragePoolObjSaveDef; virStoragePoolObjUnlock; virStoragePoolSaveConfig; virStoragePoolSaveState; -virStoragePoolSourceAdapterTypeFromString; -virStoragePoolSourceAdapterTypeToString;
These are no longer used globally? (Just making sure)
Nope - replaced by virStorageAdapterType{From|To}String which are only local to storage_adapter_conf.c... That's the VIR_ENUM_IMPL change.
virStoragePoolSourceClear; virStoragePoolSourceDeviceClear; virStoragePoolSourceFindDuplicate;
[...]
diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index 77a51ff..ff17409 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -176,12 +176,12 @@ virStoragePoolFCRefreshThread(void *opaque) }
static char * -getAdapterName(virStoragePoolSourceAdapterPtr adapter) +getAdapterName(virStorageAdapterPtr adapter) { char *name = NULL; char *parentaddr = NULL;
- if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) { + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) { virStorageAdapterSCSIHostPtr scsi_host = &adapter->data.scsi_host;
if (scsi_host->has_parent) { @@ -197,7 +197,9 @@ getAdapterName(virStoragePoolSourceAdapterPtr adapter) } else { ignore_value(VIR_STRDUP(name, scsi_host->name)); } - } else if (adapter->type == VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + } + + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) {
If you're just getting rid of the "} else" in order to shorten the line, then I'd say leave it in...
OK
virStorageAdapterFCHostPtr fchost = &adapter->data.fchost;
if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { @@ -451,7 +453,7 @@ virStorageBackendSCSICheckPool(virStoragePoolObjPtr pool, * the adapter based on might be not created yet. */ if (pool->def->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) { + VIR_STORAGE_ADAPTER_TYPE_FC_HOST) { virResetLastError(); return 0; } else { @@ -505,24 +507,24 @@ virStorageBackendSCSIRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, return ret; }
[...]
ACK.
Before I go off and push all this - just want to double check if you desire to see the adjustments in a v4 series or do you feel comfortable enough with a "summary"? 1. The virStorageAdapterPtr and friends had no changes to their names. 2. The function/helper names are now: virStorageAdapterClearFCHost virStorageAdapterClear virStorageAdapterParseXMLFCHost virStorageAdapterParseXMLSCSIHost virStorageAdapterParseXMLLegacy ** virStorageAdapterParseXML virStorageAdapterValidateFCHost virStorageAdapterValidateSCSIHost virStorageAdapterValidate virStorageAdapterFormatFCHost virStorageAdapterFormatSCSIHost virStorageAdapterFormat ** No such thing as a short comment ;-) 3. In patch1 rather than the single if statement - there are now two. The end result is the following check: if ((fchost->parent_wwnn && !fchost->parent_wwpn)) { virReportError(VIR_ERR_XML_ERROR, _("when providing parent_wwnn='%s', the " "parent_wwpn must also be provided"), fchost->parent_wwnn); return -1; } if (!fchost->parent_wwnn && fchost->parent_wwpn) { virReportError(VIR_ERR_XML_ERROR, _("when providing parent_wwpn='%s', the " "parent_wwnn must also be provided"), fchost->parent_wwpn); return -1; } which I'll replicate in a separately posted patch for node_device_conf 4. Using virPCIDeviceAddressPtr in getSCSIHostNumber and getAdapterName. Ironically the "original" series I had passed along the virStorageAdapterSCSIHostPtr, but since it's been decreed that a src/util function cannot include a src/conf header, I had to back that off. Tks - John

On 03/15/2017 09:33 AM, John Ferlan wrote:
On 03/12/2017 05:53 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
Move the virStoragePoolSourceAdapter from storage_conf.h and rename to virStorageAdapter.
Continue with code realignment for brevity and flow.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/storage_adapter_conf.c | 71 ++++++++++++++++++-------------------- src/conf/storage_adapter_conf.h | 51 ++++++++++++++++++++++++--- src/conf/storage_conf.c | 32 ++++++++--------- src/conf/storage_conf.h | 44 ++--------------------- src/libvirt_private.syms | 2 -- src/phyp/phyp_driver.c | 3 +- src/storage/storage_backend_scsi.c | 18 +++++----- src/test/test_driver.c | 5 ++- 8 files changed, 109 insertions(+), 117 deletions(-)
diff --git a/src/conf/storage_adapter_conf.c b/src/conf/storage_adapter_conf.c index 6efe5ae..53c07c7 100644 --- a/src/conf/storage_adapter_conf.c +++ b/src/conf/storage_adapter_conf.c @@ -19,7 +19,7 @@
[...]
int -virStorageAdapterParseValidate(virStoragePoolDefPtr ret) +virStorageAdapterParseValidate(virStorageAdapterPtr adapter) { - if (!ret->source.adapter.type) { + if (!adapter->type) { virReportError(VIR_ERR_XML_ERROR, "%s", _("missing storage pool source adapter")); return -1; }
- if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_FC_HOST) - return virStorageAdapterFCHostParseValidate(&ret->source.adapter.data.fchost); + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) + return virStorageAdapterFCHostParseValidate(&adapter->data.fchost);
- if (ret->source.adapter.type == - VIR_STORAGE_POOL_SOURCE_ADAPTER_TYPE_SCSI_HOST) - return virStorageAdapterSCSIHostParseValidate(&ret->source.adapter.data.scsi_host); + if (adapter->type == VIR_STORAGE_ADAPTER_TYPE_SCSI_HOST) + return virStorageAdapterSCSIHostParseValidate(&adapter->data.scsi_host);
return 0; } @@ -285,13 +280,13 @@ virStorageAdapterFCHostFormat(virBufferPtr buf, virStorageAdapterFCHostPtr fchost) { virBufferEscapeString(buf, " parent='%s'", fchost->parent); - if (fchost->managed) - virBufferAsprintf(buf, " managed='%s'", - virTristateBoolTypeToString(fchost->managed)); virBufferEscapeString(buf, " parent_wwnn='%s'", fchost->parent_wwnn); virBufferEscapeString(buf, " parent_wwpn='%s'", fchost->parent_wwpn); virBufferEscapeString(buf, " parent_fabric_wwn='%s'", fchost->parent_fabric_wwn); + if (fchost->managed != VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, " managed='%s'", + virTristateBoolTypeToString(fchost->managed));
No test cases that are tripped up by this change in order? (Not saying there need to be, just wondering...)
No - the managed would probably only appear as "managed='no'", although managed='yes' is the de facto default and essentially determines whether or not to destroy the vHBA when the pool is destroyed.
I can move it if really desired/required
Nah, order is supposed to not matter, and any code that relies on the order of the elements is broken and needs to be fixed. That's the only reason I thought of the unit tests.
Before I go off and push all this - just want to double check if you desire to see the adjustments in a v4 series or do you feel comfortable enough with a "summary"?
The summary is fine.
1. The virStorageAdapterPtr and friends had no changes to their names.
2. The function/helper names are now:
virStorageAdapterClearFCHost virStorageAdapterClear virStorageAdapterParseXMLFCHost virStorageAdapterParseXMLSCSIHost virStorageAdapterParseXMLLegacy ** virStorageAdapterParseXML virStorageAdapterValidateFCHost virStorageAdapterValidateSCSIHost virStorageAdapterValidate virStorageAdapterFormatFCHost virStorageAdapterFormatSCSIHost virStorageAdapterFormat
** No such thing as a short comment ;-)
3. In patch1 rather than the single if statement - there are now two. The end result is the following check:
if ((fchost->parent_wwnn && !fchost->parent_wwpn)) { virReportError(VIR_ERR_XML_ERROR, _("when providing parent_wwnn='%s', the " "parent_wwpn must also be provided"), fchost->parent_wwnn); return -1; }
if (!fchost->parent_wwnn && fchost->parent_wwpn) { virReportError(VIR_ERR_XML_ERROR, _("when providing parent_wwpn='%s', the " "parent_wwnn must also be provided"), fchost->parent_wwpn); return -1; }
which I'll replicate in a separately posted patch for node_device_conf
Yeah, that sounds more understandable.
4. Using virPCIDeviceAddressPtr in getSCSIHostNumber and getAdapterName. Ironically the "original" series I had passed along the virStorageAdapterSCSIHostPtr, but since it's been decreed that a src/util function cannot include a src/conf header, I had to back that off.
But virPCIDeviceAddressPtr is defined in src/util/virpci.c. There are *other* address types that are defined in conf (e.g. virDomainDeviceDriveAddress), but not PCI addresses.

[...]
4. Using virPCIDeviceAddressPtr in getSCSIHostNumber and getAdapterName. Ironically the "original" series I had passed along the virStorageAdapterSCSIHostPtr, but since it's been decreed that a src/util function cannot include a src/conf header, I had to back that off.
But virPCIDeviceAddressPtr is defined in src/util/virpci.c. There are *other* address types that are defined in conf (e.g. virDomainDeviceDriveAddress), but not PCI addresses.
Well _virPCIDeviceAddress is in virpci.c, but virPCIDeviceAddressPtr is in virpci.h... I could change virSCSIHostGetNameByParentaddr to take a virPCIDeviceAddressPtr and a unique_id - but I'll let that be separate from this series because there's way too much going on already. John

On 03/15/2017 01:59 PM, John Ferlan wrote:
[...]
4. Using virPCIDeviceAddressPtr in getSCSIHostNumber and getAdapterName. Ironically the "original" series I had passed along the virStorageAdapterSCSIHostPtr, but since it's been decreed that a src/util function cannot include a src/conf header, I had to back that off.
But virPCIDeviceAddressPtr is defined in src/util/virpci.c. There are *other* address types that are defined in conf (e.g. virDomainDeviceDriveAddress), but not PCI addresses.
Well _virPCIDeviceAddress is in virpci.c, but virPCIDeviceAddressPtr is in virpci.h...
Yeah, that's what I meant. Just mistyped.

The function is actually in virutil.c, but prototyped in virfile.h. This patch fixes that by renaming the function to virWaitForDevices, adding the prototype in virutil.h and libvirt_private.syms, and then changing the callers to use the new name. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/libvirt_private.syms | 2 +- src/node_device/node_device_driver.c | 2 +- src/storage/storage_backend_disk.c | 6 +++--- src/storage/storage_backend_iscsi.c | 2 +- src/storage/storage_backend_logical.c | 4 ++-- src/storage/storage_backend_mpath.c | 2 +- src/storage/storage_backend_scsi.c | 2 +- src/storage/storage_util.c | 2 +- src/util/virfile.h | 2 -- src/util/virutil.c | 4 ++-- src/util/virutil.h | 2 ++ 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8a9e71b..7bdcde7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1648,7 +1648,6 @@ virFileStripSuffix; virFileTouch; virFileUnlock; virFileUpdatePerm; -virFileWaitForDevices; virFileWrapperFdClose; virFileWrapperFdFree; virFileWrapperFdNew; @@ -2758,6 +2757,7 @@ virTristateSwitchTypeFromString; virTristateSwitchTypeToString; virUpdateSelfLastChanged; virValidateWWN; +virWaitForDevices; # util/viruuid.h diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index 39fd438..99f7bc5 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -548,7 +548,7 @@ find_new_device(virConnectPtr conn, const char *wwnn, const char *wwpn) while ((now - start) < LINUX_NEW_DEVICE_WAIT_TIME) { - virFileWaitForDevices(); + virWaitForDevices(); dev = nodeDeviceLookupSCSIHostByWWN(conn, wwnn, wwpn, 0); diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c index 50bdd36..39371f2 100644 --- a/src/storage/storage_backend_disk.c +++ b/src/storage/storage_backend_disk.c @@ -426,7 +426,7 @@ virStorageBackendDiskRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, VIR_FREE(pool->def->source.devices[0].freeExtents); pool->def->source.devices[0].nfreeExtent = 0; - virFileWaitForDevices(); + virWaitForDevices(); if (!virFileExists(pool->def->source.devices[0].path)) { virReportError(VIR_ERR_INVALID_ARG, @@ -450,7 +450,7 @@ virStorageBackendDiskStartPool(virConnectPtr conn ATTRIBUTE_UNUSED, virStoragePoolFormatDiskTypeToString(pool->def->source.format); const char *path = pool->def->source.devices[0].path; - virFileWaitForDevices(); + virWaitForDevices(); if (!virFileExists(path)) { virReportError(VIR_ERR_INVALID_ARG, @@ -859,7 +859,7 @@ virStorageBackendDiskCreateVol(virConnectPtr conn, goto cleanup; /* wait for device node to show up */ - virFileWaitForDevices(); + virWaitForDevices(); /* Blow away free extent info, as we're about to re-populate it */ VIR_FREE(pool->def->source.devices[0].freeExtents); diff --git a/src/storage/storage_backend_iscsi.c b/src/storage/storage_backend_iscsi.c index 866fa74..14f3e09 100644 --- a/src/storage/storage_backend_iscsi.c +++ b/src/storage/storage_backend_iscsi.c @@ -98,7 +98,7 @@ virStorageBackendISCSIGetHostNumber(const char *sysfs_path, VIR_DEBUG("Finding host number from '%s'", sysfs_path); - virFileWaitForDevices(); + virWaitForDevices(); if (virDirOpen(&sysdir, sysfs_path) < 0) goto cleanup; diff --git a/src/storage/storage_backend_logical.c b/src/storage/storage_backend_logical.c index 756c62e..29d63b1 100644 --- a/src/storage/storage_backend_logical.c +++ b/src/storage/storage_backend_logical.c @@ -831,7 +831,7 @@ virStorageBackendLogicalRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, virCommandPtr cmd = NULL; int ret = -1; - virFileWaitForDevices(); + virWaitForDevices(); /* Get list of all logical volumes */ if (virStorageBackendLogicalFindLVs(pool, NULL) < 0) @@ -925,7 +925,7 @@ virStorageBackendLogicalDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED, virCheckFlags(0, -1); - virFileWaitForDevices(); + virWaitForDevices(); lvchange_cmd = virCommandNewArgList(LVCHANGE, "-aln", vol->target.path, NULL); lvremove_cmd = virCommandNewArgList(LVREMOVE, "-f", vol->target.path, NULL); diff --git a/src/storage/storage_backend_mpath.c b/src/storage/storage_backend_mpath.c index 4bb38bb..606b399 100644 --- a/src/storage/storage_backend_mpath.c +++ b/src/storage/storage_backend_mpath.c @@ -262,7 +262,7 @@ virStorageBackendMpathRefreshPool(virConnectPtr conn ATTRIBUTE_UNUSED, pool->def->allocation = pool->def->capacity = pool->def->available = 0; - virFileWaitForDevices(); + virWaitForDevices(); virStorageBackendGetMaps(pool); diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index ff17409..abbd38d 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -349,7 +349,7 @@ createVport(virConnectPtr conn, VPORT_CREATE) < 0) goto cleanup; - virFileWaitForDevices(); + virWaitForDevices(); /* Creating our own VPORT didn't leave enough time to find any LUN's, * so, let's create a thread whose job it is to call the FindLU's with diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index bf6f0b3..38d373e 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -4017,7 +4017,7 @@ virStorageBackendSCSIFindLUs(virStoragePoolObjPtr pool, VIR_DEBUG("Discovering LUs on host %u", scanhost); - virFileWaitForDevices(); + virWaitForDevices(); if (virDirOpen(&devicedir, device_path) < 0) return -1; diff --git a/src/util/virfile.h b/src/util/virfile.h index f2a3faa..b29feee 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -292,8 +292,6 @@ int virFileOpenTty(int *ttymaster, char *virFileFindMountPoint(const char *type); -void virFileWaitForDevices(void); - /* NB: this should be combined with virFileBuildPath */ # define virBuildPath(path, ...) \ virBuildPathInternal(path, __VA_ARGS__, NULL) diff --git a/src/util/virutil.c b/src/util/virutil.c index bb0f2d2..79db1d8 100644 --- a/src/util/virutil.c +++ b/src/util/virutil.c @@ -1582,7 +1582,7 @@ virSetUIDGIDWithCaps(uid_t uid, gid_t gid, gid_t *groups, int ngroups, #if defined(UDEVADM) || defined(UDEVSETTLE) -void virFileWaitForDevices(void) +void virWaitForDevices(void) { # ifdef UDEVADM const char *const settleprog[] = { UDEVADM, "settle", NULL }; @@ -1603,7 +1603,7 @@ void virFileWaitForDevices(void) ignore_value(virRun(settleprog, &exitstatus)); } #else -void virFileWaitForDevices(void) +void virWaitForDevices(void) {} #endif diff --git a/src/util/virutil.h b/src/util/virutil.h index 877207c..e097b77 100644 --- a/src/util/virutil.h +++ b/src/util/virutil.h @@ -51,6 +51,8 @@ int virSetUIDGIDWithCaps(uid_t uid, gid_t gid, gid_t *groups, int ngroups, unsigned long long capBits, bool clearExistingCaps); +void virWaitForDevices(void); + int virScaleInteger(unsigned long long *value, const char *suffix, unsigned long long scale, unsigned long long limit) ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK; -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
The function is actually in virutil.c, but prototyped in virfile.h. This patch fixes that by renaming the function to virWaitForDevices, adding the prototype in virutil.h and libvirt_private.syms, and then changing the callers to use the new name.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/libvirt_private.syms | 2 +- src/node_device/node_device_driver.c | 2 +- src/storage/storage_backend_disk.c | 6 +++--- src/storage/storage_backend_iscsi.c | 2 +- src/storage/storage_backend_logical.c | 4 ++-- src/storage/storage_backend_mpath.c | 2 +- src/storage/storage_backend_scsi.c | 2 +- src/storage/storage_util.c | 2 +- src/util/virfile.h | 2 -- src/util/virutil.c | 4 ++-- src/util/virutil.h | 2 ++ 11 files changed, 15 insertions(+), 15 deletions(-)
ACK.

Move the bulk of the code to the node_device_conf and rename to virNodeDevice{Create|Delete}Vport. Alter the create algorithm slightly in order to return the name of the scsi_host vHBA that was created. The existing code would fetch the name and if it exists would start a thread looking for the LUNs; however, in no way did it validate the device was created for the storage pool even though it would be used thereafter. This slight change allows the code that checks if the node device by wwnn/wwpn already exists and return that name. This fixes a second yet seen issue that if the nodedev was present, but the parent by name wasn't provided (perhaps parent by wwnn/wwpn or by fabric_name), then a failure would be returned. For this path it shouldn't be an error - we should just be happy that something else is managing the device and we don't have to create/delete it. The end result is that the startVport code can now just start the thread once it gets a non NULL name back. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/node_device_conf.c | 211 +++++++++++++++++++++++++++++++++++++ src/conf/node_device_conf.h | 9 ++ src/libvirt_private.syms | 2 + src/storage/storage_backend_scsi.c | 192 +++------------------------------ 4 files changed, 235 insertions(+), 179 deletions(-) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 3565aec..66cb78d 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -1870,3 +1870,214 @@ virNodeDeviceGetParentName(virConnectPtr conn, return parent; } + + +/* + * Using the host# name found via wwnn/wwpn lookup in the fc_host + * sysfs tree to get the parent 'scsi_host#' to ensure it matches. + */ +static bool +nodeDeviceCheckParent(virConnectPtr conn, + const char *name, + const char *parent_name) +{ + char *scsi_host_name = NULL; + char *vhba_parent = NULL; + bool retval = false; + + VIR_DEBUG("conn=%p, name=%s, parent_name=%s", conn, name, parent_name); + + /* autostarted pool - assume we're OK */ + if (!conn) + return true; + + if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) + goto cleanup; + + if (!(vhba_parent = virNodeDeviceGetParentName(conn, scsi_host_name))) + goto cleanup; + + if (STRNEQ(parent_name, vhba_parent)) { + virReportError(VIR_ERR_XML_ERROR, + _("Parent attribute '%s' does not match parent '%s' " + "determined for the '%s' wwnn/wwpn lookup."), + parent_name, vhba_parent, name); + goto cleanup; + } + + retval = true; + + cleanup: + VIR_FREE(vhba_parent); + VIR_FREE(scsi_host_name); + return retval; +} + + +/** + * @conn: Connection pointer + * @fchost: Pointer to vHBA adapter + * + * Create a vHBA for Storage. This code accomplishes this via searching + * through the sysfs for scsi_host/fc_host in order to first ensure some + * vHBA doesn't already exist for the requested wwnn/wwpn (e.g. an unmanaged + * vHBA) and to search for the parent vport capable scsi_host by name, + * wwnn/wwpn, or fabric_wwn (if provided). If no parent is provided, then + * a vport capable scsi_host will be selected. + * + * Returns vHBA name on success, NULL on failure with an error message set + */ +char * +virNodeDeviceCreateVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost) +{ + unsigned int parent_host; + char *name = NULL; + char *parent_hoststr = NULL; + bool skip_capable_check = false; + + VIR_DEBUG("conn=%p, parent='%s', wwnn='%s' wwpn='%s'", + conn, NULLSTR(fchost->parent), fchost->wwnn, fchost->wwpn); + + /* If we find an existing HBA/vHBA within the fc_host sysfs + * using the wwnn/wwpn, then a nodedev is already created for + * this pool and we don't have to create the vHBA + */ + if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { + /* If a parent was provided, let's make sure the 'name' we've + * retrieved has the same parent. If not this will cause failure. */ + if (fchost->parent && nodeDeviceCheckParent(conn, name, fchost->parent)) + VIR_FREE(name); + + return name; + } + + if (fchost->parent) { + if (VIR_STRDUP(parent_hoststr, fchost->parent) < 0) + goto cleanup; + } else if (fchost->parent_wwnn && fchost->parent_wwpn) { + if (!(parent_hoststr = virVHBAGetHostByWWN(NULL, fchost->parent_wwnn, + fchost->parent_wwpn))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("cannot find parent using provided wwnn/wwpn")); + goto cleanup; + } + } else if (fchost->parent_fabric_wwn) { + if (!(parent_hoststr = + virVHBAGetHostByFabricWWN(NULL, fchost->parent_fabric_wwn))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("cannot find parent using provided fabric_wwn")); + goto cleanup; + } + } else { + if (!(parent_hoststr = virVHBAFindVportHost(NULL))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("'parent' for vHBA not specified, and " + "cannot find one on this host")); + goto cleanup; + } + skip_capable_check = true; + } + + if (virSCSIHostGetNumber(parent_hoststr, &parent_host) < 0) + goto cleanup; + + /* NOTE: + * We do not save the parent_hoststr in fchost->parent since + * we could be writing out the 'def' to the saved XML config. + * If we wrote out the name in the XML, then future starts would + * always use the same parent rather than finding the "best available" + * parent. Besides we have a way to determine the parent based on + * the 'name' field. + */ + if (!skip_capable_check && !virVHBAPathExists(NULL, parent_host)) { + virReportError(VIR_ERR_XML_ERROR, + _("parent '%s' specified for vHBA does not exist"), + parent_hoststr); + goto cleanup; + } + + if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, + VPORT_CREATE) < 0) + goto cleanup; + + /* Let's ensure the device was created */ + virWaitForDevices(); + if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { + ignore_value(virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, + VPORT_DELETE)); + goto cleanup; + } + + cleanup: + VIR_FREE(parent_hoststr); + return name; +} + + +/** + * @conn: Connection pointer + * @fchost: Pointer to vHBA adapter + * + * As long as the vHBA is being managed, search for the scsi_host via the + * provided wwnn/wwpn and then find the corresponding parent scsi_host in + * order to send the delete request. + * + * Returns 0 on success, -1 on failure + */ +int +virNodeDeviceDeleteVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost) +{ + char *name = NULL; + char *scsi_host_name = NULL; + unsigned int parent_host; + char *vhba_parent = NULL; + int ret = -1; + + VIR_DEBUG("conn=%p parent='%s', managed='%d' wwnn='%s' wwpn='%s'", + conn, NULLSTR(fchost->parent), fchost->managed, + fchost->wwnn, fchost->wwpn); + + /* If we're not managing the deletion of the vHBA, then just return */ + if (fchost->managed != VIR_TRISTATE_BOOL_YES) + return 0; + + /* Find our vHBA by searching the fc_host sysfs tree for our wwnn/wwpn */ + if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to find fc_host for wwnn='%s' and wwpn='%s'"), + fchost->wwnn, fchost->wwpn); + goto cleanup; + } + + /* If at startup time we provided a parent, then use that to + * get the parent_host value; otherwise, we have to determine + * the parent scsi_host which we did not save at startup time + */ + if (fchost->parent) { + if (virSCSIHostGetNumber(fchost->parent, &parent_host) < 0) + goto cleanup; + } else { + if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) + goto cleanup; + + if (!(vhba_parent = virNodeDeviceGetParentName(conn, scsi_host_name))) + goto cleanup; + + if (virSCSIHostGetNumber(vhba_parent, &parent_host) < 0) + goto cleanup; + } + + if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, + VPORT_DELETE) < 0) + goto cleanup; + + ret = 0; + + cleanup: + VIR_FREE(name); + VIR_FREE(vhba_parent); + VIR_FREE(scsi_host_name); + return ret; +} diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index cf51c69..15e2eac 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -28,8 +28,11 @@ # include "internal.h" # include "virbitmap.h" # include "virutil.h" +# include "virscsihost.h" # include "virpci.h" +# include "virvhba.h" # include "device_conf.h" +# include "storage_adapter_conf.h" # include <libxml/tree.h> @@ -354,4 +357,10 @@ char * virNodeDeviceGetParentName(virConnectPtr conn, const char *nodedev_name); +char *virNodeDeviceCreateVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost); + +int virNodeDeviceDeleteVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost); + #endif /* __VIR_NODE_DEVICE_CONF_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7bdcde7..cacc7aa 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -686,11 +686,13 @@ virNetDevIPRouteParseXML; virNodeDevCapsDefFree; virNodeDevCapTypeFromString; virNodeDevCapTypeToString; +virNodeDeviceCreateVport; virNodeDeviceDefFormat; virNodeDeviceDefFree; virNodeDeviceDefParseFile; virNodeDeviceDefParseNode; virNodeDeviceDefParseString; +virNodeDeviceDeleteVport; virNodeDeviceGetParentName; virNodeDeviceGetWWNs; diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index abbd38d..666e473 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -33,9 +33,7 @@ #include "virlog.h" #include "virfile.h" #include "vircommand.h" -#include "virscsihost.h" #include "virstring.h" -#include "virvhba.h" #include "storage_util.h" #include "node_device_conf.h" @@ -214,57 +212,13 @@ getAdapterName(virStorageAdapterPtr adapter) return name; } -/* - * Using the host# name found via wwnn/wwpn lookup in the fc_host - * sysfs tree to get the parent 'scsi_host#' to ensure it matches. - */ -static bool -checkParent(virConnectPtr conn, - const char *name, - const char *parent_name) -{ - char *scsi_host_name = NULL; - char *vhba_parent = NULL; - bool retval = false; - - VIR_DEBUG("conn=%p, name=%s, parent_name=%s", conn, name, parent_name); - - /* autostarted pool - assume we're OK */ - if (!conn) - return true; - - if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) - goto cleanup; - - if (!(vhba_parent = virNodeDeviceGetParentName(conn, scsi_host_name))) - goto cleanup; - - if (STRNEQ(parent_name, vhba_parent)) { - virReportError(VIR_ERR_XML_ERROR, - _("Parent attribute '%s' does not match parent '%s' " - "determined for the '%s' wwnn/wwpn lookup."), - parent_name, vhba_parent, name); - goto cleanup; - } - - retval = true; - - cleanup: - VIR_FREE(vhba_parent); - VIR_FREE(scsi_host_name); - return retval; -} - static int createVport(virConnectPtr conn, virStoragePoolDefPtr def, const char *configFile, virStorageAdapterFCHostPtr fchost) { - unsigned int parent_host; char *name = NULL; - char *parent_hoststr = NULL; - bool skip_capable_check = false; virStoragePoolFCRefreshInfoPtr cbdata = NULL; virThread thread; int ret = -1; @@ -273,66 +227,11 @@ createVport(virConnectPtr conn, conn, NULLSTR(configFile), NULLSTR(fchost->parent), fchost->wwnn, fchost->wwpn); - /* If we find an existing HBA/vHBA within the fc_host sysfs - * using the wwnn/wwpn, then a nodedev is already created for - * this pool and we don't have to create the vHBA - */ - if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { - /* If a parent was provided, let's make sure the 'name' we've - * retrieved has the same parent - */ - if (fchost->parent && checkParent(conn, name, fchost->parent)) - ret = 0; + if (!(name = virNodeDeviceCreateVport(conn, fchost))) goto cleanup; - } - if (fchost->parent) { - if (VIR_STRDUP(parent_hoststr, fchost->parent) < 0) - goto cleanup; - } else if (fchost->parent_wwnn && fchost->parent_wwpn) { - if (!(parent_hoststr = virVHBAGetHostByWWN(NULL, fchost->parent_wwnn, - fchost->parent_wwpn))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("cannot find parent using provided wwnn/wwpn")); - goto cleanup; - } - } else if (fchost->parent_fabric_wwn) { - if (!(parent_hoststr = - virVHBAGetHostByFabricWWN(NULL, fchost->parent_fabric_wwn))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("cannot find parent using provided fabric_wwn")); - goto cleanup; - } - } else { - if (!(parent_hoststr = virVHBAFindVportHost(NULL))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("'parent' for vHBA not specified, and " - "cannot find one on this host")); - goto cleanup; - } - skip_capable_check = true; - } - - if (virSCSIHostGetNumber(parent_hoststr, &parent_host) < 0) - goto cleanup; - - /* NOTE: - * We do not save the parent_hoststr in fchost->parent since - * we could be writing out the 'def' to the saved XML config. - * If we wrote out the name in the XML, then future starts would - * always use the same parent rather than finding the "best available" - * parent. Besides we have a way to determine the parent based on - * the 'name' field. - */ - if (!skip_capable_check && !virVHBAPathExists(NULL, parent_host)) { - virReportError(VIR_ERR_XML_ERROR, - _("parent '%s' specified for vHBA does not exist"), - parent_hoststr); - goto cleanup; - } - - /* Since we're creating the vHBA, then we need to manage removing it + /* Since we've created the vHBA, then we need to manage removing it * as well. Since we need this setting to "live" through a libvirtd * restart, we need to save the persistent configuration. So if not * already defined as YES, then force the issue. @@ -345,28 +244,20 @@ createVport(virConnectPtr conn, } } - if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, - VPORT_CREATE) < 0) - goto cleanup; - - virWaitForDevices(); - /* Creating our own VPORT didn't leave enough time to find any LUN's, * so, let's create a thread whose job it is to call the FindLU's with * retry logic set to true. If the thread isn't created, then no big * deal since it's still possible to refresh the pool later. */ - if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { - if (VIR_ALLOC(cbdata) == 0) { - memcpy(cbdata->pool_uuid, def->uuid, VIR_UUID_BUFLEN); - VIR_STEAL_PTR(cbdata->fchost_name, name); - - if (virThreadCreate(&thread, false, virStoragePoolFCRefreshThread, - cbdata) < 0) { - /* Oh well - at least someone can still refresh afterwards */ - VIR_DEBUG("Failed to create FC Pool Refresh Thread"); - virStoragePoolFCRefreshDataFree(cbdata); - } + if (VIR_ALLOC(cbdata) == 0) { + memcpy(cbdata->pool_uuid, def->uuid, VIR_UUID_BUFLEN); + VIR_STEAL_PTR(cbdata->fchost_name, name); + + if (virThreadCreate(&thread, false, virStoragePoolFCRefreshThread, + cbdata) < 0) { + /* Oh well - at least someone can still refresh afterwards */ + VIR_DEBUG("Failed to create FC Pool Refresh Thread"); + virStoragePoolFCRefreshDataFree(cbdata); } } @@ -374,64 +265,6 @@ createVport(virConnectPtr conn, cleanup: VIR_FREE(name); - VIR_FREE(parent_hoststr); - return ret; -} - - -static int -deleteVport(virConnectPtr conn, - virStorageAdapterFCHostPtr fchost) -{ - unsigned int parent_host; - char *name = NULL; - char *scsi_host_name = NULL; - char *vhba_parent = NULL; - int ret = -1; - - VIR_DEBUG("conn=%p parent='%s', managed='%d' wwnn='%s' wwpn='%s'", - conn, NULLSTR(fchost->parent), fchost->managed, - fchost->wwnn, fchost->wwpn); - - /* If we're not managing the deletion of the vHBA, then just return */ - if (fchost->managed != VIR_TRISTATE_BOOL_YES) - return 0; - - /* Find our vHBA by searching the fc_host sysfs tree for our wwnn/wwpn */ - if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to find fc_host for wwnn='%s' and wwpn='%s'"), - fchost->wwnn, fchost->wwpn); - goto cleanup; - } - - /* If at startup time we provided a parent, then use that to - * get the parent_host value; otherwise, we have to determine - * the parent scsi_host which we did not save at startup time - */ - if (fchost->parent) { - if (virSCSIHostGetNumber(fchost->parent, &parent_host) < 0) - goto cleanup; - } else { - if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) - goto cleanup; - - if (!(vhba_parent = virNodeDeviceGetParentName(conn, scsi_host_name))) - goto cleanup; - - if (virSCSIHostGetNumber(vhba_parent, &parent_host) < 0) - goto cleanup; - } - - if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, - VPORT_DELETE) < 0) - goto cleanup; - - ret = 0; - cleanup: - VIR_FREE(name); - VIR_FREE(vhba_parent); - VIR_FREE(scsi_host_name); return ret; } @@ -525,7 +358,8 @@ virStorageBackendSCSIStopPool(virConnectPtr conn, virStoragePoolObjPtr pool) { if (pool->def->source.adapter.type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) - return deleteVport(conn, &pool->def->source.adapter.data.fchost); + return virNodeDeviceDeleteVport(conn, + &pool->def->source.adapter.data.fchost); return 0; } -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
Move the bulk of the code to the node_device_conf and rename to virNodeDevice{Create|Delete}Vport.
Alter the create algorithm slightly in order to return the name of the scsi_host vHBA that was created. The existing code would fetch the name and if it exists would start a thread looking for the LUNs; however, in no way did it validate the device was created for the storage pool even though it would be used thereafter.
This slight change allows the code that checks if the node device by wwnn/wwpn already exists and return that name. This fixes a second yet seen issue that if the nodedev was present, but the parent by name wasn't provided (perhaps parent by wwnn/wwpn or by fabric_name), then a failure would be returned. For this path it shouldn't be an error - we should just be happy that something else is managing the device and we don't have to create/delete it.
The end result is that the startVport code can now just start the thread once it gets a non NULL name back.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/node_device_conf.c | 211 +++++++++++++++++++++++++++++++++++++ src/conf/node_device_conf.h | 9 ++ src/libvirt_private.syms | 2 + src/storage/storage_backend_scsi.c | 192 +++------------------------------ 4 files changed, 235 insertions(+), 179 deletions(-)
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 3565aec..66cb78d 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -1870,3 +1870,214 @@ virNodeDeviceGetParentName(virConnectPtr conn,
return parent; } + + +/* + * Using the host# name found via wwnn/wwpn lookup in the fc_host + * sysfs tree to get the parent 'scsi_host#' to ensure it matches. + */ +static bool +nodeDeviceCheckParent(virConnectPtr conn, + const char *name, + const char *parent_name) +{ + char *scsi_host_name = NULL; + char *vhba_parent = NULL; + bool retval = false; + + VIR_DEBUG("conn=%p, name=%s, parent_name=%s", conn, name, parent_name); + + /* autostarted pool - assume we're OK */ + if (!conn) + return true; + + if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) + goto cleanup; + + if (!(vhba_parent = virNodeDeviceGetParentName(conn, scsi_host_name))) + goto cleanup; + + if (STRNEQ(parent_name, vhba_parent)) { + virReportError(VIR_ERR_XML_ERROR, + _("Parent attribute '%s' does not match parent '%s' " + "determined for the '%s' wwnn/wwpn lookup."), + parent_name, vhba_parent, name); + goto cleanup; + } + + retval = true; + + cleanup: + VIR_FREE(vhba_parent); + VIR_FREE(scsi_host_name); + return retval; +} + + +/** + * @conn: Connection pointer + * @fchost: Pointer to vHBA adapter + * + * Create a vHBA for Storage. This code accomplishes this via searching + * through the sysfs for scsi_host/fc_host in order to first ensure some + * vHBA doesn't already exist for the requested wwnn/wwpn (e.g. an unmanaged + * vHBA) and to search for the parent vport capable scsi_host by name, + * wwnn/wwpn, or fabric_wwn (if provided). If no parent is provided, then + * a vport capable scsi_host will be selected. + * + * Returns vHBA name on success, NULL on failure with an error message set + */ +char * +virNodeDeviceCreateVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost) +{ + unsigned int parent_host; + char *name = NULL; + char *parent_hoststr = NULL; + bool skip_capable_check = false; + + VIR_DEBUG("conn=%p, parent='%s', wwnn='%s' wwpn='%s'", + conn, NULLSTR(fchost->parent), fchost->wwnn, fchost->wwpn); + + /* If we find an existing HBA/vHBA within the fc_host sysfs + * using the wwnn/wwpn, then a nodedev is already created for + * this pool and we don't have to create the vHBA + */ + if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { + /* If a parent was provided, let's make sure the 'name' we've + * retrieved has the same parent. If not this will cause failure. */ + if (fchost->parent && nodeDeviceCheckParent(conn, name, fchost->parent)) + VIR_FREE(name); + + return name; + } + + if (fchost->parent) { + if (VIR_STRDUP(parent_hoststr, fchost->parent) < 0) + goto cleanup; + } else if (fchost->parent_wwnn && fchost->parent_wwpn) { + if (!(parent_hoststr = virVHBAGetHostByWWN(NULL, fchost->parent_wwnn, + fchost->parent_wwpn))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("cannot find parent using provided wwnn/wwpn")); + goto cleanup; + } + } else if (fchost->parent_fabric_wwn) { + if (!(parent_hoststr = + virVHBAGetHostByFabricWWN(NULL, fchost->parent_fabric_wwn))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("cannot find parent using provided fabric_wwn")); + goto cleanup; + } + } else { + if (!(parent_hoststr = virVHBAFindVportHost(NULL))) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("'parent' for vHBA not specified, and " + "cannot find one on this host")); + goto cleanup; + } + skip_capable_check = true; + } + + if (virSCSIHostGetNumber(parent_hoststr, &parent_host) < 0) + goto cleanup; + + /* NOTE: + * We do not save the parent_hoststr in fchost->parent since + * we could be writing out the 'def' to the saved XML config. + * If we wrote out the name in the XML, then future starts would + * always use the same parent rather than finding the "best available" + * parent. Besides we have a way to determine the parent based on + * the 'name' field. + */ + if (!skip_capable_check && !virVHBAPathExists(NULL, parent_host)) { + virReportError(VIR_ERR_XML_ERROR, + _("parent '%s' specified for vHBA does not exist"), + parent_hoststr); + goto cleanup; + } + + if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, + VPORT_CREATE) < 0) + goto cleanup; + + /* Let's ensure the device was created */ + virWaitForDevices(); + if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { + ignore_value(virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, + VPORT_DELETE)); + goto cleanup; + } + + cleanup: + VIR_FREE(parent_hoststr); + return name; +} + + +/** + * @conn: Connection pointer + * @fchost: Pointer to vHBA adapter + * + * As long as the vHBA is being managed, search for the scsi_host via the + * provided wwnn/wwpn and then find the corresponding parent scsi_host in + * order to send the delete request. + * + * Returns 0 on success, -1 on failure + */ +int +virNodeDeviceDeleteVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost) +{ + char *name = NULL; + char *scsi_host_name = NULL; + unsigned int parent_host; + char *vhba_parent = NULL; + int ret = -1; + + VIR_DEBUG("conn=%p parent='%s', managed='%d' wwnn='%s' wwpn='%s'", + conn, NULLSTR(fchost->parent), fchost->managed, + fchost->wwnn, fchost->wwpn); + + /* If we're not managing the deletion of the vHBA, then just return */ + if (fchost->managed != VIR_TRISTATE_BOOL_YES) + return 0; + + /* Find our vHBA by searching the fc_host sysfs tree for our wwnn/wwpn */ + if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to find fc_host for wwnn='%s' and wwpn='%s'"), + fchost->wwnn, fchost->wwpn); + goto cleanup; + } + + /* If at startup time we provided a parent, then use that to + * get the parent_host value; otherwise, we have to determine + * the parent scsi_host which we did not save at startup time + */ + if (fchost->parent) { + if (virSCSIHostGetNumber(fchost->parent, &parent_host) < 0) + goto cleanup; + } else { + if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) + goto cleanup; + + if (!(vhba_parent = virNodeDeviceGetParentName(conn, scsi_host_name))) + goto cleanup; + + if (virSCSIHostGetNumber(vhba_parent, &parent_host) < 0) + goto cleanup; + } + + if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, + VPORT_DELETE) < 0) + goto cleanup; + + ret = 0; + + cleanup: + VIR_FREE(name); + VIR_FREE(vhba_parent); + VIR_FREE(scsi_host_name); + return ret; +} diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index cf51c69..15e2eac 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -28,8 +28,11 @@ # include "internal.h" # include "virbitmap.h" # include "virutil.h" +# include "virscsihost.h" # include "virpci.h" +# include "virvhba.h" # include "device_conf.h" +# include "storage_adapter_conf.h"
# include <libxml/tree.h>
@@ -354,4 +357,10 @@ char * virNodeDeviceGetParentName(virConnectPtr conn, const char *nodedev_name);
+char *virNodeDeviceCreateVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost); + +int virNodeDeviceDeleteVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost); + #endif /* __VIR_NODE_DEVICE_CONF_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 7bdcde7..cacc7aa 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -686,11 +686,13 @@ virNetDevIPRouteParseXML; virNodeDevCapsDefFree; virNodeDevCapTypeFromString; virNodeDevCapTypeToString; +virNodeDeviceCreateVport; virNodeDeviceDefFormat; virNodeDeviceDefFree; virNodeDeviceDefParseFile; virNodeDeviceDefParseNode; virNodeDeviceDefParseString; +virNodeDeviceDeleteVport; virNodeDeviceGetParentName; virNodeDeviceGetWWNs;
diff --git a/src/storage/storage_backend_scsi.c b/src/storage/storage_backend_scsi.c index abbd38d..666e473 100644 --- a/src/storage/storage_backend_scsi.c +++ b/src/storage/storage_backend_scsi.c @@ -33,9 +33,7 @@ #include "virlog.h" #include "virfile.h" #include "vircommand.h" -#include "virscsihost.h" #include "virstring.h" -#include "virvhba.h" #include "storage_util.h" #include "node_device_conf.h"
@@ -214,57 +212,13 @@ getAdapterName(virStorageAdapterPtr adapter) return name; }
-/* - * Using the host# name found via wwnn/wwpn lookup in the fc_host - * sysfs tree to get the parent 'scsi_host#' to ensure it matches. - */ -static bool -checkParent(virConnectPtr conn, - const char *name, - const char *parent_name) -{ - char *scsi_host_name = NULL; - char *vhba_parent = NULL; - bool retval = false; - - VIR_DEBUG("conn=%p, name=%s, parent_name=%s", conn, name, parent_name); - - /* autostarted pool - assume we're OK */ - if (!conn) - return true; - - if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) - goto cleanup; - - if (!(vhba_parent = virNodeDeviceGetParentName(conn, scsi_host_name))) - goto cleanup; - - if (STRNEQ(parent_name, vhba_parent)) { - virReportError(VIR_ERR_XML_ERROR, - _("Parent attribute '%s' does not match parent '%s' " - "determined for the '%s' wwnn/wwpn lookup."), - parent_name, vhba_parent, name); - goto cleanup; - } - - retval = true; - - cleanup: - VIR_FREE(vhba_parent); - VIR_FREE(scsi_host_name); - return retval; -} - static int createVport(virConnectPtr conn, virStoragePoolDefPtr def, const char *configFile, virStorageAdapterFCHostPtr fchost) { - unsigned int parent_host; char *name = NULL; - char *parent_hoststr = NULL; - bool skip_capable_check = false; virStoragePoolFCRefreshInfoPtr cbdata = NULL; virThread thread; int ret = -1; @@ -273,66 +227,11 @@ createVport(virConnectPtr conn, conn, NULLSTR(configFile), NULLSTR(fchost->parent), fchost->wwnn, fchost->wwpn);
- /* If we find an existing HBA/vHBA within the fc_host sysfs - * using the wwnn/wwpn, then a nodedev is already created for - * this pool and we don't have to create the vHBA - */ - if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { - /* If a parent was provided, let's make sure the 'name' we've - * retrieved has the same parent - */ - if (fchost->parent && checkParent(conn, name, fchost->parent)) - ret = 0;
+ if (!(name = virNodeDeviceCreateVport(conn, fchost))) goto cleanup; - }
- if (fchost->parent) { - if (VIR_STRDUP(parent_hoststr, fchost->parent) < 0) - goto cleanup; - } else if (fchost->parent_wwnn && fchost->parent_wwpn) { - if (!(parent_hoststr = virVHBAGetHostByWWN(NULL, fchost->parent_wwnn, - fchost->parent_wwpn))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("cannot find parent using provided wwnn/wwpn")); - goto cleanup; - } - } else if (fchost->parent_fabric_wwn) { - if (!(parent_hoststr = - virVHBAGetHostByFabricWWN(NULL, fchost->parent_fabric_wwn))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("cannot find parent using provided fabric_wwn")); - goto cleanup; - } - } else { - if (!(parent_hoststr = virVHBAFindVportHost(NULL))) { - virReportError(VIR_ERR_XML_ERROR, "%s", - _("'parent' for vHBA not specified, and " - "cannot find one on this host")); - goto cleanup; - } - skip_capable_check = true; - } - - if (virSCSIHostGetNumber(parent_hoststr, &parent_host) < 0) - goto cleanup; - - /* NOTE: - * We do not save the parent_hoststr in fchost->parent since - * we could be writing out the 'def' to the saved XML config. - * If we wrote out the name in the XML, then future starts would - * always use the same parent rather than finding the "best available" - * parent. Besides we have a way to determine the parent based on - * the 'name' field. - */ - if (!skip_capable_check && !virVHBAPathExists(NULL, parent_host)) { - virReportError(VIR_ERR_XML_ERROR, - _("parent '%s' specified for vHBA does not exist"), - parent_hoststr); - goto cleanup; - } - - /* Since we're creating the vHBA, then we need to manage removing it + /* Since we've created the vHBA, then we need to manage removing it * as well. Since we need this setting to "live" through a libvirtd * restart, we need to save the persistent configuration. So if not * already defined as YES, then force the issue. @@ -345,28 +244,20 @@ createVport(virConnectPtr conn,
Right in this space the old code would set managed = YES and call virStoragePoolSaveConfig(). That is now done *after calling virVHBAManageVport() (whatever *that* does) and a few other things from post-saveconfig that have been moed into virNodeDeviceCreateVport(). I just want a confirmation that this change in ordering won't cause a problem...
} }
- if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, - VPORT_CREATE) < 0) - goto cleanup; - - virWaitForDevices(); - /* Creating our own VPORT didn't leave enough time to find any LUN's, * so, let's create a thread whose job it is to call the FindLU's with * retry logic set to true. If the thread isn't created, then no big * deal since it's still possible to refresh the pool later. */ - if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { - if (VIR_ALLOC(cbdata) == 0) { - memcpy(cbdata->pool_uuid, def->uuid, VIR_UUID_BUFLEN); - VIR_STEAL_PTR(cbdata->fchost_name, name); - - if (virThreadCreate(&thread, false, virStoragePoolFCRefreshThread, - cbdata) < 0) { - /* Oh well - at least someone can still refresh afterwards */ - VIR_DEBUG("Failed to create FC Pool Refresh Thread"); - virStoragePoolFCRefreshDataFree(cbdata); - }
Okay, since a failure of virVHBAGetHostByWWN() in virNodeDeviceCreateVport() would have resulted in an early return, it's okay to move all of this outside the conditional (which no longer exists!) Everything looks like a simple hatchet and stitch job to me - ACK.
+ if (VIR_ALLOC(cbdata) == 0) { + memcpy(cbdata->pool_uuid, def->uuid, VIR_UUID_BUFLEN); + VIR_STEAL_PTR(cbdata->fchost_name, name); + + if (virThreadCreate(&thread, false, virStoragePoolFCRefreshThread, + cbdata) < 0) { + /* Oh well - at least someone can still refresh afterwards */ + VIR_DEBUG("Failed to create FC Pool Refresh Thread"); + virStoragePoolFCRefreshDataFree(cbdata); } }
@@ -374,64 +265,6 @@ createVport(virConnectPtr conn,
cleanup: VIR_FREE(name); - VIR_FREE(parent_hoststr); - return ret; -} - - -static int -deleteVport(virConnectPtr conn, - virStorageAdapterFCHostPtr fchost) -{ - unsigned int parent_host; - char *name = NULL; - char *scsi_host_name = NULL; - char *vhba_parent = NULL; - int ret = -1; - - VIR_DEBUG("conn=%p parent='%s', managed='%d' wwnn='%s' wwpn='%s'", - conn, NULLSTR(fchost->parent), fchost->managed, - fchost->wwnn, fchost->wwpn); - - /* If we're not managing the deletion of the vHBA, then just return */ - if (fchost->managed != VIR_TRISTATE_BOOL_YES) - return 0; - - /* Find our vHBA by searching the fc_host sysfs tree for our wwnn/wwpn */ - if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Failed to find fc_host for wwnn='%s' and wwpn='%s'"), - fchost->wwnn, fchost->wwpn); - goto cleanup; - } - - /* If at startup time we provided a parent, then use that to - * get the parent_host value; otherwise, we have to determine - * the parent scsi_host which we did not save at startup time - */ - if (fchost->parent) { - if (virSCSIHostGetNumber(fchost->parent, &parent_host) < 0) - goto cleanup; - } else { - if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0) - goto cleanup; - - if (!(vhba_parent = virNodeDeviceGetParentName(conn, scsi_host_name))) - goto cleanup; - - if (virSCSIHostGetNumber(vhba_parent, &parent_host) < 0) - goto cleanup; - } - - if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, - VPORT_DELETE) < 0) - goto cleanup; - - ret = 0; - cleanup: - VIR_FREE(name); - VIR_FREE(vhba_parent); - VIR_FREE(scsi_host_name); return ret; }
@@ -525,7 +358,8 @@ virStorageBackendSCSIStopPool(virConnectPtr conn, virStoragePoolObjPtr pool) { if (pool->def->source.adapter.type == VIR_STORAGE_ADAPTER_TYPE_FC_HOST) - return deleteVport(conn, &pool->def->source.adapter.data.fchost); + return virNodeDeviceDeleteVport(conn, + &pool->def->source.adapter.data.fchost);
return 0; }

On 03/12/2017 06:35 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
Move the bulk of the code to the node_device_conf and rename to virNodeDevice{Create|Delete}Vport.
Alter the create algorithm slightly in order to return the name of the scsi_host vHBA that was created. The existing code would fetch the name and if it exists would start a thread looking for the LUNs; however, in no way did it validate the device was created for the storage pool even though it would be used thereafter.
This slight change allows the code that checks if the node device by wwnn/wwpn already exists and return that name. This fixes a second yet seen issue that if the nodedev was present, but the parent by name wasn't provided (perhaps parent by wwnn/wwpn or by fabric_name), then a failure would be returned. For this path it shouldn't be an error - we should just be happy that something else is managing the device and we don't have to create/delete it.
The end result is that the startVport code can now just start the thread once it gets a non NULL name back.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/node_device_conf.c | 211 +++++++++++++++++++++++++++++++++++++ src/conf/node_device_conf.h | 9 ++ src/libvirt_private.syms | 2 + src/storage/storage_backend_scsi.c | 192 +++------------------------------ 4 files changed, 235 insertions(+), 179 deletions(-)
[...]
- - /* Since we're creating the vHBA, then we need to manage removing it + /* Since we've created the vHBA, then we need to manage removing it * as well. Since we need this setting to "live" through a libvirtd * restart, we need to save the persistent configuration. So if not * already defined as YES, then force the issue. @@ -345,28 +244,20 @@ createVport(virConnectPtr conn,
Right in this space the old code would set managed = YES and call virStoragePoolSaveConfig(). That is now done *after calling virVHBAManageVport() (whatever *that* does) and a few other things from post-saveconfig that have been moed into virNodeDeviceCreateVport(). I just want a confirmation that this change in ordering won't cause a problem...
Right it was intentional and (famous last words) I don't think there's going to be a problem in the change of ordering... One of the things virNodeDeviceCreateVport now does is ensure that the vHBA was created (whether via using virNodeDeviceCreateXML success or after the virVHBAManageVport(CREATE) ensuring that the new scsi_hostN by FCHost wwnn/wwpn can be found and if not, attempt a DELETE. If you consider the "current" code - it would save the XML, then attempt the CREATE, but not reset the config file if that failed. I suppose I could have split across multiple patches too. Of course that's why my commit message is extra wordy ;-)
} }
- if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, - VPORT_CREATE) < 0) - goto cleanup; - - virWaitForDevices(); - /* Creating our own VPORT didn't leave enough time to find any LUN's, * so, let's create a thread whose job it is to call the FindLU's with * retry logic set to true. If the thread isn't created, then no big * deal since it's still possible to refresh the pool later. */ - if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { - if (VIR_ALLOC(cbdata) == 0) { - memcpy(cbdata->pool_uuid, def->uuid, VIR_UUID_BUFLEN); - VIR_STEAL_PTR(cbdata->fchost_name, name); - - if (virThreadCreate(&thread, false, virStoragePoolFCRefreshThread, - cbdata) < 0) { - /* Oh well - at least someone can still refresh afterwards */ - VIR_DEBUG("Failed to create FC Pool Refresh Thread"); - virStoragePoolFCRefreshDataFree(cbdata); - }
Okay, since a failure of virVHBAGetHostByWWN() in virNodeDeviceCreateVport() would have resulted in an early return, it's okay to move all of this outside the conditional (which no longer exists!)
Right - although if desired I can split this patch up into (at least) two to make it more obvious. Tks - John
Everything looks like a simple hatchet and stitch job to me - ACK.
[...]

On 03/15/2017 10:08 AM, John Ferlan wrote:
On 03/12/2017 06:35 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
Move the bulk of the code to the node_device_conf and rename to virNodeDevice{Create|Delete}Vport.
Alter the create algorithm slightly in order to return the name of the scsi_host vHBA that was created. The existing code would fetch the name and if it exists would start a thread looking for the LUNs; however, in no way did it validate the device was created for the storage pool even though it would be used thereafter.
This slight change allows the code that checks if the node device by wwnn/wwpn already exists and return that name. This fixes a second yet seen issue that if the nodedev was present, but the parent by name wasn't provided (perhaps parent by wwnn/wwpn or by fabric_name), then a failure would be returned. For this path it shouldn't be an error - we should just be happy that something else is managing the device and we don't have to create/delete it.
The end result is that the startVport code can now just start the thread once it gets a non NULL name back.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/node_device_conf.c | 211 +++++++++++++++++++++++++++++++++++++ src/conf/node_device_conf.h | 9 ++ src/libvirt_private.syms | 2 + src/storage/storage_backend_scsi.c | 192 +++------------------------------ 4 files changed, 235 insertions(+), 179 deletions(-)
[...]
- - /* Since we're creating the vHBA, then we need to manage removing it + /* Since we've created the vHBA, then we need to manage removing it * as well. Since we need this setting to "live" through a libvirtd * restart, we need to save the persistent configuration. So if not * already defined as YES, then force the issue. @@ -345,28 +244,20 @@ createVport(virConnectPtr conn,
Right in this space the old code would set managed = YES and call virStoragePoolSaveConfig(). That is now done *after calling virVHBAManageVport() (whatever *that* does) and a few other things from post-saveconfig that have been moed into virNodeDeviceCreateVport(). I just want a confirmation that this change in ordering won't cause a problem...
Right it was intentional and (famous last words) I don't think there's going to be a problem in the change of ordering...
One of the things virNodeDeviceCreateVport now does is ensure that the vHBA was created (whether via using virNodeDeviceCreateXML success or after the virVHBAManageVport(CREATE) ensuring that the new scsi_hostN by FCHost wwnn/wwpn can be found and if not, attempt a DELETE.
If you consider the "current" code - it would save the XML, then attempt the CREATE, but not reset the config file if that failed. I suppose I could have split across multiple patches too. Of course that's why my commit message is extra wordy ;-)
} }
- if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, - VPORT_CREATE) < 0) - goto cleanup; - - virWaitForDevices(); - /* Creating our own VPORT didn't leave enough time to find any LUN's, * so, let's create a thread whose job it is to call the FindLU's with * retry logic set to true. If the thread isn't created, then no big * deal since it's still possible to refresh the pool later. */ - if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { - if (VIR_ALLOC(cbdata) == 0) { - memcpy(cbdata->pool_uuid, def->uuid, VIR_UUID_BUFLEN); - VIR_STEAL_PTR(cbdata->fchost_name, name); - - if (virThreadCreate(&thread, false, virStoragePoolFCRefreshThread, - cbdata) < 0) { - /* Oh well - at least someone can still refresh afterwards */ - VIR_DEBUG("Failed to create FC Pool Refresh Thread"); - virStoragePoolFCRefreshDataFree(cbdata); - }
Okay, since a failure of virVHBAGetHostByWWN() in virNodeDeviceCreateVport() would have resulted in an early return, it's okay to move all of this outside the conditional (which no longer exists!)
Right - although if desired I can split this patch up into (at least) two to make it more obvious.
Nope. It was all decipherable as it is. Of course if you're looking to get your patch count up, then...
Tks -
John
Everything looks like a simple hatchet and stitch job to me - ACK.
[...]

On 03/15/2017 11:19 AM, Laine Stump wrote:
On 03/15/2017 10:08 AM, John Ferlan wrote:
On 03/12/2017 06:35 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
Move the bulk of the code to the node_device_conf and rename to virNodeDevice{Create|Delete}Vport.
Alter the create algorithm slightly in order to return the name of the scsi_host vHBA that was created. The existing code would fetch the name and if it exists would start a thread looking for the LUNs; however, in no way did it validate the device was created for the storage pool even though it would be used thereafter.
This slight change allows the code that checks if the node device by wwnn/wwpn already exists and return that name. This fixes a second yet seen issue that if the nodedev was present, but the parent by name wasn't provided (perhaps parent by wwnn/wwpn or by fabric_name), then a failure would be returned. For this path it shouldn't be an error - we should just be happy that something else is managing the device and we don't have to create/delete it.
The end result is that the startVport code can now just start the thread once it gets a non NULL name back.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/node_device_conf.c | 211 +++++++++++++++++++++++++++++++++++++ src/conf/node_device_conf.h | 9 ++ src/libvirt_private.syms | 2 + src/storage/storage_backend_scsi.c | 192 +++------------------------------ 4 files changed, 235 insertions(+), 179 deletions(-)
[...]
- - /* Since we're creating the vHBA, then we need to manage removing it + /* Since we've created the vHBA, then we need to manage removing it * as well. Since we need this setting to "live" through a libvirtd * restart, we need to save the persistent configuration. So if not * already defined as YES, then force the issue. @@ -345,28 +244,20 @@ createVport(virConnectPtr conn,
Right in this space the old code would set managed = YES and call virStoragePoolSaveConfig(). That is now done *after calling virVHBAManageVport() (whatever *that* does) and a few other things from post-saveconfig that have been moed into virNodeDeviceCreateVport(). I just want a confirmation that this change in ordering won't cause a problem...
Right it was intentional and (famous last words) I don't think there's going to be a problem in the change of ordering...
One of the things virNodeDeviceCreateVport now does is ensure that the vHBA was created (whether via using virNodeDeviceCreateXML success or after the virVHBAManageVport(CREATE) ensuring that the new scsi_hostN by FCHost wwnn/wwpn can be found and if not, attempt a DELETE.
If you consider the "current" code - it would save the XML, then attempt the CREATE, but not reset the config file if that failed. I suppose I could have split across multiple patches too. Of course that's why my commit message is extra wordy ;-)
Upon further reflection - I've flip-flopped - I'll do the save first and then the create. Not sure I can remember or even recreate why the order is as it is, so let's not mess with (ahem) success...
} }
- if (virVHBAManageVport(parent_host, fchost->wwpn, fchost->wwnn, - VPORT_CREATE) < 0) - goto cleanup; - - virWaitForDevices(); - /* Creating our own VPORT didn't leave enough time to find any LUN's, * so, let's create a thread whose job it is to call the FindLU's with * retry logic set to true. If the thread isn't created, then no big * deal since it's still possible to refresh the pool later. */ - if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { - if (VIR_ALLOC(cbdata) == 0) { - memcpy(cbdata->pool_uuid, def->uuid, VIR_UUID_BUFLEN); - VIR_STEAL_PTR(cbdata->fchost_name, name); - - if (virThreadCreate(&thread, false, virStoragePoolFCRefreshThread, - cbdata) < 0) { - /* Oh well - at least someone can still refresh afterwards */ - VIR_DEBUG("Failed to create FC Pool Refresh Thread"); - virStoragePoolFCRefreshDataFree(cbdata); - }
Okay, since a failure of virVHBAGetHostByWWN() in virNodeDeviceCreateVport() would have resulted in an early return, it's okay to move all of this outside the conditional (which no longer exists!)
Right - although if desired I can split this patch up into (at least) two to make it more obvious.
Nope. It was all decipherable as it is. Of course if you're looking to get your patch count up, then...
Nah - I was originally hoping for the leap of faith by just having 1 patch which is now 12 and could have been more. Still in order to be true to having one patch be purely code motion - I did insert a patch which just moves the createVport/deleteVport and renames it. Then the followup patch will do the ensure the device was created logic. So patches up through here have been ACK'd and I'll separate out and push later on today... Then I'll rework the rest of the patches. John

If we have a connection pointer there's no sense walking through the sysfs in order to create/destroy the vHBA. Instead, let's make use of the node device create/destroy API's. Since we don't have to rewrite all the various parent options for the test driver in order to test whether the storage pool creation works as the node device creation has been tested already, let's just use the altered API to test the storage pool paths. Fix a "bug" in the storage pool test driver code which "assumed" testStoragePoolObjSetDefaults should fill in the configFile for both the Define/Create (persistent) and CreateXML (transient) pools by just VIR_FREE() of the pool during CreateXML. Because the configFile was filled in, during Destroy, the pool wouldn't be free causing a test using the same name pool to fail. Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/node_device_conf.c | 121 ++++++++++++++++++++++++++++++++++++++++++++ src/test/test_driver.c | 6 +++ tests/fchosttest.c | 15 ++++++ 3 files changed, 142 insertions(+) diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 66cb78d..0c25f58 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -1916,6 +1916,82 @@ nodeDeviceCheckParent(virConnectPtr conn, /** * @conn: Connection pointer + * @fchost: Pointer to the vHBA adapter + * + * If we have a valid connection, then use the node device create + * XML API rather than traversing through the sysfs to create the vHBA. + * Generate the Node Device XML using the Storage vHBA Adapter providing + * either the parent name, parent wwnn/wwpn, or parent fabric_name if + * available to the Node Device code. Since the Storage XML processing + * requires the wwnn/wwpn to be used for the vHBA to be provided (and + * not generated), we can use that as the fc_host wwnn/wwpn. This will + * allow for easier search later when we need it. + * + * Returns vHBA name on success, NULL on failure with an error message set + */ +static char * +nodeDeviceCreateNodeDeviceVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *vhbaStr = NULL; + virNodeDevicePtr dev = NULL; + char *name; + bool created = false; + + /* If the nodedev already knows about this vHBA, then we're not + * managing it - we'll just use it. */ + if ((dev = virNodeDeviceLookupSCSIHostByWWN(conn, fchost->wwnn, + fchost->wwpn, 0))) + goto skip_create; + + virBufferAddLit(&buf, "<device>\n"); + virBufferAdjustIndent(&buf, 2); + if (fchost->parent) + virBufferEscapeString(&buf, "<parent>%s</parent>\n", + fchost->parent); + else if (fchost->parent_wwnn && fchost->parent_wwpn) + virBufferAsprintf(&buf, "<parent wwnn='%s' wwpn='%s'/>\n", + fchost->parent_wwnn, fchost->parent_wwpn); + else if (fchost->parent_fabric_wwn) + virBufferAsprintf(&buf, "<parent fabric_wnn='%s'/>\n", + fchost->parent_fabric_wwn); + virBufferAddLit(&buf, "<capability type='scsi_host'>\n"); + virBufferAdjustIndent(&buf, 2); + virBufferAsprintf(&buf, "<capability type='fc_host' wwnn='%s' wwpn='%s'>\n", + fchost->wwnn, fchost->wwpn); + virBufferAddLit(&buf, "</capability>\n"); + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "</capability>\n"); + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "</device>\n"); + + if (!(vhbaStr = virBufferContentAndReset(&buf))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("unable to create node device XML")); + goto cleanup; + } + + if (!(dev = virNodeDeviceCreateXML(conn, vhbaStr, 0))) + goto cleanup; + created = true; + + skip_create: + if (VIR_STRDUP(name, virNodeDeviceGetName(dev)) < 0) { + /* If we created, then destroy it */ + if (created) + ignore_value(virNodeDeviceDestroy(dev)); + } + + cleanup: + VIR_FREE(vhbaStr); + virObjectUnref(dev); + return name; +} + + +/** + * @conn: Connection pointer * @fchost: Pointer to vHBA adapter * * Create a vHBA for Storage. This code accomplishes this via searching @@ -1939,6 +2015,11 @@ virNodeDeviceCreateVport(virConnectPtr conn, VIR_DEBUG("conn=%p, parent='%s', wwnn='%s' wwpn='%s'", conn, NULLSTR(fchost->parent), fchost->wwnn, fchost->wwpn); + /* If we have a connection, bypass sysfs searching and use the + * NodeDevice API's in order to perform our delete */ + if (conn) + return nodeDeviceCreateNodeDeviceVport(conn, fchost); + /* If we find an existing HBA/vHBA within the fc_host sysfs * using the wwnn/wwpn, then a nodedev is already created for * this pool and we don't have to create the vHBA @@ -2019,6 +2100,41 @@ virNodeDeviceCreateVport(virConnectPtr conn, * @conn: Connection pointer * @fchost: Pointer to vHBA adapter * + * Search for the vHBA SCSI_HOST by the wwnn/wwpn provided at creation + * and use the node device driver to destroy. + * + * Returns 0 on success, -1 on failure w/ error message. + */ +static int +nodeDeviceDeleteNodeDeviceVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost) +{ + int ret = -1; + virNodeDevicePtr dev; + + if (!(dev = virNodeDeviceLookupSCSIHostByWWN(conn, fchost->wwnn, + fchost->wwpn, 0))) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Failed to find fc_host for wwnn='%s' and wwpn='%s'"), + fchost->wwnn, fchost->wwpn); + return -1; + } + + if (virNodeDeviceDestroy(dev) < 0) + goto cleanup; + + ret = 0; + + cleanup: + virObjectUnref(dev); + return ret; +} + + +/** + * @conn: Connection pointer + * @fchost: Pointer to vHBA adapter + * * As long as the vHBA is being managed, search for the scsi_host via the * provided wwnn/wwpn and then find the corresponding parent scsi_host in * order to send the delete request. @@ -2043,6 +2159,11 @@ virNodeDeviceDeleteVport(virConnectPtr conn, if (fchost->managed != VIR_TRISTATE_BOOL_YES) return 0; + /* If we have a connection, bypass sysfs searching and use the + * NodeDevice API's in order to perform our delete */ + if (conn) + return nodeDeviceDeleteNodeDeviceVport(conn, fchost); + /* Find our vHBA by searching the fc_host sysfs tree for our wwnn/wwpn */ if (!(name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) { virReportError(VIR_ERR_INTERNAL_ERROR, diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 18792bc..1023956 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -4439,6 +4439,12 @@ testStoragePoolCreateXML(virConnectPtr conn, pool = NULL; goto cleanup; } + + /* *SetDefaults fills this in for the persistent pools, but this + * would be a transient pool so remove it; otherwise, the Destroy + * code will not Remove the pool */ + VIR_FREE(pool->configFile); + pool->active = 1; event = virStoragePoolEventLifecycleNew(pool->def->name, pool->def->uuid, diff --git a/tests/fchosttest.c b/tests/fchosttest.c index dc6b9af..c024ae5 100644 --- a/tests/fchosttest.c +++ b/tests/fchosttest.c @@ -87,6 +87,18 @@ static const char test11_xml[] = " </target>" "</pool>"; +/* virStoragePoolCreateXML without any parent to find the vport capable HBA */ +static const char test12_xml[] = +"<pool type='scsi'>" +" <name>vhba_pool</name>" +" <source>" +" <adapter type='fc_host' wwnn='20000000c9831b4b' wwpn='10000000c9831b4b'/>" +" </source>" +" <target>" +" <path>/dev/disk/by-path</path>" +" </target>" +"</pool>"; + /* Test virIsVHBACapable */ static int @@ -374,6 +386,9 @@ mymain(void) if (virTestRun("manageVHBAByStoragePool-by-parent", manageVHBAByStoragePool, test11_xml) < 0) ret = -1; + if (virTestRun("manageVHBAByStoragePool-no-parent", manageVHBAByStoragePool, + test12_xml) < 0) + ret = -1; cleanup: VIR_FREE(fchost_prefix); -- 2.9.3

On 03/10/2017 04:10 PM, John Ferlan wrote:
If we have a connection pointer there's no sense walking through the sysfs in order to create/destroy the vHBA. Instead, let's make use of the node device create/destroy API's.
Since we don't have to rewrite all the various parent options for the test driver in order to test whether the storage pool creation works as the node device creation has been tested already, let's just use the altered API to test the storage pool paths.
Fix a "bug" in the storage pool test driver code which "assumed" testStoragePoolObjSetDefaults should fill in the configFile for both the Define/Create (persistent) and CreateXML (transient) pools by just VIR_FREE() of the pool during CreateXML. Because the configFile was filled in, during Destroy, the pool wouldn't be free causing a test using the same name pool to fail.
Without trying to go through this patch, the commit log makes it sound like there are 3 separate things being done. Or am I misinterpreting? Can it maybe be split up so a mindless reviewer doesn't need to do any work to figure out which is the code fixing the bug. If no splitting is possible/useful, then I'll tackle it as-is tomorrow.

On 03/12/2017 09:20 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
If we have a connection pointer there's no sense walking through the sysfs in order to create/destroy the vHBA. Instead, let's make use of the node device create/destroy API's.
Since we don't have to rewrite all the various parent options for the test driver in order to test whether the storage pool creation works as the node device creation has been tested already, let's just use the altered API to test the storage pool paths.
Fix a "bug" in the storage pool test driver code which "assumed" testStoragePoolObjSetDefaults should fill in the configFile for both the Define/Create (persistent) and CreateXML (transient) pools by just VIR_FREE() of the pool during CreateXML. Because the configFile was filled in, during Destroy, the pool wouldn't be free causing a test using the same name pool to fail.
Without trying to go through this patch, the commit log makes it sound like there are 3 separate things being done. Or am I misinterpreting? Can it maybe be split up so a mindless reviewer doesn't need to do any work to figure out which is the code fixing the bug. If no splitting is possible/useful, then I'll tackle it as-is tomorrow.
What's happening here is using the NodeDevice API's in order to create the vHBA instead of essentially repeating what the nodedev API does for create. In working through the code I discovered the test_driver pool->configFile "bug" and it seems "over described" it... I can separate that. The primary reason for doing this is I didn't want to rewrite all the parent* options in the test driver in order to test the storage pool XML options. By using the node device create - I get that for free! I also figured it'd be "quicker" and more reliable to use what nodedev driver has 'in memory' rather than walking through the file system that theoretically udev has already done for us and nodedev has saved away. I could really take the hard road and create an API that would handle all those parent* options and do the right thing. That would mean both nodedevice and storage pool would call that. John

On 03/15/2017 10:22 AM, John Ferlan wrote:
On 03/12/2017 09:20 PM, Laine Stump wrote:
On 03/10/2017 04:10 PM, John Ferlan wrote:
If we have a connection pointer there's no sense walking through the sysfs in order to create/destroy the vHBA. Instead, let's make use of the node device create/destroy API's.
Since we don't have to rewrite all the various parent options for the test driver in order to test whether the storage pool creation works as the node device creation has been tested already, let's just use the altered API to test the storage pool paths.
Fix a "bug" in the storage pool test driver code which "assumed" testStoragePoolObjSetDefaults should fill in the configFile for both the Define/Create (persistent) and CreateXML (transient) pools by just VIR_FREE() of the pool during CreateXML. Because the configFile was filled in, during Destroy, the pool wouldn't be free causing a test using the same name pool to fail.
Without trying to go through this patch, the commit log makes it sound like there are 3 separate things being done. Or am I misinterpreting? Can it maybe be split up so a mindless reviewer doesn't need to do any work to figure out which is the code fixing the bug. If no splitting is possible/useful, then I'll tackle it as-is tomorrow.
What's happening here is using the NodeDevice API's in order to create the vHBA instead of essentially repeating what the nodedev API does for create.
In working through the code I discovered the test_driver pool->configFile "bug" and it seems "over described" it... I can separate that.
The primary reason for doing this is I didn't want to rewrite all the parent* options in the test driver in order to test the storage pool XML options. By using the node device create - I get that for free!
I also figured it'd be "quicker" and more reliable to use what nodedev driver has 'in memory' rather than walking through the file system that theoretically udev has already done for us and nodedev has saved away.
I could really take the hard road and create an API that would handle all those parent* options and do the right thing. That would mean both nodedevice and storage pool would call that.
This ^. (or something similar). As Dan just pointed out with some concrete reasons (and I also said in a previous review, but without providing the good reasons like Dan did) calling a libvirt public API from within libvirt may be tempting but not a good idea.

On Fri, Mar 10, 2017 at 04:10:49PM -0500, John Ferlan wrote:
If we have a connection pointer there's no sense walking through the sysfs in order to create/destroy the vHBA. Instead, let's make use of the node device create/destroy API's.
In general we should *not* call out to the public API entry points, from inside libvirt code. Instead we should have an internal only function that is called from both the public API entry point, and from whatever other context needs the same functionality. Calling the public API entry points directly imposes access control checks on the internal code which is not good. Also if public APIs are triggered in clean up code paths, then it'll blow away any reported error.
Since we don't have to rewrite all the various parent options for the test driver in order to test whether the storage pool creation works as the node device creation has been tested already, let's just use the altered API to test the storage pool paths.
Fix a "bug" in the storage pool test driver code which "assumed" testStoragePoolObjSetDefaults should fill in the configFile for both the Define/Create (persistent) and CreateXML (transient) pools by just VIR_FREE() of the pool during CreateXML. Because the configFile was filled in, during Destroy, the pool wouldn't be free causing a test using the same name pool to fail.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/node_device_conf.c | 121 ++++++++++++++++++++++++++++++++++++++++++++ src/test/test_driver.c | 6 +++ tests/fchosttest.c | 15 ++++++ 3 files changed, 142 insertions(+)
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 66cb78d..0c25f58 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -1916,6 +1916,82 @@ nodeDeviceCheckParent(virConnectPtr conn,
/** * @conn: Connection pointer + * @fchost: Pointer to the vHBA adapter + * + * If we have a valid connection, then use the node device create + * XML API rather than traversing through the sysfs to create the vHBA. + * Generate the Node Device XML using the Storage vHBA Adapter providing + * either the parent name, parent wwnn/wwpn, or parent fabric_name if + * available to the Node Device code. Since the Storage XML processing + * requires the wwnn/wwpn to be used for the vHBA to be provided (and + * not generated), we can use that as the fc_host wwnn/wwpn. This will + * allow for easier search later when we need it. + * + * Returns vHBA name on success, NULL on failure with an error message set + */ +static char * +nodeDeviceCreateNodeDeviceVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *vhbaStr = NULL; + virNodeDevicePtr dev = NULL; + char *name; + bool created = false; + + /* If the nodedev already knows about this vHBA, then we're not + * managing it - we'll just use it. */ + if ((dev = virNodeDeviceLookupSCSIHostByWWN(conn, fchost->wwnn, + fchost->wwpn, 0))) + goto skip_create; + + virBufferAddLit(&buf, "<device>\n"); + virBufferAdjustIndent(&buf, 2); + if (fchost->parent) + virBufferEscapeString(&buf, "<parent>%s</parent>\n", + fchost->parent); + else if (fchost->parent_wwnn && fchost->parent_wwpn) + virBufferAsprintf(&buf, "<parent wwnn='%s' wwpn='%s'/>\n", + fchost->parent_wwnn, fchost->parent_wwpn); + else if (fchost->parent_fabric_wwn) + virBufferAsprintf(&buf, "<parent fabric_wnn='%s'/>\n", + fchost->parent_fabric_wwn); + virBufferAddLit(&buf, "<capability type='scsi_host'>\n"); + virBufferAdjustIndent(&buf, 2); + virBufferAsprintf(&buf, "<capability type='fc_host' wwnn='%s' wwpn='%s'>\n", + fchost->wwnn, fchost->wwpn); + virBufferAddLit(&buf, "</capability>\n"); + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "</capability>\n"); + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "</device>\n");
We really shouldn't be generating XML internally just to immediately give back to ourselves. We should populate the appropriate internal config data struct instead and avoid XML entirely.
+ + if (!(vhbaStr = virBufferContentAndReset(&buf))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("unable to create node device XML")); + goto cleanup; + } + + if (!(dev = virNodeDeviceCreateXML(conn, vhbaStr, 0))) + goto cleanup; + created = true; + + skip_create: + if (VIR_STRDUP(name, virNodeDeviceGetName(dev)) < 0) { + /* If we created, then destroy it */ + if (created) + ignore_value(virNodeDeviceDestroy(dev)); + } + + cleanup: + VIR_FREE(vhbaStr); + virObjectUnref(dev); + return name; +} +
Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|

On 03/15/2017 10:46 AM, Daniel P. Berrange wrote:
On Fri, Mar 10, 2017 at 04:10:49PM -0500, John Ferlan wrote:
If we have a connection pointer there's no sense walking through the sysfs in order to create/destroy the vHBA. Instead, let's make use of the node device create/destroy API's.
In general we should *not* call out to the public API entry points, from inside libvirt code. Instead we should have an internal only function that is called from both the public API entry point, and from whatever other context needs the same functionality.
Calling the public API entry points directly imposes access control checks on the internal code which is not good. Also if public APIs are triggered in clean up code paths, then it'll blow away any reported error.
OK - so I'll take a different tack with this...
Since we don't have to rewrite all the various parent options for the test driver in order to test whether the storage pool creation works as the node device creation has been tested already, let's just use the altered API to test the storage pool paths.
Fix a "bug" in the storage pool test driver code which "assumed" testStoragePoolObjSetDefaults should fill in the configFile for both the Define/Create (persistent) and CreateXML (transient) pools by just VIR_FREE() of the pool during CreateXML. Because the configFile was filled in, during Destroy, the pool wouldn't be free causing a test using the same name pool to fail.
Signed-off-by: John Ferlan <jferlan@redhat.com> --- src/conf/node_device_conf.c | 121 ++++++++++++++++++++++++++++++++++++++++++++ src/test/test_driver.c | 6 +++ tests/fchosttest.c | 15 ++++++ 3 files changed, 142 insertions(+)
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index 66cb78d..0c25f58 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -1916,6 +1916,82 @@ nodeDeviceCheckParent(virConnectPtr conn,
/** * @conn: Connection pointer + * @fchost: Pointer to the vHBA adapter + * + * If we have a valid connection, then use the node device create + * XML API rather than traversing through the sysfs to create the vHBA. + * Generate the Node Device XML using the Storage vHBA Adapter providing + * either the parent name, parent wwnn/wwpn, or parent fabric_name if + * available to the Node Device code. Since the Storage XML processing + * requires the wwnn/wwpn to be used for the vHBA to be provided (and + * not generated), we can use that as the fc_host wwnn/wwpn. This will + * allow for easier search later when we need it. + * + * Returns vHBA name on success, NULL on failure with an error message set + */ +static char * +nodeDeviceCreateNodeDeviceVport(virConnectPtr conn, + virStorageAdapterFCHostPtr fchost) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *vhbaStr = NULL; + virNodeDevicePtr dev = NULL; + char *name; + bool created = false; + + /* If the nodedev already knows about this vHBA, then we're not + * managing it - we'll just use it. */ + if ((dev = virNodeDeviceLookupSCSIHostByWWN(conn, fchost->wwnn, + fchost->wwpn, 0))) + goto skip_create; + + virBufferAddLit(&buf, "<device>\n"); + virBufferAdjustIndent(&buf, 2); + if (fchost->parent) + virBufferEscapeString(&buf, "<parent>%s</parent>\n", + fchost->parent); + else if (fchost->parent_wwnn && fchost->parent_wwpn) + virBufferAsprintf(&buf, "<parent wwnn='%s' wwpn='%s'/>\n", + fchost->parent_wwnn, fchost->parent_wwpn); + else if (fchost->parent_fabric_wwn) + virBufferAsprintf(&buf, "<parent fabric_wnn='%s'/>\n", + fchost->parent_fabric_wwn); + virBufferAddLit(&buf, "<capability type='scsi_host'>\n"); + virBufferAdjustIndent(&buf, 2); + virBufferAsprintf(&buf, "<capability type='fc_host' wwnn='%s' wwpn='%s'>\n", + fchost->wwnn, fchost->wwpn); + virBufferAddLit(&buf, "</capability>\n"); + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "</capability>\n"); + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "</device>\n");
We really shouldn't be generating XML internally just to immediately give back to ourselves. We should populate the appropriate internal config data struct instead and avoid XML entirely.
I think I originally got the idea from qemuMigrationPrecreateDisk and a desire (at the time) to not create an API for perhaps some less obvious to some backporting reasons. Also since NodeDeviceCreateXML essentially has a single purpose - I guess it just felt "bounded"... John
+ + if (!(vhbaStr = virBufferContentAndReset(&buf))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("unable to create node device XML")); + goto cleanup; + } + + if (!(dev = virNodeDeviceCreateXML(conn, vhbaStr, 0))) + goto cleanup; + created = true; + + skip_create: + if (VIR_STRDUP(name, virNodeDeviceGetName(dev)) < 0) { + /* If we created, then destroy it */ + if (created) + ignore_value(virNodeDeviceDestroy(dev)); + } + + cleanup: + VIR_FREE(vhbaStr); + virObjectUnref(dev); + return name; +} +
Regards, Daniel

Add the parent wwnn/wwpn and fabric_wwn tests for the storage pool now that we have the capability to use the node device driver to handle the searches via a connection. Signed-off-by: John Ferlan <jferlan@redhat.com> --- tests/fchosttest.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/fchosttest.c b/tests/fchosttest.c index c024ae5..c080c9b 100644 --- a/tests/fchosttest.c +++ b/tests/fchosttest.c @@ -100,6 +100,30 @@ static const char test12_xml[] = "</pool>"; +/* virStoragePoolCreateXML parent wwnn/wwpn to find the vport capable HBA */ +static const char test13_xml[] = +"<pool type='scsi'>" +" <name>vhba_pool</name>" +" <source>" +" <adapter type='fc_host' parent_wwnn='2000000012341234' parent_wwpn='1000000012341234' wwnn='20000000c9831b4b' wwpn='10000000c9831b4b'/>" +" </source>" +" <target>" +" <path>/dev/disk/by-path</path>" +" </target>" +"</pool>"; + +/* virStoragePoolCreateXML parent fabric_wwn to find the vport capable HBA */ +static const char test14_xml[] = +"<pool type='scsi'>" +" <name>vhba_pool</name>" +" <source>" +" <adapter type='fc_host' parent_fabric_wwn='2000000043214321' wwnn='20000000c9831b4b' wwpn='10000000c9831b4b'/>" +" </source>" +" <target>" +" <path>/dev/disk/by-path</path>" +" </target>" +"</pool>"; + /* Test virIsVHBACapable */ static int test1(const void *data ATTRIBUTE_UNUSED) @@ -389,6 +413,14 @@ mymain(void) if (virTestRun("manageVHBAByStoragePool-no-parent", manageVHBAByStoragePool, test12_xml) < 0) ret = -1; + if (virTestRun("manageVHBAByStoragePool-parent-wwn", + manageVHBAByStoragePool, + test13_xml) < 0) + ret = -1; + if (virTestRun("manageVHBAByStoragePool-parent-fabric-wwn", + manageVHBAByStoragePool, + test14_xml) < 0) + ret = -1; cleanup: VIR_FREE(fchost_prefix); -- 2.9.3
participants (3)
-
Daniel P. Berrange
-
John Ferlan
-
Laine Stump