Move parsing of <backingStore> into virDomainStorageSourceParseFull so that it can be reused easily. Signed-off-by: Peter Krempa <pkrempa@xxxxxxxxxx> --- src/conf/domain_conf.c | 100 +++++++++++++++++++++------------------ src/conf/domain_conf.h | 3 +- src/conf/snapshot_conf.c | 2 +- src/qemu/qemu_domain.c | 2 +- tests/qemublocktest.c | 2 +- 5 files changed, 59 insertions(+), 50 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5790b19315..5b13402154 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -9111,6 +9111,43 @@ virDomainStorageSourceParse(xmlNodePtr node, } +static int +virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt, + virStorageSourcePtr src, + unsigned int flags, + virDomainXMLOptionPtr xmlopt) +{ + VIR_XPATH_NODE_AUTORESTORE(ctxt); + VIR_AUTOUNREF(virStorageSourcePtr) backingStore = NULL; + VIR_AUTOFREE(char *) type = NULL; + + if (!(ctxt->node = virXPathNode("./backingStore", ctxt))) + return 0; + + /* terminator does not have a type */ + if (!(type = virXMLPropString(ctxt->node, "type"))) { + if (!(src->backingStore = virStorageSourceNew())) + return -1; + + return 0; + } + + if (!(backingStore = virDomainStorageSourceParseFull("string(@type)", + "string(./format/@type)", + "./source", + "string(@index)", + false, true, ctxt, flags, xmlopt))) + return -1; + + /* backing store is always read-only */ + backingStore->readonly = true; + + VIR_STEAL_PTR(src->backingStore, backingStore); + + return 0; +} + + /** * virDomainStorageSourceParseFull * @typeXPath: XPath query string for the 'type' of virStorageSource @@ -9118,6 +9155,7 @@ virDomainStorageSourceParse(xmlNodePtr node, * @sourceXPath: XPath query for the <source> subelement * @indexXPath: XPath query for 'id' in virStorageSource (may be NULL if skipped) * @allowMissing: if true no errors are reported if the above fields are missing + * @backingStore: Full backing chain is parsed if true * @ctxt: XPath context * @flags: XML parser flags * @xmlopt: XML parser callbacks @@ -9128,6 +9166,10 @@ virDomainStorageSourceParse(xmlNodePtr node, * are missing. @formatXPath and @indexXpath may be NULL if they should be omitted * or if the caller parses the value separately. * + * @backingStore controls whether the full backing chain should be parsed. + * Backing chain is parsed from elements named <backingStore> relative to + * the node of @ctxt when called. + * * Returns the parsed source or NULL on error. */ virStorageSourcePtr @@ -9136,6 +9178,7 @@ virDomainStorageSourceParseFull(const char *typeXPath, const char *sourceXPath, const char *indexXPath, bool allowMissing, + bool backingStore, xmlXPathContextPtr ctxt, unsigned int flags, virDomainXMLOptionPtr xmlopt) @@ -9200,50 +9243,15 @@ virDomainStorageSourceParseFull(const char *typeXPath, virDomainStorageSourceParse(sourceNode, ctxt, src, flags, xmlopt) < 0) return NULL; + if (backingStore && + virDomainDiskBackingStoreParse(ctxt, src, flags, xmlopt) < 0) + return NULL; + VIR_STEAL_PTR(ret, src); return ret; } -static int -virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt, - virStorageSourcePtr src, - unsigned int flags, - virDomainXMLOptionPtr xmlopt) -{ - VIR_XPATH_NODE_AUTORESTORE(ctxt); - VIR_AUTOUNREF(virStorageSourcePtr) backingStore = NULL; - VIR_AUTOFREE(char *) type = NULL; - - if (!(ctxt->node = virXPathNode("./backingStore", ctxt))) - return 0; - - /* terminator does not have a type */ - if (!(type = virXMLPropString(ctxt->node, "type"))) { - if (!(src->backingStore = virStorageSourceNew())) - return -1; - - return 0; - } - - if (!(backingStore = virDomainStorageSourceParseFull("string(@type)", - "string(./format/@type)", - "./source", - "string(@index)", - false, ctxt, flags, xmlopt))) - return -1; - - /* backing store is always read-only */ - backingStore->readonly = true; - - if (virDomainDiskBackingStoreParse(ctxt, backingStore, flags, xmlopt) < 0) - return -1; - - VIR_STEAL_PTR(src->backingStore, backingStore); - - return 0; -} - #define PARSE_IOTUNE(val) \ if (virXPathULongLong("string(./iotune/" #val ")", \ ctxt, &def->blkdeviotune.val) == -2) { \ @@ -9354,7 +9362,7 @@ virDomainDiskDefMirrorParse(virDomainDiskDefPtr def, NULL, "./mirror/source", NULL, - false, ctxt, flags, xmlopt))) + false, false, ctxt, flags, xmlopt))) return -1; mirrorFormat = virXPathString("string(./mirror/format/@type)", ctxt); @@ -9765,6 +9773,7 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, VIR_AUTOFREE(char *) vendor = NULL; VIR_AUTOFREE(char *) product = NULL; VIR_AUTOFREE(char *) domain_name = NULL; + bool backingStore = true; if (!(def = virDomainDiskDefNew(xmlopt))) return NULL; @@ -9774,6 +9783,9 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, /* defaults */ def->device = VIR_DOMAIN_DISK_DEVICE_DISK; + if ((flags & VIR_DOMAIN_DEF_PARSE_DISK_SOURCE)) + backingStore = false; + if ((tmp = virXMLPropString(node, "device")) && (def->device = virDomainDiskDeviceTypeFromString(tmp)) < 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -9799,7 +9811,8 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, if (!(def->src = virDomainStorageSourceParseFull("string(@type)", NULL, "./source", "string(./source/@index)", - true, ctxt, flags, xmlopt))) + true, backingStore, + ctxt, flags, xmlopt))) goto error; for (cur = node->children; cur != NULL; cur = cur->next) { @@ -10134,11 +10147,6 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt, VIR_STEAL_PTR(def->vendor, vendor); VIR_STEAL_PTR(def->product, product); - if (!(flags & VIR_DOMAIN_DEF_PARSE_DISK_SOURCE)) { - if (virDomainDiskBackingStoreParse(ctxt, def->src, flags, xmlopt) < 0) - goto error; - } - if (flags & VIR_DOMAIN_DEF_PARSE_STATUS && virDomainDiskDefParsePrivateData(ctxt, def, xmlopt) < 0) goto error; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 72272965ae..7ab7b28e4f 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3470,11 +3470,12 @@ virDomainStorageSourceParseFull(const char *typeXPath, const char *sourceXPath, const char *indexXPath, bool allowMissing, + bool backingStore, xmlXPathContextPtr ctxt, unsigned int flags, virDomainXMLOptionPtr xmlopt) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) - ATTRIBUTE_NONNULL(6); + ATTRIBUTE_NONNULL(7); int virDomainDefGetVcpuPinInfoHelper(virDomainDefPtr def, int maplen, diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c index 5dad2c3c51..4cc4795cf4 100644 --- a/src/conf/snapshot_conf.c +++ b/src/conf/snapshot_conf.c @@ -133,7 +133,7 @@ virDomainSnapshotDiskDefParseXML(xmlNodePtr node, if (!(def->src = virDomainStorageSourceParseFull("string(@type)", "string(./driver/@type)", "./source", - NULL, true, + NULL, true, false, ctxt, flags, xmlopt))) goto cleanup; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e406647d8f..3ae9bdad1a 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2696,7 +2696,7 @@ qemuDomainObjPrivateXMLParseJobNBDSource(xmlNodePtr node, if (!(diskPriv->migrSource = virDomainStorageSourceParseFull("string(@type)", "string(@format)", ".", NULL, - false, ctxt, + false, false, ctxt, VIR_DOMAIN_DEF_PARSE_STATUS, priv->driver->xmlopt))) return -1; diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 48cec2869b..09eaf155e9 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -57,7 +57,7 @@ testBackingXMLjsonXML(const void *args) if (!(xmlsrc = virDomainStorageSourceParseFull("string(./@type)", "string(./@format)", - ".", NULL, false, + ".", NULL, false, false, ctxt, 0, NULL))) { fprintf(stderr, "failed to parse disk source xml\n"); return -1; -- 2.20.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list