[PATCH 00/14] qemu: Fix 'backing store' string generator for -blockdev

QEMU doesn't like the backing store string generated by libvirt with -blockdev. Luckily we are able to parse them back and with blockdev they would no longer be used by qemu directly. Fix the generator an da few issues noticed along. Peter Krempa (14): conf: rename 'namespace' property of struct _virStorageSourceNVMeDef qemublocktest: xml->json: Add test for NVMe virDomainDiskSourceNVMeFormat: Format only valid 'managed' values qemublocktest: xml->json: Refactor cleanup in test case functions testQemuDiskXMLToPropsValidateFileSrcOnly: Move together with rest of xml->json code qemuBlockGetBackingStoreString: Add 'pretty' argument testQemuDiskXMLToProps: Store all per-image data in one structure qemublocktest: Test backing store strings qemuBlockGetBackingStoreString: Remove 'ret' variable storage: Implement backing store support for "fat:" prefix qemuBlockGetBackingStoreString: Add extra wrapping object to JSON strings qemu: block: Extract formatting of cookie string qemuBlockGetBackingStoreString: Properly handle 'http/s' with cookies and others storage: Parse 'nvme' disk source properties from json:{} pseudo-uri src/conf/domain_conf.c | 17 +- src/hypervisor/virhostdev.c | 2 +- src/qemu/qemu_block.c | 64 +++-- src/qemu/qemu_block.h | 6 +- src/qemu/qemu_domain.c | 13 +- src/qemu/qemu_driver.c | 4 +- src/util/virstoragefile.c | 43 +++- src/util/virstoragefile.h | 2 +- tests/qemublocktest.c | 232 ++++++++++-------- .../qcow2-backing-qcow2-slice.json | 2 +- .../imagecreate/qcow2-backing-raw-slice.json | 2 +- .../xml2json/block-raw-noopts-srconly.json | 13 +- .../block-raw-reservations-srconly.json | 13 +- .../xml2json/dir-fat-cache-srconly.json | 15 +- .../xml2json/dir-fat-floppy-srconly.json | 15 +- .../xml2json/dir-fat-readonly-srconly.json | 15 +- ...ile-backing_basic-aio_threads-srconly.json | 68 +++-- ...acking_basic-cache-directsync-srconly.json | 68 +++-- ...file-backing_basic-cache-none-srconly.json | 68 +++-- ...le-backing_basic-cache-unsafe-srconly.json | 68 +++-- ...backing_basic-cache-writeback-srconly.json | 68 +++-- ...king_basic-cache-writethrough-srconly.json | 68 +++-- .../file-backing_basic-detect-srconly.json | 68 +++-- .../file-backing_basic-noopts-srconly.json | 52 ++-- ...le-backing_basic-unmap-detect-srconly.json | 68 +++-- ...le-backing_basic-unmap-ignore-srconly.json | 68 +++-- .../file-backing_basic-unmap-srconly.json | 68 +++-- .../xml2json/file-bochs-noopts-srconly.json | 13 +- .../xml2json/file-cloop-noopts-srconly.json | 13 +- .../xml2json/file-dmg-noopts-srconly.json | 13 +- .../xml2json/file-ploop-noopts-srconly.json | 13 +- ...cow2-backing-chain-encryption-srconly.json | 26 +- ...le-qcow2-backing-chain-noopts-srconly.json | 130 +++++++--- ...w2-backing-chain-unterminated-srconly.json | 26 +- .../xml2json/file-raw-aio_native-srconly.json | 13 +- .../xml2json/file-raw-luks-srconly.json | 13 +- .../xml2json/file-raw-noopts-srconly.json | 13 +- .../xml2json/file-vdi-noopts-srconly.json | 13 +- .../xml2json/file-vhd-noopts-srconly.json | 13 +- .../xml2json/file-vpc-noopts-srconly.json | 13 +- .../network-http-curlopts-srconly.json | 17 ++ .../xml2json/network-http-curlopts.json | 15 ++ .../xml2json/network-http-curlopts.xml | 20 ++ .../xml2json/network-http-noopts-srconly.json | 9 + .../xml2json/network-http-noopts.json | 14 ++ .../xml2json/network-http-noopts.xml | 15 ++ .../xml2json/network-nbd-tls-srconly.json | 19 +- ...w2-backing-chain-cache-unsafe-srconly.json | 69 ++++-- ...backing-chain-encryption_auth-srconly.json | 69 ++++-- .../xml2json/nvme-raw-noopts-srconly.json | 15 ++ .../xml2json/nvme-raw-noopts.json | 14 ++ .../xml2json/nvme-raw-noopts.xml | 13 + tests/virstoragetest.c | 10 + 53 files changed, 1226 insertions(+), 575 deletions(-) create mode 100644 tests/qemublocktestdata/xml2json/network-http-curlopts-srconly.json create mode 100644 tests/qemublocktestdata/xml2json/network-http-curlopts.json create mode 100644 tests/qemublocktestdata/xml2json/network-http-curlopts.xml create mode 100644 tests/qemublocktestdata/xml2json/network-http-noopts-srconly.json create mode 100644 tests/qemublocktestdata/xml2json/network-http-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/network-http-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json create mode 100644 tests/qemublocktestdata/xml2json/nvme-raw-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/nvme-raw-noopts.xml -- 2.24.1

