Use XPath instead of iterating through the nodes.
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/conf/domain_conf.c | 98 +++++++++++++++---------------------------
1 file changed, 35 insertions(+), 63 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ae7cb1e1c5..05c2c63f58 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -8262,89 +8262,61 @@ virDomainStorageNetworkParseHosts(xmlNodePtr node,
static int
virDomainHostdevSubsysSCSIHostDefParseXML(xmlNodePtr sourcenode,
+ xmlXPathContextPtr ctxt,
virDomainHostdevSubsysSCSIPtr scsisrc)
{
- bool got_address = false, got_adapter = false;
- xmlNodePtr cur;
virDomainHostdevSubsysSCSIHostPtr scsihostsrc = &scsisrc->u.host;
g_autofree char *bus = NULL;
g_autofree char *target = NULL;
g_autofree char *unit = NULL;
+ xmlNodePtr addressnode = NULL;
+ VIR_XPATH_NODE_AUTORESTORE(ctxt);
- cur = sourcenode->children;
- while (cur != NULL) {
- if (cur->type == XML_ELEMENT_NODE) {
- if (virXMLNodeNameEqual(cur, "address")) {
- if (got_address) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("more than one source addresses is "
- "specified for scsi hostdev"));
- return -1;
- }
-
- if (!(bus = virXMLPropString(cur, "bus")) ||
- !(target = virXMLPropString(cur, "target")) ||
- !(unit = virXMLPropString(cur, "unit"))) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("'bus', 'target', and
'unit' must be specified "
- "for scsi hostdev source address"));
- return -1;
- }
+ ctxt->node = sourcenode;
- if (virStrToLong_uip(bus, NULL, 0, &scsihostsrc->bus) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot parse bus '%s'"), bus);
- return -1;
- }
+ if (!(addressnode = virXPathNode("./address", ctxt))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("'address' must be specified for scsi hostdev
source"));
+ return -1;
+ }
- if (virStrToLong_uip(target, NULL, 0,
- &scsihostsrc->target) < 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot parse target '%s'"),
target);
- return -1;
- }
+ if (!(bus = virXMLPropString(addressnode, "bus")) ||
+ !(target = virXMLPropString(addressnode, "target")) ||
+ !(unit = virXMLPropString(addressnode, "unit"))) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("'bus', 'target', and 'unit' must
be specified "
+ "for scsi hostdev source address"));
+ return -1;
+ }
- if (virStrToLong_ullp(unit, NULL, 0, &scsihostsrc->unit) < 0)
{
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot parse unit '%s'"), unit);
- return -1;
- }
+ if (virStrToLong_uip(bus, NULL, 0, &scsihostsrc->bus) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse bus '%s'"), bus);
+ return -1;
+ }
- got_address = true;
- } else if (virXMLNodeNameEqual(cur, "adapter")) {
- if (got_adapter) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("more than one adapters is specified "
- "for scsi hostdev source"));
- return -1;
- }
- if (!(scsihostsrc->adapter = virXMLPropString(cur, "name")))
{
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("'adapter' must be specified for scsi
hostdev source"));
- return -1;
- }
+ if (virStrToLong_uip(target, NULL, 0, &scsihostsrc->target) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse target '%s'"), target);
+ return -1;
+ }
- got_adapter = true;
- } else {
- virReportError(VIR_ERR_XML_ERROR,
- _("unsupported element '%s' of scsi hostdev
source"),
- cur->name);
- return -1;
- }
- }
- cur = cur->next;
+ if (virStrToLong_ullp(unit, NULL, 0, &scsihostsrc->unit) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse unit '%s'"), unit);
+ return -1;
}
- if (!got_address || !got_adapter) {
+ if (!(scsihostsrc->adapter = virXPathString("string(./adapter/@name)",
ctxt))) {
virReportError(VIR_ERR_XML_ERROR, "%s",
- _("'adapter' and 'address' must be specified
for scsi "
- "hostdev source"));
+ _("'adapter' name must be specified for scsi hostdev
source"));
return -1;
}
return 0;
}
+
static int
virDomainHostdevSubsysSCSIiSCSIDefParseXML(xmlNodePtr sourcenode,
virDomainHostdevSubsysSCSIPtr def,
@@ -8441,7 +8413,7 @@ virDomainHostdevSubsysSCSIDefParseXML(xmlNodePtr sourcenode,
switch ((virDomainHostdevSCSIProtocolType) scsisrc->protocol) {
case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_NONE:
- return virDomainHostdevSubsysSCSIHostDefParseXML(sourcenode, scsisrc);
+ return virDomainHostdevSubsysSCSIHostDefParseXML(sourcenode, ctxt, scsisrc);
case VIR_DOMAIN_HOSTDEV_SCSI_PROTOCOL_TYPE_ISCSI:
return virDomainHostdevSubsysSCSIiSCSIDefParseXML(sourcenode, scsisrc, ctxt,
--
2.26.2