While 'namespace' is not a reserved word in C, it is in C++. Our compilers are happy with it but syntax-hilighting in some editors hilights is as a keyword. Rename it to prevent confusion. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 12 ++++++------ src/hypervisor/virhostdev.c | 2 +- src/qemu/qemu_block.c | 2 +- src/util/virstoragefile.c | 4 ++-- src/util/virstoragefile.h | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e0432fc47d..f1e4d33a8d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6087,7 +6087,7 @@ virDomainDiskDefValidate(const virDomainDef *def, if (disk->src->type == VIR_STORAGE_TYPE_NVME) { /* NVMe namespaces start from 1 */ - if (disk->src->nvme->namespace == 0) { + if (disk->src->nvme->namespc == 0) { virReportError(VIR_ERR_XML_ERROR, "%s", _("NVMe namespace can't be zero")); return -1; @@ -9525,7 +9525,7 @@ virDomainDiskSourceNVMeParse(xmlNodePtr node, { g_autoptr(virStorageSourceNVMeDef) nvme = NULL; g_autofree char *type = NULL; - g_autofree char *namespace = NULL; + g_autofree char *namespc = NULL; g_autofree char *managed = NULL; xmlNodePtr address; @@ -9544,16 +9544,16 @@ virDomainDiskSourceNVMeParse(xmlNodePtr node, return -1; } - if (!(namespace = virXMLPropString(node, "namespace"))) { + if (!(namespc = virXMLPropString(node, "namespace"))) { virReportError(VIR_ERR_XML_ERROR, "%s", _("missing 'namespace' attribute to disk source")); return -1; } - if (virStrToLong_ull(namespace, NULL, 10, &nvme->namespace) < 0) { + if (virStrToLong_ull(namespc, NULL, 10, &nvme->namespc) < 0) { virReportError(VIR_ERR_XML_ERROR, _("malformed namespace '%s'"), - namespace); + namespc); return -1; } @@ -24664,7 +24664,7 @@ virDomainDiskSourceNVMeFormat(virBufferPtr attrBuf, virBufferAddLit(attrBuf, " type='pci'"); virBufferAsprintf(attrBuf, " managed='%s'", virTristateBoolTypeToString(nvme->managed)); - virBufferAsprintf(attrBuf, " namespace='%llu'", nvme->namespace); + virBufferAsprintf(attrBuf, " namespace='%llu'", nvme->namespc); virPCIDeviceAddressFormat(childBuf, nvme->pciAddr, false); } diff --git a/src/hypervisor/virhostdev.c b/src/hypervisor/virhostdev.c index 6565cebe57..9017cc3be8 100644 --- a/src/hypervisor/virhostdev.c +++ b/src/hypervisor/virhostdev.c @@ -2212,7 +2212,7 @@ virHostdevGetNVMeDeviceList(virNVMeDeviceListPtr nvmeDevices, continue; if (!(dev = virNVMeDeviceNew(&srcNVMe->pciAddr, - srcNVMe->namespace, + srcNVMe->namespc, srcNVMe->managed))) return -1; diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 5c85ddd44c..22ea2fe018 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1008,7 +1008,7 @@ qemuBlockStorageSourceGetNVMeProps(virStorageSourcePtr src) ignore_value(virJSONValueObjectCreate(&ret, "s:driver", "nvme", "s:device", pciAddr, - "U:namespace", nvme->namespace, + "U:namespace", nvme->namespc, NULL)); return ret; } diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index e723cc9410..ca39391379 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -2052,7 +2052,7 @@ virStorageSourceNVMeDefCopy(const virStorageSourceNVMeDef *src) ret = g_new0(virStorageSourceNVMeDef, 1); - ret->namespace = src->namespace; + ret->namespc = src->namespc; ret->managed = src->managed; virPCIDeviceAddressCopy(&ret->pciAddr, &src->pciAddr); return ret; @@ -2069,7 +2069,7 @@ virStorageSourceNVMeDefIsEqual(const virStorageSourceNVMeDef *a, if (!a || !b) return false; - if (a->namespace != b->namespace || + if (a->namespc != b->namespc || a->managed != b->managed || !virPCIDeviceAddressEqual(&a->pciAddr, &b->pciAddr)) return false; diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index f2a73feb6a..9427057f94 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -245,7 +245,7 @@ struct _virStorageSourceInitiatorDef { typedef struct _virStorageSourceNVMeDef virStorageSourceNVMeDef; typedef virStorageSourceNVMeDef *virStorageSourceNVMeDefPtr; struct _virStorageSourceNVMeDef { - unsigned long long namespace; + unsigned long long namespc; int managed; /* enum virTristateBool */ virPCIDeviceAddress pciAddr; -- 2.24.1

Based on the configuration from the only qemuxml2argv test. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 2 ++ .../xml2json/nvme-raw-noopts-srconly.json | 5 +++++ .../xml2json/nvme-raw-noopts.json | 14 ++++++++++++++ .../qemublocktestdata/xml2json/nvme-raw-noopts.xml | 13 +++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json create mode 100644 tests/qemublocktestdata/xml2json/nvme-raw-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/nvme-raw-noopts.xml diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index fca8939fbb..4c3e05b6b5 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1203,6 +1203,8 @@ mymain(void) TEST_DISK_TO_JSON("block-raw-noopts"); TEST_DISK_TO_JSON("block-raw-reservations"); + TEST_DISK_TO_JSON("nvme-raw-noopts"); + #define TEST_JSON_TO_JSON(nme) \ do { \ jsontojsondata.name = nme; \ diff --git a/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json b/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json new file mode 100644 index 0000000000..ed55c08cbf --- /dev/null +++ b/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json @@ -0,0 +1,5 @@ +{ + "driver": "nvme", + "device": "0000:01:00.0", + "namespace": 1 +} diff --git a/tests/qemublocktestdata/xml2json/nvme-raw-noopts.json b/tests/qemublocktestdata/xml2json/nvme-raw-noopts.json new file mode 100644 index 0000000000..e18e96099c --- /dev/null +++ b/tests/qemublocktestdata/xml2json/nvme-raw-noopts.json @@ -0,0 +1,14 @@ +{ + "node-name": "0123456789ABCDEF0123456789ABCDE", + "read-only": false, + "driver": "raw", + "file": "0123456789ABCDEF0123456789ABCDE" +} +{ + "driver": "nvme", + "device": "0000:01:00.0", + "namespace": 1, + "node-name": "0123456789ABCDEF0123456789ABCDE", + "auto-read-only": true, + "discard": "unmap" +} diff --git a/tests/qemublocktestdata/xml2json/nvme-raw-noopts.xml b/tests/qemublocktestdata/xml2json/nvme-raw-noopts.xml new file mode 100644 index 0000000000..1e4dbd6e56 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/nvme-raw-noopts.xml @@ -0,0 +1,13 @@ +<disk type='nvme' device='disk'> + <driver name='qemu' type='raw'/> + <source type='pci' managed='yes' namespace='1'> + <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + <privateData> + <nodenames> + <nodename type='storage' name='0123456789ABCDEF0123456789ABCDE'/> + <nodename type='format' name='0123456789ABCDEF0123456789ABCDE'/> + </nodenames> + </privateData> + </source> + <target dev='vda' bus='virtio'/> +</disk> -- 2.24.1

VIR_TRISTATE_BOOL_ABSENT which maps to the 'default' string would not be parsed back, so we shouldn't format it either. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f1e4d33a8d..f6a225e4e6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -24662,8 +24662,9 @@ virDomainDiskSourceNVMeFormat(virBufferPtr attrBuf, const virStorageSourceNVMeDef *nvme) { virBufferAddLit(attrBuf, " type='pci'"); - virBufferAsprintf(attrBuf, " managed='%s'", - virTristateBoolTypeToString(nvme->managed)); + if (nvme->managed != VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(attrBuf, " managed='%s'", + virTristateBoolTypeToString(nvme->managed)); virBufferAsprintf(attrBuf, " namespace='%llu'", nvme->namespc); virPCIDeviceAddressFormat(childBuf, nvme->pciAddr, false); } -- 2.24.1

On 23. 3. 2020 19:11, Peter Krempa wrote:
VIR_TRISTATE_BOOL_ABSENT which maps to the 'default' string would not be parsed back, so we shouldn't format it either.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f1e4d33a8d..f6a225e4e6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -24662,8 +24662,9 @@ virDomainDiskSourceNVMeFormat(virBufferPtr attrBuf, const virStorageSourceNVMeDef *nvme) { virBufferAddLit(attrBuf, " type='pci'"); - virBufferAsprintf(attrBuf, " managed='%s'", - virTristateBoolTypeToString(nvme->managed)); + if (nvme->managed != VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(attrBuf, " managed='%s'", + virTristateBoolTypeToString(nvme->managed)); virBufferAsprintf(attrBuf, " namespace='%llu'", nvme->namespc); virPCIDeviceAddressFormat(childBuf, nvme->pciAddr, false); }
There is a postparse callback which deals with _ABSENT (see commit 8cd7196974d): static int virDomainDiskDefPostParse(virDomainDiskDefPtr disk, const virDomainDef *def, virDomainXMLOptionPtr xmlopt) { ... if (disk->src->type == VIR_STORAGE_TYPE_NVME) { if (disk->src->nvme->managed == VIR_TRISTATE_BOOL_ABSENT) disk->src->nvme->managed = VIR_TRISTATE_BOOL_YES; } ... } But maybe the callback is not called from tests where virStorageSource is parsed directly? Michal

On Tue, Mar 24, 2020 at 12:38:58 +0100, Michal Privoznik wrote:
On 23. 3. 2020 19:11, Peter Krempa wrote:
VIR_TRISTATE_BOOL_ABSENT which maps to the 'default' string would not be parsed back, so we shouldn't format it either.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index f1e4d33a8d..f6a225e4e6 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -24662,8 +24662,9 @@ virDomainDiskSourceNVMeFormat(virBufferPtr attrBuf, const virStorageSourceNVMeDef *nvme) { virBufferAddLit(attrBuf, " type='pci'"); - virBufferAsprintf(attrBuf, " managed='%s'", - virTristateBoolTypeToString(nvme->managed)); + if (nvme->managed != VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(attrBuf, " managed='%s'", + virTristateBoolTypeToString(nvme->managed)); virBufferAsprintf(attrBuf, " namespace='%llu'", nvme->namespc); virPCIDeviceAddressFormat(childBuf, nvme->pciAddr, false); }
There is a postparse callback which deals with _ABSENT (see commit 8cd7196974d):
static int virDomainDiskDefPostParse(virDomainDiskDefPtr disk, const virDomainDef *def, virDomainXMLOptionPtr xmlopt) { ... if (disk->src->type == VIR_STORAGE_TYPE_NVME) { if (disk->src->nvme->managed == VIR_TRISTATE_BOOL_ABSENT) disk->src->nvme->managed = VIR_TRISTATE_BOOL_YES; } ... }
But maybe the callback is not called from tests where virStorageSource is parsed directly?
Well, the issue is when the virStorageSource is created from the backing store rather than parsed from XML which is added later on.

On 24. 3. 2020 13:12, Peter Krempa wrote:
Well, the issue is when the virStorageSource is created from the backing store rather than parsed from XML which is added later on.
Should have a source post parse callback then? Anyway, Reviewed-by: Michal Privoznik <mprivozn@redhat.com> for whole series. Michal

Use automatic variable clearing and remove the cleanup sections of testQemuDiskXMLToProps, testQemuDiskXMLToPropsValidateSchema and testQemuDiskXMLToPropsValidateFile. testQemuDiskXMLToPropsValidateFileSrcOnly already uses new helpers. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 76 +++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 49 deletions(-) diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 4c3e05b6b5..dfcf7552c1 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -259,39 +259,38 @@ testQemuDiskXMLToProps(const void *opaque) g_autoptr(virDomainDef) vmdef = NULL; virDomainDiskDefPtr disk = NULL; virStorageSourcePtr n; - virJSONValuePtr formatProps = NULL; - virJSONValuePtr storageProps = NULL; + g_autoptr(virJSONValue) formatProps = NULL; + g_autoptr(virJSONValue) storageProps = NULL; g_autoptr(virJSONValue) storageSrcOnlyProps = NULL; - char *xmlpath = NULL; - char *xmlstr = NULL; - int ret = -1; + g_autofree char *xmlpath = NULL; + g_autofree char *xmlstr = NULL; xmlpath = g_strdup_printf("%s%s.xml", testQemuDiskXMLToJSONPath, data->name); if (virTestLoadFile(xmlpath, &xmlstr) < 0) - goto cleanup; + return -1; /* qemu stores node names in the status XML portion */ if (!(disk = virDomainDiskDefParse(xmlstr, data->driver->xmlopt, VIR_DOMAIN_DEF_PARSE_STATUS))) - goto cleanup; + return -1; if (!(vmdef = virDomainDefNew()) || virDomainDiskInsert(vmdef, disk) < 0) - goto cleanup; + return -1; if (qemuCheckDiskConfig(disk, vmdef, data->qemuCaps) < 0 || qemuDomainDeviceDefValidateDisk(disk, data->qemuCaps) < 0) { VIR_TEST_VERBOSE("invalid configuration for disk"); - goto cleanup; + return -1; } for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) { if (testQemuDiskXMLToJSONFakeSecrets(n) < 0) - goto cleanup; + return -1; if (qemuDomainValidateStorageSource(n, data->qemuCaps) < 0) - goto cleanup; + return -1; qemuDomainPrepareDiskSourceData(disk, n); @@ -300,27 +299,20 @@ testQemuDiskXMLToProps(const void *opaque) !(storageProps = qemuBlockStorageSourceGetBackendProps(n, false, false, true))) { if (!data->fail) { VIR_TEST_VERBOSE("failed to generate qemu blockdev props"); - goto cleanup; + return -1; } } else if (data->fail) { VIR_TEST_VERBOSE("qemu blockdev props should have failed"); - goto cleanup; + return -1; } if (VIR_APPEND_ELEMENT(data->props, data->nprops, formatProps) < 0 || VIR_APPEND_ELEMENT(data->props, data->nprops, storageProps) < 0 || VIR_APPEND_ELEMENT(data->propssrc, data->npropssrc, storageSrcOnlyProps) < 0) - goto cleanup; + return -1; } - ret = 0; - - cleanup: - virJSONValueFree(formatProps); - virJSONValueFree(storageProps); - VIR_FREE(xmlpath); - VIR_FREE(xmlstr); - return ret; + return 0; } @@ -328,9 +320,6 @@ static int testQemuDiskXMLToPropsValidateSchema(const void *opaque) { struct testQemuDiskXMLToJSONData *data = (void *) opaque; - virBuffer debug = VIR_BUFFER_INITIALIZER; - char *propsstr = NULL; - char *debugmsg = NULL; int ret = 0; size_t i; @@ -338,35 +327,31 @@ testQemuDiskXMLToPropsValidateSchema(const void *opaque) return EXIT_AM_SKIP; for (i = 0; i < data->nprops; i++) { + g_auto(virBuffer) debug = VIR_BUFFER_INITIALIZER; + if (testQEMUSchemaValidate(data->props[i], data->schemaroot, data->schema, &debug) < 0) { - debugmsg = virBufferContentAndReset(&debug); - propsstr = virJSONValueToString(data->props[i], true); + g_autofree char *debugmsg = virBufferContentAndReset(&debug); + g_autofree char *propsstr = virJSONValueToString(data->props[i], true); VIR_TEST_VERBOSE("json does not conform to QAPI schema"); VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s", propsstr, NULLSTR(debugmsg)); - VIR_FREE(debugmsg); - VIR_FREE(propsstr); ret = -1; } - - virBufferFreeAndReset(&debug); } for (i = 0; i < data->npropssrc; i++) { + g_auto(virBuffer) debug = VIR_BUFFER_INITIALIZER; + if (testQEMUSchemaValidate(data->propssrc[i], data->schemaroot, data->schema, &debug) < 0) { - debugmsg = virBufferContentAndReset(&debug); - propsstr = virJSONValueToString(data->propssrc[i], true); + g_autofree char *debugmsg = virBufferContentAndReset(&debug); + g_autofree char *propsstr = virJSONValueToString(data->propssrc[i], true); VIR_TEST_VERBOSE("json does not conform to QAPI schema"); VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s", propsstr, NULLSTR(debugmsg)); - VIR_FREE(debugmsg); - VIR_FREE(propsstr); ret = -1; } - - virBufferFreeAndReset(&debug); } return ret; @@ -378,9 +363,8 @@ testQemuDiskXMLToPropsValidateFile(const void *opaque) { struct testQemuDiskXMLToJSONData *data = (void *) opaque; virBuffer buf = VIR_BUFFER_INITIALIZER; - char *jsonpath = NULL; - char *actual = NULL; - int ret = -1; + g_autofree char *jsonpath = NULL; + g_autofree char *actual = NULL; size_t i; if (data->fail) @@ -389,23 +373,17 @@ testQemuDiskXMLToPropsValidateFile(const void *opaque) jsonpath = g_strdup_printf("%s%s.json", testQemuDiskXMLToJSONPath, data->name); for (i = 0; i < data->nprops; i++) { - char *jsonstr; + g_autofree char *jsonstr = NULL; if (!(jsonstr = virJSONValueToString(data->props[i], true))) - goto cleanup; + return -1; virBufferAdd(&buf, jsonstr, -1); - VIR_FREE(jsonstr); } actual = virBufferContentAndReset(&buf); - ret = virTestCompareToFile(actual, jsonpath); - - cleanup: - VIR_FREE(jsonpath); - VIR_FREE(actual); - return ret; + return virTestCompareToFile(actual, jsonpath); } -- 2.24.1

The function was misplaced. Group it together with other helper functions for testing disk XML to qemu JSON props conversion. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 61 ++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index dfcf7552c1..312af0d962 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -387,6 +387,37 @@ testQemuDiskXMLToPropsValidateFile(const void *opaque) } +static int +testQemuDiskXMLToPropsValidateFileSrcOnly(const void *opaque) +{ + struct testQemuDiskXMLToJSONData *data = (void *) opaque; + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + g_autofree char *jsonpath = NULL; + g_autofree char *actual = NULL; + size_t i; + + if (data->fail) + return EXIT_AM_SKIP; + + jsonpath = g_strdup_printf("%s%s-srconly.json", testQemuDiskXMLToJSONPath, + data->name); + + for (i = 0; i < data->npropssrc; i++) { + g_autofree char *jsonstr = NULL; + + if (!(jsonstr = virJSONValueToString(data->propssrc[i], true))) + return -1; + + virBufferAdd(&buf, jsonstr, -1); + } + + actual = virBufferContentAndReset(&buf); + + return virTestCompareToFile(actual, jsonpath); +} + + + struct testQemuImageCreateData { const char *name; const char *backingname; @@ -515,36 +546,6 @@ testQemuImageCreate(const void *opaque) } -static int -testQemuDiskXMLToPropsValidateFileSrcOnly(const void *opaque) -{ - struct testQemuDiskXMLToJSONData *data = (void *) opaque; - g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; - g_autofree char *jsonpath = NULL; - g_autofree char *actual = NULL; - size_t i; - - if (data->fail) - return EXIT_AM_SKIP; - - jsonpath = g_strdup_printf("%s%s-srconly.json", testQemuDiskXMLToJSONPath, - data->name); - - for (i = 0; i < data->npropssrc; i++) { - g_autofree char *jsonstr = NULL; - - if (!(jsonstr = virJSONValueToString(data->propssrc[i], true))) - return -1; - - virBufferAdd(&buf, jsonstr, -1); - } - - actual = virBufferContentAndReset(&buf); - - return virTestCompareToFile(actual, jsonpath); -} - - static const char *bitmapDetectPrefix = "qemublocktestdata/bitmap/"; static void -- 2.24.1

Add support for pretty-printing of the JSON variant of the output for consumption in tests. All current callers pass 'false'. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 8 +++++--- src/qemu/qemu_block.h | 3 ++- src/qemu/qemu_driver.c | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 22ea2fe018..d6cc999a43 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -2027,13 +2027,15 @@ qemuBlockStorageGetCopyOnReadProps(virDomainDiskDefPtr disk) /** * qemuBlockGetBackingStoreString: * @src: storage source to get the string for + * @pretty: pretty-print the JSON (if applicable, used by tests) * * Formats a string used in the backing store field of a disk image which * supports backing store. Non-local storage may result in use of the json: * pseudo protocol for any complex configuration. */ char * -qemuBlockGetBackingStoreString(virStorageSourcePtr src) +qemuBlockGetBackingStoreString(virStorageSourcePtr src, + bool pretty) { int actualType = virStorageSourceGetActualType(src); g_autoptr(virJSONValue) backingProps = NULL; @@ -2100,7 +2102,7 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src) props = sliceProps; } - if (!(backingJSON = virJSONValueToString(props, false))) + if (!(backingJSON = virJSONValueToString(props, pretty))) return NULL; ret = g_strdup_printf("json:%s", backingJSON); @@ -2128,7 +2130,7 @@ qemuBlockStorageSourceCreateAddBacking(virStorageSourcePtr backing, backingFormatStr = virStorageFileFormatTypeToString(backing->format); } - if (!(backingFileStr = qemuBlockGetBackingStoreString(backing))) + if (!(backingFileStr = qemuBlockGetBackingStoreString(backing, false))) return -1; if (virJSONValueObjectAdd(props, diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index 28475b25c1..9bffe20bfb 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -178,7 +178,8 @@ qemuBlockSnapshotAddBlockdev(virJSONValuePtr actions, virStorageSourcePtr newsrc); char * -qemuBlockGetBackingStoreString(virStorageSourcePtr src) +qemuBlockGetBackingStoreString(virStorageSourcePtr src, + bool pretty) ATTRIBUTE_NONNULL(1); int diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 8a2cd35fa7..209f8279bd 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -17499,7 +17499,7 @@ qemuDomainBlockPullCommon(virDomainObjPtr vm, if (baseSource) { nodebase = baseSource->nodeformat; if (!backingPath && - !(backingPath = qemuBlockGetBackingStoreString(baseSource))) + !(backingPath = qemuBlockGetBackingStoreString(baseSource, false))) goto endjob; } device = disk->src->nodeformat; @@ -18667,7 +18667,7 @@ qemuDomainBlockCommit(virDomainPtr dom, nodebase = baseSource->nodeformat; device = qemuDomainDiskGetTopNodename(disk); if (!backingPath && top_parent && - !(backingPath = qemuBlockGetBackingStoreString(baseSource))) + !(backingPath = qemuBlockGetBackingStoreString(baseSource, false))) goto endjob; if (bitmapDisableActions) { -- 2.24.1

We had two non-syncrhonized arrays holding the individual data. This was a lazy way to do it when I was adding new tests recently. Since it's hard to extend with new data to test refactor the storage of test data to use a new struct where all per-image data are kept and can be extended easily. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 90 ++++++++++++++++++++++++++----------------- 1 file changed, 54 insertions(+), 36 deletions(-) diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 312af0d962..47d08333f7 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -180,6 +180,13 @@ testJSONtoJSON(const void *args) } +struct testQemuDiskXMLToJSONImageData { + virJSONValuePtr formatprops; + virJSONValuePtr storageprops; + virJSONValuePtr storagepropssrc; +}; + + struct testQemuDiskXMLToJSONData { virQEMUDriverPtr driver; virHashTablePtr schema; @@ -187,11 +194,8 @@ struct testQemuDiskXMLToJSONData { const char *name; bool fail; - virJSONValuePtr *props; - size_t nprops; - - virJSONValuePtr *propssrc; - size_t npropssrc; + struct testQemuDiskXMLToJSONImageData *images; + size_t nimages; virQEMUCapsPtr qemuCaps; }; @@ -202,16 +206,13 @@ testQemuDiskXMLToPropsClear(struct testQemuDiskXMLToJSONData *data) { size_t i; - for (i = 0; i < data->nprops; i++) - virJSONValueFree(data->props[i]); - - for (i = 0; i < data->npropssrc; i++) - virJSONValueFree(data->propssrc[i]); - - data->nprops = 0; - VIR_FREE(data->props); - data->npropssrc = 0; - VIR_FREE(data->propssrc); + for (i = 0; i < data->nimages; i++) { + virJSONValueFree(data->images[i].formatprops); + virJSONValueFree(data->images[i].storageprops); + virJSONValueFree(data->images[i].storagepropssrc); + } + data->nimages = 0; + VIR_FREE(data->images); } @@ -286,6 +287,7 @@ testQemuDiskXMLToProps(const void *opaque) } for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) { + if (testQemuDiskXMLToJSONFakeSecrets(n) < 0) return -1; @@ -306,10 +308,14 @@ testQemuDiskXMLToProps(const void *opaque) return -1; } - if (VIR_APPEND_ELEMENT(data->props, data->nprops, formatProps) < 0 || - VIR_APPEND_ELEMENT(data->props, data->nprops, storageProps) < 0 || - VIR_APPEND_ELEMENT(data->propssrc, data->npropssrc, storageSrcOnlyProps) < 0) + if (VIR_REALLOC_N(data->images, data->nimages + 1) < 0) return -1; + + data->images[data->nimages].formatprops = g_steal_pointer(&formatProps); + data->images[data->nimages].storageprops = g_steal_pointer(&storageProps); + data->images[data->nimages].storagepropssrc = g_steal_pointer(&storageSrcOnlyProps); + + data->nimages++; } return 0; @@ -326,27 +332,37 @@ testQemuDiskXMLToPropsValidateSchema(const void *opaque) if (data->fail) return EXIT_AM_SKIP; - for (i = 0; i < data->nprops; i++) { + for (i = 0; i < data->nimages; i++) { g_auto(virBuffer) debug = VIR_BUFFER_INITIALIZER; - if (testQEMUSchemaValidate(data->props[i], data->schemaroot, + if (testQEMUSchemaValidate(data->images[i].formatprops, data->schemaroot, data->schema, &debug) < 0) { g_autofree char *debugmsg = virBufferContentAndReset(&debug); - g_autofree char *propsstr = virJSONValueToString(data->props[i], true); + g_autofree char *propsstr = virJSONValueToString(data->images[i].formatprops, true); VIR_TEST_VERBOSE("json does not conform to QAPI schema"); VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s", propsstr, NULLSTR(debugmsg)); ret = -1; } - } - for (i = 0; i < data->npropssrc; i++) { - g_auto(virBuffer) debug = VIR_BUFFER_INITIALIZER; + virBufferFreeAndReset(&debug); - if (testQEMUSchemaValidate(data->propssrc[i], data->schemaroot, + if (testQEMUSchemaValidate(data->images[i].storageprops, data->schemaroot, data->schema, &debug) < 0) { g_autofree char *debugmsg = virBufferContentAndReset(&debug); - g_autofree char *propsstr = virJSONValueToString(data->propssrc[i], true); + g_autofree char *propsstr = virJSONValueToString(data->images[i].storageprops, true); + VIR_TEST_VERBOSE("json does not conform to QAPI schema"); + VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s", + propsstr, NULLSTR(debugmsg)); + ret = -1; + } + + virBufferFreeAndReset(&debug); + + if (testQEMUSchemaValidate(data->images[i].storagepropssrc, data->schemaroot, + data->schema, &debug) < 0) { + g_autofree char *debugmsg = virBufferContentAndReset(&debug); + g_autofree char *propsstr = virJSONValueToString(data->images[i].storagepropssrc, true); VIR_TEST_VERBOSE("json does not conform to QAPI schema"); VIR_TEST_DEBUG("json:\n%s\ndoes not match schema. Debug output:\n %s", propsstr, NULLSTR(debugmsg)); @@ -372,13 +388,17 @@ testQemuDiskXMLToPropsValidateFile(const void *opaque) jsonpath = g_strdup_printf("%s%s.json", testQemuDiskXMLToJSONPath, data->name); - for (i = 0; i < data->nprops; i++) { - g_autofree char *jsonstr = NULL; + for (i = 0; i < data->nimages; i++) { + g_autofree char *formatprops = NULL; + g_autofree char *storageprops = NULL; - if (!(jsonstr = virJSONValueToString(data->props[i], true))) + if (!(formatprops = virJSONValueToString(data->images[i].formatprops, true))) return -1; - virBufferAdd(&buf, jsonstr, -1); + if (!(storageprops = virJSONValueToString(data->images[i].storageprops, true))) + return -1; + + virBufferStrcat(&buf, formatprops, storageprops, NULL); } actual = virBufferContentAndReset(&buf); @@ -402,10 +422,10 @@ testQemuDiskXMLToPropsValidateFileSrcOnly(const void *opaque) jsonpath = g_strdup_printf("%s%s-srconly.json", testQemuDiskXMLToJSONPath, data->name); - for (i = 0; i < data->npropssrc; i++) { + for (i = 0; i < data->nimages; i++) { g_autofree char *jsonstr = NULL; - if (!(jsonstr = virJSONValueToString(data->propssrc[i], true))) + if (!(jsonstr = virJSONValueToString(data->images[i].storagepropssrc, true))) return -1; virBufferAdd(&buf, jsonstr, -1); @@ -1117,10 +1137,8 @@ mymain(void) #define TEST_DISK_TO_JSON_FULL(nme, fl) \ do { \ diskxmljsondata.name = nme; \ - diskxmljsondata.props = NULL; \ - diskxmljsondata.nprops = 0; \ - diskxmljsondata.propssrc = NULL; \ - diskxmljsondata.npropssrc = 0; \ + diskxmljsondata.images = NULL; \ + diskxmljsondata.nimages = 0; \ diskxmljsondata.fail = fl; \ if (virTestRun("disk xml to props " nme, testQemuDiskXMLToProps, \ &diskxmljsondata) < 0) \ -- 2.24.1

With -blockdev libvirt provides the string which is recorded as 'backing store' property of an image to qemu. Add testing for qemuBlockGetBackingStoreString which generates these strings as there's logic which determines which format to use. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 20 ++- .../xml2json/block-raw-noopts-srconly.json | 13 +- .../block-raw-reservations-srconly.json | 13 +- .../xml2json/dir-fat-cache-srconly.json | 15 +- .../xml2json/dir-fat-floppy-srconly.json | 15 +- .../xml2json/dir-fat-readonly-srconly.json | 15 +- ...ile-backing_basic-aio_threads-srconly.json | 68 +++++---- ...acking_basic-cache-directsync-srconly.json | 68 +++++---- ...file-backing_basic-cache-none-srconly.json | 68 +++++---- ...le-backing_basic-cache-unsafe-srconly.json | 68 +++++---- ...backing_basic-cache-writeback-srconly.json | 68 +++++---- ...king_basic-cache-writethrough-srconly.json | 68 +++++---- .../file-backing_basic-detect-srconly.json | 68 +++++---- .../file-backing_basic-noopts-srconly.json | 52 ++++--- ...le-backing_basic-unmap-detect-srconly.json | 68 +++++---- ...le-backing_basic-unmap-ignore-srconly.json | 68 +++++---- .../file-backing_basic-unmap-srconly.json | 68 +++++---- .../xml2json/file-bochs-noopts-srconly.json | 13 +- .../xml2json/file-cloop-noopts-srconly.json | 13 +- .../xml2json/file-dmg-noopts-srconly.json | 13 +- .../xml2json/file-ploop-noopts-srconly.json | 13 +- ...cow2-backing-chain-encryption-srconly.json | 26 ++-- ...le-qcow2-backing-chain-noopts-srconly.json | 130 ++++++++++++------ ...w2-backing-chain-unterminated-srconly.json | 26 ++-- .../xml2json/file-raw-aio_native-srconly.json | 13 +- .../xml2json/file-raw-luks-srconly.json | 13 +- .../xml2json/file-raw-noopts-srconly.json | 13 +- .../xml2json/file-vdi-noopts-srconly.json | 13 +- .../xml2json/file-vhd-noopts-srconly.json | 13 +- .../xml2json/file-vpc-noopts-srconly.json | 13 +- .../xml2json/network-nbd-tls-srconly.json | 19 ++- ...w2-backing-chain-cache-unsafe-srconly.json | 68 ++++++--- ...backing-chain-encryption_auth-srconly.json | 68 ++++++--- .../xml2json/nvme-raw-noopts-srconly.json | 19 ++- 34 files changed, 876 insertions(+), 433 deletions(-) diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 47d08333f7..709d94fd80 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -184,6 +184,7 @@ struct testQemuDiskXMLToJSONImageData { virJSONValuePtr formatprops; virJSONValuePtr storageprops; virJSONValuePtr storagepropssrc; + char *backingstore; }; @@ -210,6 +211,7 @@ testQemuDiskXMLToPropsClear(struct testQemuDiskXMLToJSONData *data) virJSONValueFree(data->images[i].formatprops); virJSONValueFree(data->images[i].storageprops); virJSONValueFree(data->images[i].storagepropssrc); + g_free(data->images[i].backingstore); } data->nimages = 0; VIR_FREE(data->images); @@ -287,6 +289,7 @@ testQemuDiskXMLToProps(const void *opaque) } for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) { + g_autofree char *backingstore = NULL; if (testQemuDiskXMLToJSONFakeSecrets(n) < 0) return -1; @@ -298,7 +301,8 @@ testQemuDiskXMLToProps(const void *opaque) if (!(formatProps = qemuBlockStorageSourceGetBlockdevProps(n, n->backingStore)) || !(storageSrcOnlyProps = qemuBlockStorageSourceGetBackendProps(n, false, true, true)) || - !(storageProps = qemuBlockStorageSourceGetBackendProps(n, false, false, true))) { + !(storageProps = qemuBlockStorageSourceGetBackendProps(n, false, false, true)) || + !(backingstore = qemuBlockGetBackingStoreString(n, true))) { if (!data->fail) { VIR_TEST_VERBOSE("failed to generate qemu blockdev props"); return -1; @@ -314,6 +318,7 @@ testQemuDiskXMLToProps(const void *opaque) data->images[data->nimages].formatprops = g_steal_pointer(&formatProps); data->images[data->nimages].storageprops = g_steal_pointer(&storageProps); data->images[data->nimages].storagepropssrc = g_steal_pointer(&storageSrcOnlyProps); + data->images[data->nimages].backingstore = g_steal_pointer(&backingstore); data->nimages++; } @@ -425,10 +430,21 @@ testQemuDiskXMLToPropsValidateFileSrcOnly(const void *opaque) for (i = 0; i < data->nimages; i++) { g_autofree char *jsonstr = NULL; + virBufferAddLit(&buf, "(\n"); + virBufferAdjustIndent(&buf, 2); + virBufferAddLit(&buf, "source only properties:\n"); + if (!(jsonstr = virJSONValueToString(data->images[i].storagepropssrc, true))) return -1; - virBufferAdd(&buf, jsonstr, -1); + virBufferAddStr(&buf, jsonstr); + + virBufferAddLit(&buf, "backing store string:\n"); + virBufferAddStr(&buf, data->images[i].backingstore); + + virBufferTrim(&buf, "\n"); + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "\n)\n"); } actual = virBufferContentAndReset(&buf); diff --git a/tests/qemublocktestdata/xml2json/block-raw-noopts-srconly.json b/tests/qemublocktestdata/xml2json/block-raw-noopts-srconly.json index 72f9067353..07f7390433 100644 --- a/tests/qemublocktestdata/xml2json/block-raw-noopts-srconly.json +++ b/tests/qemublocktestdata/xml2json/block-raw-noopts-srconly.json @@ -1,4 +1,9 @@ -{ - "driver": "host_device", - "filename": "/dev/blah" -} +( + source only properties: + { + "driver": "host_device", + "filename": "/dev/blah" + } + backing store string: + /dev/blah +) diff --git a/tests/qemublocktestdata/xml2json/block-raw-reservations-srconly.json b/tests/qemublocktestdata/xml2json/block-raw-reservations-srconly.json index 72f9067353..07f7390433 100644 --- a/tests/qemublocktestdata/xml2json/block-raw-reservations-srconly.json +++ b/tests/qemublocktestdata/xml2json/block-raw-reservations-srconly.json @@ -1,4 +1,9 @@ -{ - "driver": "host_device", - "filename": "/dev/blah" -} +( + source only properties: + { + "driver": "host_device", + "filename": "/dev/blah" + } + backing store string: + /dev/blah +) diff --git a/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json b/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json index 6ec4f78d7b..8bc58fa033 100644 --- a/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json +++ b/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json @@ -1,5 +1,10 @@ -{ - "driver": "vvfat", - "dir": "/var/somefiles", - "floppy": false -} +( + source only properties: + { + "driver": "vvfat", + "dir": "/var/somefiles", + "floppy": false + } + backing store string: + /var/somefiles +) diff --git a/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json b/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json index 6b0388bc18..043b796435 100644 --- a/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json +++ b/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json @@ -1,5 +1,10 @@ -{ - "driver": "vvfat", - "dir": "/var/somefiles", - "floppy": true -} +( + source only properties: + { + "driver": "vvfat", + "dir": "/var/somefiles", + "floppy": true + } + backing store string: + /var/somefiles +) diff --git a/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json b/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json index 6ec4f78d7b..8bc58fa033 100644 --- a/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json +++ b/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json @@ -1,5 +1,10 @@ -{ - "driver": "vvfat", - "dir": "/var/somefiles", - "floppy": false -} +( + source only properties: + { + "driver": "vvfat", + "dir": "/var/somefiles", + "floppy": false + } + backing store string: + /var/somefiles +) diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads-srconly.json index ea490b0034..65a3773b97 100644 --- a/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads-srconly.json @@ -1,24 +1,44 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/a" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/b" -} -{ - "driver": "gluster", - "volume": "images", - "path": "c", - "server": [ - { - "type": "inet", - "host": "test.org", - "port": "24007" - } - ] -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/d" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/a" + } + backing store string: + /var/lib/libvirt/images/a +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/b" + } + backing store string: + /var/lib/libvirt/images/b +) +( + source only properties: + { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ] + } + backing store string: + gluster://test.org:24007/images/c +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/d" + } + backing store string: + /var/lib/libvirt/images/d +) diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync-srconly.json index ea490b0034..65a3773b97 100644 --- a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync-srconly.json @@ -1,24 +1,44 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/a" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/b" -} -{ - "driver": "gluster", - "volume": "images", - "path": "c", - "server": [ - { - "type": "inet", - "host": "test.org", - "port": "24007" - } - ] -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/d" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/a" + } + backing store string: + /var/lib/libvirt/images/a +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/b" + } + backing store string: + /var/lib/libvirt/images/b +) +( + source only properties: + { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ] + } + backing store string: + gluster://test.org:24007/images/c +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/d" + } + backing store string: + /var/lib/libvirt/images/d +) diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none-srconly.json index ea490b0034..65a3773b97 100644 --- a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none-srconly.json @@ -1,24 +1,44 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/a" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/b" -} -{ - "driver": "gluster", - "volume": "images", - "path": "c", - "server": [ - { - "type": "inet", - "host": "test.org", - "port": "24007" - } - ] -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/d" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/a" + } + backing store string: + /var/lib/libvirt/images/a +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/b" + } + backing store string: + /var/lib/libvirt/images/b +) +( + source only properties: + { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ] + } + backing store string: + gluster://test.org:24007/images/c +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/d" + } + backing store string: + /var/lib/libvirt/images/d +) diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe-srconly.json index ea490b0034..65a3773b97 100644 --- a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe-srconly.json @@ -1,24 +1,44 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/a" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/b" -} -{ - "driver": "gluster", - "volume": "images", - "path": "c", - "server": [ - { - "type": "inet", - "host": "test.org", - "port": "24007" - } - ] -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/d" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/a" + } + backing store string: + /var/lib/libvirt/images/a +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/b" + } + backing store string: + /var/lib/libvirt/images/b +) +( + source only properties: + { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ] + } + backing store string: + gluster://test.org:24007/images/c +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/d" + } + backing store string: + /var/lib/libvirt/images/d +) diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback-srconly.json index ea490b0034..65a3773b97 100644 --- a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback-srconly.json @@ -1,24 +1,44 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/a" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/b" -} -{ - "driver": "gluster", - "volume": "images", - "path": "c", - "server": [ - { - "type": "inet", - "host": "test.org", - "port": "24007" - } - ] -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/d" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/a" + } + backing store string: + /var/lib/libvirt/images/a +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/b" + } + backing store string: + /var/lib/libvirt/images/b +) +( + source only properties: + { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ] + } + backing store string: + gluster://test.org:24007/images/c +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/d" + } + backing store string: + /var/lib/libvirt/images/d +) diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough-srconly.json index ea490b0034..65a3773b97 100644 --- a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough-srconly.json @@ -1,24 +1,44 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/a" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/b" -} -{ - "driver": "gluster", - "volume": "images", - "path": "c", - "server": [ - { - "type": "inet", - "host": "test.org", - "port": "24007" - } - ] -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/d" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/a" + } + backing store string: + /var/lib/libvirt/images/a +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/b" + } + backing store string: + /var/lib/libvirt/images/b +) +( + source only properties: + { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ] + } + backing store string: + gluster://test.org:24007/images/c +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/d" + } + backing store string: + /var/lib/libvirt/images/d +) diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-detect-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-detect-srconly.json index ea490b0034..65a3773b97 100644 --- a/tests/qemublocktestdata/xml2json/file-backing_basic-detect-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-detect-srconly.json @@ -1,24 +1,44 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/a" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/b" -} -{ - "driver": "gluster", - "volume": "images", - "path": "c", - "server": [ - { - "type": "inet", - "host": "test.org", - "port": "24007" - } - ] -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/d" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/a" + } + backing store string: + /var/lib/libvirt/images/a +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/b" + } + backing store string: + /var/lib/libvirt/images/b +) +( + source only properties: + { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ] + } + backing store string: + gluster://test.org:24007/images/c +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/d" + } + backing store string: + /var/lib/libvirt/images/d +) diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-noopts-srconly.json index dbdf6e563b..35a8c3af37 100644 --- a/tests/qemublocktestdata/xml2json/file-backing_basic-noopts-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-noopts-srconly.json @@ -1,16 +1,36 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/a" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/b" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/c" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/d" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/a" + } + backing store string: + /var/lib/libvirt/images/a +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/b" + } + backing store string: + /var/lib/libvirt/images/b +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/c" + } + backing store string: + /var/lib/libvirt/images/c +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/d" + } + backing store string: + /var/lib/libvirt/images/d +) diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect-srconly.json index ea490b0034..65a3773b97 100644 --- a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect-srconly.json @@ -1,24 +1,44 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/a" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/b" -} -{ - "driver": "gluster", - "volume": "images", - "path": "c", - "server": [ - { - "type": "inet", - "host": "test.org", - "port": "24007" - } - ] -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/d" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/a" + } + backing store string: + /var/lib/libvirt/images/a +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/b" + } + backing store string: + /var/lib/libvirt/images/b +) +( + source only properties: + { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ] + } + backing store string: + gluster://test.org:24007/images/c +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/d" + } + backing store string: + /var/lib/libvirt/images/d +) diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore-srconly.json index ea490b0034..65a3773b97 100644 --- a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore-srconly.json @@ -1,24 +1,44 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/a" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/b" -} -{ - "driver": "gluster", - "volume": "images", - "path": "c", - "server": [ - { - "type": "inet", - "host": "test.org", - "port": "24007" - } - ] -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/d" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/a" + } + backing store string: + /var/lib/libvirt/images/a +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/b" + } + backing store string: + /var/lib/libvirt/images/b +) +( + source only properties: + { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ] + } + backing store string: + gluster://test.org:24007/images/c +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/d" + } + backing store string: + /var/lib/libvirt/images/d +) diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-srconly.json b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-srconly.json index ea490b0034..65a3773b97 100644 --- a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-srconly.json @@ -1,24 +1,44 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/a" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/b" -} -{ - "driver": "gluster", - "volume": "images", - "path": "c", - "server": [ - { - "type": "inet", - "host": "test.org", - "port": "24007" - } - ] -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/d" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/a" + } + backing store string: + /var/lib/libvirt/images/a +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/b" + } + backing store string: + /var/lib/libvirt/images/b +) +( + source only properties: + { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ] + } + backing store string: + gluster://test.org:24007/images/c +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/d" + } + backing store string: + /var/lib/libvirt/images/d +) diff --git a/tests/qemublocktestdata/xml2json/file-bochs-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-bochs-noopts-srconly.json index c50fa903f5..58dd7e1c34 100644 --- a/tests/qemublocktestdata/xml2json/file-bochs-noopts-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-bochs-noopts-srconly.json @@ -1,4 +1,9 @@ -{ - "driver": "file", - "filename": "/path/to/i.img" -} +( + source only properties: + { + "driver": "file", + "filename": "/path/to/i.img" + } + backing store string: + /path/to/i.img +) diff --git a/tests/qemublocktestdata/xml2json/file-cloop-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-cloop-noopts-srconly.json index c50fa903f5..58dd7e1c34 100644 --- a/tests/qemublocktestdata/xml2json/file-cloop-noopts-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-cloop-noopts-srconly.json @@ -1,4 +1,9 @@ -{ - "driver": "file", - "filename": "/path/to/i.img" -} +( + source only properties: + { + "driver": "file", + "filename": "/path/to/i.img" + } + backing store string: + /path/to/i.img +) diff --git a/tests/qemublocktestdata/xml2json/file-dmg-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-dmg-noopts-srconly.json index c50fa903f5..58dd7e1c34 100644 --- a/tests/qemublocktestdata/xml2json/file-dmg-noopts-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-dmg-noopts-srconly.json @@ -1,4 +1,9 @@ -{ - "driver": "file", - "filename": "/path/to/i.img" -} +( + source only properties: + { + "driver": "file", + "filename": "/path/to/i.img" + } + backing store string: + /path/to/i.img +) diff --git a/tests/qemublocktestdata/xml2json/file-ploop-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-ploop-noopts-srconly.json index c50fa903f5..58dd7e1c34 100644 --- a/tests/qemublocktestdata/xml2json/file-ploop-noopts-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-ploop-noopts-srconly.json @@ -1,4 +1,9 @@ -{ - "driver": "file", - "filename": "/path/to/i.img" -} +( + source only properties: + { + "driver": "file", + "filename": "/path/to/i.img" + } + backing store string: + /path/to/i.img +) diff --git a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption-srconly.json b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption-srconly.json index 316dbc9df2..29644f8c0f 100644 --- a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption-srconly.json @@ -1,8 +1,18 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/a" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/b" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/a" + } + backing store string: + /var/lib/libvirt/images/a +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/b" + } + backing store string: + /var/lib/libvirt/images/b +) diff --git a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts-srconly.json index d998acc194..7691609577 100644 --- a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts-srconly.json @@ -1,40 +1,90 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/rhel7.3.1507297895" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/rhel7.3.1484071872" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/rhel7.3.1483615252" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/rhel7.3.1483605924" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/rhel7.3.1483605920" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/rhel7.3.1483546244" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/rhel7.3.1483545901" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/rhel7.3.1483545313" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/rhel7.3.1483536402" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/rhel7.3.qcow2" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1507297895" + } + backing store string: + /var/lib/libvirt/images/rhel7.3.1507297895 +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1484071872" + } + backing store string: + /var/lib/libvirt/images/rhel7.3.1484071872 +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483615252" + } + backing store string: + /var/lib/libvirt/images/rhel7.3.1483615252 +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483605924" + } + backing store string: + /var/lib/libvirt/images/rhel7.3.1483605924 +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483605920" + } + backing store string: + /var/lib/libvirt/images/rhel7.3.1483605920 +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483546244" + } + backing store string: + /var/lib/libvirt/images/rhel7.3.1483546244 +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483545901" + } + backing store string: + /var/lib/libvirt/images/rhel7.3.1483545901 +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483545313" + } + backing store string: + /var/lib/libvirt/images/rhel7.3.1483545313 +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483536402" + } + backing store string: + /var/lib/libvirt/images/rhel7.3.1483536402 +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.qcow2" + } + backing store string: + /var/lib/libvirt/images/rhel7.3.qcow2 +) diff --git a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated-srconly.json b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated-srconly.json index e0bce3bcd2..f2fd81184b 100644 --- a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated-srconly.json @@ -1,8 +1,18 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/rhel7.3.1507297895" -} -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/rhel7.3.1484071872" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1507297895" + } + backing store string: + /var/lib/libvirt/images/rhel7.3.1507297895 +) +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1484071872" + } + backing store string: + /var/lib/libvirt/images/rhel7.3.1484071872 +) diff --git a/tests/qemublocktestdata/xml2json/file-raw-aio_native-srconly.json b/tests/qemublocktestdata/xml2json/file-raw-aio_native-srconly.json index c50fa903f5..58dd7e1c34 100644 --- a/tests/qemublocktestdata/xml2json/file-raw-aio_native-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-raw-aio_native-srconly.json @@ -1,4 +1,9 @@ -{ - "driver": "file", - "filename": "/path/to/i.img" -} +( + source only properties: + { + "driver": "file", + "filename": "/path/to/i.img" + } + backing store string: + /path/to/i.img +) diff --git a/tests/qemublocktestdata/xml2json/file-raw-luks-srconly.json b/tests/qemublocktestdata/xml2json/file-raw-luks-srconly.json index 6d7088211f..c065e3fab0 100644 --- a/tests/qemublocktestdata/xml2json/file-raw-luks-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-raw-luks-srconly.json @@ -1,4 +1,9 @@ -{ - "driver": "file", - "filename": "/path/luks.img" -} +( + source only properties: + { + "driver": "file", + "filename": "/path/luks.img" + } + backing store string: + /path/luks.img +) diff --git a/tests/qemublocktestdata/xml2json/file-raw-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-raw-noopts-srconly.json index bb3e8af9eb..a2b32b09e0 100644 --- a/tests/qemublocktestdata/xml2json/file-raw-noopts-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-raw-noopts-srconly.json @@ -1,4 +1,9 @@ -{ - "driver": "file", - "filename": "/var/lib/libvirt/images/i.img" -} +( + source only properties: + { + "driver": "file", + "filename": "/var/lib/libvirt/images/i.img" + } + backing store string: + /var/lib/libvirt/images/i.img +) diff --git a/tests/qemublocktestdata/xml2json/file-vdi-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-vdi-noopts-srconly.json index c50fa903f5..58dd7e1c34 100644 --- a/tests/qemublocktestdata/xml2json/file-vdi-noopts-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-vdi-noopts-srconly.json @@ -1,4 +1,9 @@ -{ - "driver": "file", - "filename": "/path/to/i.img" -} +( + source only properties: + { + "driver": "file", + "filename": "/path/to/i.img" + } + backing store string: + /path/to/i.img +) diff --git a/tests/qemublocktestdata/xml2json/file-vhd-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-vhd-noopts-srconly.json index c50fa903f5..58dd7e1c34 100644 --- a/tests/qemublocktestdata/xml2json/file-vhd-noopts-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-vhd-noopts-srconly.json @@ -1,4 +1,9 @@ -{ - "driver": "file", - "filename": "/path/to/i.img" -} +( + source only properties: + { + "driver": "file", + "filename": "/path/to/i.img" + } + backing store string: + /path/to/i.img +) diff --git a/tests/qemublocktestdata/xml2json/file-vpc-noopts-srconly.json b/tests/qemublocktestdata/xml2json/file-vpc-noopts-srconly.json index c50fa903f5..58dd7e1c34 100644 --- a/tests/qemublocktestdata/xml2json/file-vpc-noopts-srconly.json +++ b/tests/qemublocktestdata/xml2json/file-vpc-noopts-srconly.json @@ -1,4 +1,9 @@ -{ - "driver": "file", - "filename": "/path/to/i.img" -} +( + source only properties: + { + "driver": "file", + "filename": "/path/to/i.img" + } + backing store string: + /path/to/i.img +) diff --git a/tests/qemublocktestdata/xml2json/network-nbd-tls-srconly.json b/tests/qemublocktestdata/xml2json/network-nbd-tls-srconly.json index 455f4e5140..606e68713a 100644 --- a/tests/qemublocktestdata/xml2json/network-nbd-tls-srconly.json +++ b/tests/qemublocktestdata/xml2json/network-nbd-tls-srconly.json @@ -1,8 +1,13 @@ -{ - "driver": "nbd", - "server": { - "type": "inet", - "host": "host1.example.com", - "port": "10809" +( + source only properties: + { + "driver": "nbd", + "server": { + "type": "inet", + "host": "host1.example.com", + "port": "10809" + } } -} + backing store string: + nbd://host1.example.com:10809 +) diff --git a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json index 69ca9caf88..2d7eeb3bca 100644 --- a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json +++ b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json @@ -1,22 +1,46 @@ -{ - "driver": "rbd", - "pool": "rbdpool", - "image": "rbdimg", - "server": [ - { - "host": "host1.example.com", - "port": "0" - }, - { - "host": "host2.example.com", - "port": "0" - } - ] -} -{ - "driver": "iscsi", - "portal": "example.org:3260", - "target": "iscsitarget", - "lun": 1, - "transport": "tcp" -} +( + source only properties: + { + "driver": "rbd", + "pool": "rbdpool", + "image": "rbdimg", + "server": [ + { + "host": "host1.example.com", + "port": "0" + }, + { + "host": "host2.example.com", + "port": "0" + } + ] + } + backing store string: + json:{ + "driver": "rbd", + "pool": "rbdpool", + "image": "rbdimg", + "server": [ + { + "host": "host1.example.com", + "port": "0" + }, + { + "host": "host2.example.com", + "port": "0" + } + ] + } +) +( + source only properties: + { + "driver": "iscsi", + "portal": "example.org:3260", + "target": "iscsitarget", + "lun": 1, + "transport": "tcp" + } + backing store string: + iscsi://example.org:3260/iscsitarget/1 +) diff --git a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json index 6298329812..5679318fbe 100644 --- a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json +++ b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json @@ -1,22 +1,46 @@ -{ - "driver": "rbd", - "pool": "rbdpool", - "image": "rbdimg", - "server": [ - { - "host": "host1.example.com", - "port": "0" - }, - { - "host": "host2.example.com", - "port": "0" - } - ] -} -{ - "driver": "iscsi", - "portal": "example.org:3260", - "target": "iqn.2016-09.com.example:iscsitarget", - "lun": 1, - "transport": "tcp" -} +( + source only properties: + { + "driver": "rbd", + "pool": "rbdpool", + "image": "rbdimg", + "server": [ + { + "host": "host1.example.com", + "port": "0" + }, + { + "host": "host2.example.com", + "port": "0" + } + ] + } + backing store string: + json:{ + "driver": "rbd", + "pool": "rbdpool", + "image": "rbdimg", + "server": [ + { + "host": "host1.example.com", + "port": "0" + }, + { + "host": "host2.example.com", + "port": "0" + } + ] + } +) +( + source only properties: + { + "driver": "iscsi", + "portal": "example.org:3260", + "target": "iqn.2016-09.com.example:iscsitarget", + "lun": 1, + "transport": "tcp" + } + backing store string: + iscsi://example.org:3260/iqn.2016-09.com.example%3Aiscsitarget/1 +) diff --git a/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json b/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json index ed55c08cbf..970e1bb8af 100644 --- a/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json +++ b/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json @@ -1,5 +1,14 @@ -{ - "driver": "nvme", - "device": "0000:01:00.0", - "namespace": 1 -} +( + source only properties: + { + "driver": "nvme", + "device": "0000:01:00.0", + "namespace": 1 + } + backing store string: + json:{ + "driver": "nvme", + "device": "0000:01:00.0", + "namespace": 1 + } +) -- 2.24.1

We can return the appropriate string directly. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index d6cc999a43..b7c3ba7530 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -2043,13 +2043,10 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src, virJSONValuePtr props = NULL; g_autoptr(virURI) uri = NULL; g_autofree char *backingJSON = NULL; - char *ret = NULL; if (!src->sliceStorage) { - if (virStorageSourceIsLocalStorage(src)) { - ret = g_strdup(src->path); - return ret; - } + if (virStorageSourceIsLocalStorage(src)) + return g_strdup(src->path); /* generate simplified URIs for the easy cases */ if (actualType == VIR_STORAGE_TYPE_NETWORK && @@ -2068,10 +2065,7 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src, if (!(uri = qemuBlockStorageSourceGetURI(src))) return NULL; - if (!(ret = virURIFormat(uri))) - return NULL; - - return ret; + return virURIFormat(uri); case VIR_STORAGE_NET_PROTOCOL_SHEEPDOG: case VIR_STORAGE_NET_PROTOCOL_RBD: @@ -2105,9 +2099,7 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src, if (!(backingJSON = virJSONValueToString(props, pretty))) return NULL; - ret = g_strdup_printf("json:%s", backingJSON); - - return ret; + return g_strdup_printf("json:%s", backingJSON); } -- 2.24.1

qemublocktest showed that we don't add the "fat:" prefix for directory storage when formatting the backing store string. While it's unlikely to be used it's simple enough to actually implement the support rather than trying to forbid it. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 7 ++++++- src/util/virstoragefile.c | 9 +++++++++ .../xml2json/dir-fat-cache-srconly.json | 2 +- .../xml2json/dir-fat-floppy-srconly.json | 2 +- .../xml2json/dir-fat-readonly-srconly.json | 2 +- tests/virstoragetest.c | 1 + 6 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index b7c3ba7530..a44cfeb99c 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -2045,8 +2045,13 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src, g_autofree char *backingJSON = NULL; if (!src->sliceStorage) { - if (virStorageSourceIsLocalStorage(src)) + if (virStorageSourceIsLocalStorage(src)) { + if (src->type == VIR_STORAGE_TYPE_DIR && + src->format == VIR_STORAGE_FILE_FAT) + return g_strdup_printf("fat:%s", src->path); + return g_strdup(src->path); + } /* generate simplified URIs for the easy cases */ if (actualType == VIR_STORAGE_TYPE_NETWORK && diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index ca39391379..fa04ff74e1 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -3922,6 +3922,7 @@ virStorageSourceNewFromBackingAbsolute(const char *path, virStorageSourcePtr *src) { const char *json; + const char *dirpath; int rc = 0; g_autoptr(virStorageSource) def = NULL; @@ -3935,6 +3936,14 @@ virStorageSourceNewFromBackingAbsolute(const char *path, def->path = g_strdup(path); } else { + if ((dirpath = STRSKIP(path, "fat:"))) { + def->type = VIR_STORAGE_TYPE_DIR; + def->format = VIR_STORAGE_FILE_FAT; + def->path = g_strdup(dirpath); + *src = g_steal_pointer(&def); + return 0; + } + def->type = VIR_STORAGE_TYPE_NETWORK; VIR_DEBUG("parsing backing store string: '%s'", path); diff --git a/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json b/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json index 8bc58fa033..80f866f08b 100644 --- a/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json +++ b/tests/qemublocktestdata/xml2json/dir-fat-cache-srconly.json @@ -6,5 +6,5 @@ "floppy": false } backing store string: - /var/somefiles + fat:/var/somefiles ) diff --git a/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json b/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json index 043b796435..6c86f1da06 100644 --- a/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json +++ b/tests/qemublocktestdata/xml2json/dir-fat-floppy-srconly.json @@ -6,5 +6,5 @@ "floppy": true } backing store string: - /var/somefiles + fat:/var/somefiles ) diff --git a/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json b/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json index 8bc58fa033..80f866f08b 100644 --- a/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json +++ b/tests/qemublocktestdata/xml2json/dir-fat-readonly-srconly.json @@ -6,5 +6,5 @@ "floppy": false } backing store string: - /var/somefiles + fat:/var/somefiles ) diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c index 547118951e..209d0c37d3 100644 --- a/tests/virstoragetest.c +++ b/tests/virstoragetest.c @@ -1226,6 +1226,7 @@ mymain(void) TEST_BACKING_PARSE_FULL(bck, xml, 0) TEST_BACKING_PARSE("path", "<source file='path'/>\n"); + TEST_BACKING_PARSE("fat:/somedir", "<source dir='/somedir'/>\n"); TEST_BACKING_PARSE("://", NULL); TEST_BACKING_PARSE("http://example.com", "<source protocol='http' name=''>\n" -- 2.24.1

QEMU requires an extra wrapper object where only the "file" member is populated. This is basically a placeholder for establishing the format layer. We did the same in qemuDiskSourceGetProps for the old-school JSON usage with -drive but forgot to adopt this for -blockdev. https://bugzilla.redhat.com/show_bug.cgi?id=1804617 Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 2 +- .../imagecreate/qcow2-backing-qcow2-slice.json | 2 +- .../qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json | 2 +- .../network-qcow2-backing-chain-cache-unsafe-srconly.json | 3 ++- .../network-qcow2-backing-chain-encryption_auth-srconly.json | 3 ++- tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json | 3 ++- 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index a44cfeb99c..3365ee677b 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -2104,7 +2104,7 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src, if (!(backingJSON = virJSONValueToString(props, pretty))) return NULL; - return g_strdup_printf("json:%s", backingJSON); + return g_strdup_printf("json:{\"file\":%s}", backingJSON); } diff --git a/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.json b/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.json index 2fa27c1933..2526740b9a 100644 --- a/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.json +++ b/tests/qemublocktestdata/imagecreate/qcow2-backing-qcow2-slice.json @@ -10,6 +10,6 @@ format: "driver": "qcow2", "file": "0123456789ABCDEF0123456789ABCDE", "size": 8589934590, - "backing-file": "json:{\"driver\":\"raw\",\"offset\":1234,\"size\":5768,\"file\":{\"driver\":\"file\",\"filename\":\"/var/lib/libvirt/images/i.qcow2\"}}", + "backing-file": "json:{\"file\":{\"driver\":\"raw\",\"offset\":1234,\"size\":5768,\"file\":{\"driver\":\"file\",\"filename\":\"/var/lib/libvirt/images/i.qcow2\"}}}", "backing-fmt": "qcow2" } diff --git a/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json b/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json index 761002afd9..e76221da16 100644 --- a/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json +++ b/tests/qemublocktestdata/imagecreate/qcow2-backing-raw-slice.json @@ -10,6 +10,6 @@ format: "driver": "qcow2", "file": "0123456789ABCDEF0123456789ABCDE", "size": 8589934590, - "backing-file": "json:{\"driver\":\"raw\",\"offset\":9876,\"size\":54321,\"file\":{\"driver\":\"file\",\"filename\":\"/var/lib/libvirt/images/i.img\"}}", + "backing-file": "json:{\"file\":{\"driver\":\"raw\",\"offset\":9876,\"size\":54321,\"file\":{\"driver\":\"file\",\"filename\":\"/var/lib/libvirt/images/i.img\"}}}", "backing-fmt": "raw" } diff --git a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json index 2d7eeb3bca..0fb0b8eff9 100644 --- a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json +++ b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe-srconly.json @@ -16,7 +16,7 @@ ] } backing store string: - json:{ + json:{"file":{ "driver": "rbd", "pool": "rbdpool", "image": "rbdimg", @@ -31,6 +31,7 @@ } ] } + } ) ( source only properties: diff --git a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json index 5679318fbe..777a372471 100644 --- a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json +++ b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth-srconly.json @@ -16,7 +16,7 @@ ] } backing store string: - json:{ + json:{"file":{ "driver": "rbd", "pool": "rbdpool", "image": "rbdimg", @@ -31,6 +31,7 @@ } ] } + } ) ( source only properties: diff --git a/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json b/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json index 970e1bb8af..26f9557c80 100644 --- a/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json +++ b/tests/qemublocktestdata/xml2json/nvme-raw-noopts-srconly.json @@ -6,9 +6,10 @@ "namespace": 1 } backing store string: - json:{ + json:{"file":{ "driver": "nvme", "device": "0000:01:00.0", "namespace": 1 } + } ) -- 2.24.1

Introduce qemuBlockStorageSourceGetCookieString which does the concatenation so that we can reuse it later. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 25 +++++++++++++++++++++++++ src/qemu/qemu_block.h | 3 +++ src/qemu/qemu_domain.c | 13 +------------ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 3365ee677b..d9665ec4a0 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -3343,3 +3343,28 @@ qemuBlockStorageSourceNeedsStorageSliceLayer(const virStorageSource *src) return false; } + + +/** + * qemuBlockStorageSourceGetCookieString: + * @src: storage source + * + * Returns a properly formatted string representing cookies of @src in format + * accepted by qemu. + */ +char * +qemuBlockStorageSourceGetCookieString(virStorageSourcePtr src) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + size_t i; + + for (i = 0; i < src->ncookies; i++) { + virStorageNetCookieDefPtr cookie = src->cookies[i]; + + virBufferAsprintf(&buf, "%s=%s; ", cookie->name, cookie->value); + } + + virBufferTrim(&buf, "; "); + + return virBufferContentAndReset(&buf); +} diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index 9bffe20bfb..8b57ffd8a5 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -258,3 +258,6 @@ qemuBlockReopenReadOnly(virDomainObjPtr vm, bool qemuBlockStorageSourceNeedsStorageSliceLayer(const virStorageSource *src); + +char * +qemuBlockStorageSourceGetCookieString(virStorageSourcePtr src); diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 9cff36cb77..b55765c8ee 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1747,18 +1747,7 @@ qemuDomainSecretStorageSourcePrepareCookies(qemuDomainObjPrivatePtr priv, const char *aliasprotocol) { g_autofree char *secretalias = qemuAliasForSecret(aliasprotocol, "httpcookie"); - g_autofree char *cookies = NULL; - g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; - size_t i; - - for (i = 0; i < src->ncookies; i++) { - virStorageNetCookieDefPtr cookie = src->cookies[i]; - - virBufferAsprintf(&buf, "%s=%s; ", cookie->name, cookie->value); - } - - virBufferTrim(&buf, "; "); - cookies = virBufferContentAndReset(&buf); + g_autofree char *cookies = qemuBlockStorageSourceGetCookieString(src); return qemuDomainSecretAESSetup(priv, secretalias, NULL, (uint8_t *) cookies, strlen(cookies)); -- 2.24.1

Format cookies into the backing store string without encryption as they will not be visible on the command line when formatting a 'target' only string. In cases when cookies or other options are used we must use the JSON format rather than pure URI. Add tests to validate the scenario. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 12 ++++++++++- tests/qemublocktest.c | 2 ++ .../network-http-curlopts-srconly.json | 17 ++++++++++++++++ .../xml2json/network-http-curlopts.json | 15 ++++++++++++++ .../xml2json/network-http-curlopts.xml | 20 +++++++++++++++++++ .../xml2json/network-http-noopts-srconly.json | 9 +++++++++ .../xml2json/network-http-noopts.json | 14 +++++++++++++ .../xml2json/network-http-noopts.xml | 15 ++++++++++++++ 8 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 tests/qemublocktestdata/xml2json/network-http-curlopts-srconly.json create mode 100644 tests/qemublocktestdata/xml2json/network-http-curlopts.json create mode 100644 tests/qemublocktestdata/xml2json/network-http-curlopts.xml create mode 100644 tests/qemublocktestdata/xml2json/network-http-noopts-srconly.json create mode 100644 tests/qemublocktestdata/xml2json/network-http-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/network-http-noopts.xml diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index d9665ec4a0..648c3f1026 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -685,6 +685,7 @@ qemuBlockStorageSourceGetCURLProps(virStorageSourcePtr src, virJSONValuePtr ret = NULL; g_autoptr(virURI) uri = NULL; g_autofree char *uristr = NULL; + g_autofree char *cookiestr = NULL; /** * Common options: @@ -714,6 +715,9 @@ qemuBlockStorageSourceGetCURLProps(virStorageSourcePtr src, if (srcPriv && srcPriv->httpcookie) cookiealias = srcPriv->httpcookie->s.aes.alias; + } else { + /* format target string along with cookies */ + cookiestr = qemuBlockStorageSourceGetCookieString(src); } ignore_value(virJSONValueObjectCreate(&ret, @@ -721,6 +725,7 @@ qemuBlockStorageSourceGetCURLProps(virStorageSourcePtr src, "S:username", username, "S:password-secret", passwordalias, "T:sslverify", src->sslverify, + "S:cookie", cookiestr, "S:cookie-secret", cookiealias, "P:timeout", src->timeout, "P:readahead", src->readahead, @@ -2056,7 +2061,12 @@ qemuBlockGetBackingStoreString(virStorageSourcePtr src, /* generate simplified URIs for the easy cases */ if (actualType == VIR_STORAGE_TYPE_NETWORK && src->nhosts == 1 && - src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP) { + src->hosts->transport == VIR_STORAGE_NET_HOST_TRANS_TCP && + src->timeout == 0 && + src->ncookies == 0 && + src->sslverify == VIR_TRISTATE_BOOL_ABSENT && + src->timeout == 0 && + src->readahead == 0) { switch ((virStorageNetProtocol) src->protocol) { case VIR_STORAGE_NET_PROTOCOL_NBD: diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 709d94fd80..8640b72116 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1212,6 +1212,8 @@ mymain(void) TEST_DISK_TO_JSON("network-qcow2-backing-chain-cache-unsafe"); TEST_DISK_TO_JSON("dir-fat-cache"); TEST_DISK_TO_JSON("network-nbd-tls"); + TEST_DISK_TO_JSON("network-http-noopts"); + TEST_DISK_TO_JSON("network-http-curlopts"); TEST_DISK_TO_JSON("block-raw-noopts"); TEST_DISK_TO_JSON("block-raw-reservations"); diff --git a/tests/qemublocktestdata/xml2json/network-http-curlopts-srconly.json b/tests/qemublocktestdata/xml2json/network-http-curlopts-srconly.json new file mode 100644 index 0000000000..f5645ac2a6 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/network-http-curlopts-srconly.json @@ -0,0 +1,17 @@ +( + source only properties: + { + "driver": "https", + "url": "https://host1.example.com:443/something", + "sslverify": false, + "cookie": "test=123456; blurb=here" + } + backing store string: + json:{"file":{ + "driver": "https", + "url": "https://host1.example.com:443/something", + "sslverify": false, + "cookie": "test=123456; blurb=here" + } + } +) diff --git a/tests/qemublocktestdata/xml2json/network-http-curlopts.json b/tests/qemublocktestdata/xml2json/network-http-curlopts.json new file mode 100644 index 0000000000..08dfd1b300 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/network-http-curlopts.json @@ -0,0 +1,15 @@ +{ + "node-name": "node-b-f", + "read-only": false, + "driver": "qcow2", + "file": "node-a-s", + "backing": null +} +{ + "driver": "https", + "url": "https://host1.example.com:443/something", + "sslverify": false, + "node-name": "node-a-s", + "auto-read-only": true, + "discard": "unmap" +} diff --git a/tests/qemublocktestdata/xml2json/network-http-curlopts.xml b/tests/qemublocktestdata/xml2json/network-http-curlopts.xml new file mode 100644 index 0000000000..a656247e2e --- /dev/null +++ b/tests/qemublocktestdata/xml2json/network-http-curlopts.xml @@ -0,0 +1,20 @@ +<disk type='network' device='disk'> + <driver name='qemu' type='qcow2'/> + <source protocol='https' name='/something'> + <host name='host1.example.com'/> + <ssl verify='no'/> + <cookies> + <cookie name='test'>123456</cookie> + <cookie name='blurb'>here</cookie> + </cookies> + <privateData> + <nodenames> + <nodename type='storage' name='node-a-s'/> + <nodename type='format' name='node-b-f'/> + </nodenames> + </privateData> + </source> + <backingStore/> + <target dev='vda' bus='virtio'/> + <alias name='virtio-disk0'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/network-http-noopts-srconly.json b/tests/qemublocktestdata/xml2json/network-http-noopts-srconly.json new file mode 100644 index 0000000000..1303623036 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/network-http-noopts-srconly.json @@ -0,0 +1,9 @@ +( + source only properties: + { + "driver": "https", + "url": "https://host1.example.com:443/something" + } + backing store string: + https://host1.example.com:443/something +) diff --git a/tests/qemublocktestdata/xml2json/network-http-noopts.json b/tests/qemublocktestdata/xml2json/network-http-noopts.json new file mode 100644 index 0000000000..d577858236 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/network-http-noopts.json @@ -0,0 +1,14 @@ +{ + "node-name": "node-b-f", + "read-only": false, + "driver": "qcow2", + "file": "node-a-s", + "backing": null +} +{ + "driver": "https", + "url": "https://host1.example.com:443/something", + "node-name": "node-a-s", + "auto-read-only": true, + "discard": "unmap" +} diff --git a/tests/qemublocktestdata/xml2json/network-http-noopts.xml b/tests/qemublocktestdata/xml2json/network-http-noopts.xml new file mode 100644 index 0000000000..f09ff7ba67 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/network-http-noopts.xml @@ -0,0 +1,15 @@ +<disk type='network' device='disk'> + <driver name='qemu' type='qcow2'/> + <source protocol='https' name='/something'> + <host name='host1.example.com'/> + <privateData> + <nodenames> + <nodename type='storage' name='node-a-s'/> + <nodename type='format' name='node-b-f'/> + </nodenames> + </privateData> + </source> + <backingStore/> + <target dev='vda' bus='virtio'/> + <alias name='virtio-disk0'/> +</disk> -- 2.24.1

Our code allows snapshots of NVMe based disks which means we create overlay file with a 'json:{}' pseudo-uri refering to the NVME device. Our parser code doesn't handle them though. Add the parser and test it via the XML->json->XML round-trip and reference data. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/util/virstoragefile.c | 30 ++++++++++++++++++++++++++++++ tests/qemublocktest.c | 5 +++++ tests/virstoragetest.c | 9 +++++++++ 3 files changed, 44 insertions(+) diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index fa04ff74e1..d81ed70a97 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -3806,6 +3806,35 @@ virStorageSourceParseBackingJSONVxHS(virStorageSourcePtr src, } +static int +virStorageSourceParseBackingJSONNVMe(virStorageSourcePtr src, + virJSONValuePtr json, + const char *jsonstr G_GNUC_UNUSED, + int opaque G_GNUC_UNUSED) +{ + g_autoptr(virStorageSourceNVMeDef) nvme = g_new0(virStorageSourceNVMeDef, 1); + const char *device = virJSONValueObjectGetString(json, "device"); + + if (!device || virPCIDeviceAddressParse((char *) device, &nvme->pciAddr) < 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing or malformed 'device' field of 'nvme' storage")); + return -1; + } + + if (virJSONValueObjectGetNumberUlong(json, "namespace", &nvme->namespc) < 0 || + nvme->namespc == 0) { + virReportError(VIR_ERR_INVALID_ARG, "%s", + _("missing or malformed 'namespace' field of 'nvme' storage")); + return -1; + } + + src->type = VIR_STORAGE_TYPE_NVME; + src->nvme = g_steal_pointer(&nvme); + + return 0; +} + + struct virStorageSourceJSONDriverParser { const char *drvname; bool formatdriver; @@ -3837,6 +3866,7 @@ static const struct virStorageSourceJSONDriverParser jsonParsers[] = { {"rbd", false, virStorageSourceParseBackingJSONRBD, 0}, {"raw", true, virStorageSourceParseBackingJSONRaw, 0}, {"vxhs", false, virStorageSourceParseBackingJSONVxHS, 0}, + {"nvme", false, virStorageSourceParseBackingJSONNVMe, 0}, }; diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 8640b72116..124eaea752 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -1096,6 +1096,11 @@ mymain(void) /* type VIR_STORAGE_TYPE_BLOCK is not tested since it parses back to 'file' */ /* type VIR_STORAGE_TYPE_DIR it is a 'format' driver in qemu */ + TEST_JSON_FORMAT(VIR_STORAGE_TYPE_NVME, + "<source type='pci' namespace='1'>\n" + " <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>\n" + "</source>\n"); + TEST_JSON_FORMAT_NET("<source protocol='http' name=''>\n" " <host name='example.com' port='80'/>\n" "</source>\n"); diff --git a/tests/virstoragetest.c b/tests/virstoragetest.c index 209d0c37d3..10d5421150 100644 --- a/tests/virstoragetest.c +++ b/tests/virstoragetest.c @@ -1656,6 +1656,15 @@ mymain(void) " <timeout seconds='2000'/>\n" "</source>\n", 0); + TEST_BACKING_PARSE("json:{\"file\":{\"driver\": \"nvme\"," + "\"device\": \"0000:01:00.0\"," + "\"namespace\": 1" + "}" + "}", + "<source type='pci' namespace='1'>\n" + " <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>\n" + "</source>\n"); + #endif /* WITH_YAJL */ cleanup: -- 2.24.1
participants (2)
-
Michal Prívozník
-
Peter Krempa