[libvirt] [RFC PATCH 00/30] qemu: Add generators and tests for format block node layers (blockdev-add saga)

To adopt -blockdev we will need to fully convert virStorageSource into the format accepted by qemu. This series adds the format layer (qcow2/raw/etc ...) since the protocol layer is already implemented. The goal is that we do the equivalent thing with blockdev to what we did with -drive. This series also adds a lot of tests to make sure that we generate the right things. Note that this series is also a precursor to the NBD+TLS migration series, although only a small part of the code will be excercised. Please have a look at the tests. I've anotated them by putting the equivalent command line which would be used by libvirt into the commit message. Note that I've been looking at those JSON snippets for such a long time that I probably stopped being able to see any differences. Kevin, please look whether the configurations make sense (specifically I'm not really sure about patch 14/30, but that resulted from my poking in qemu.). All JSON documents were validated according to the qemu schema. The only known missing piece is the ability to use authentication with RBD, since that is missing from qemu. Peter Krempa (30): storage: Properly track that backing chain members are readonly qemu: domain: Format storage source node names into private data util: storage: Add shadow copies of few disk properties to virStorageSource qemu: domain: Carefuly transfer configuration from disk to storage source qemu: block: Extract formatting of props for 'file' backend qemu: block: Handle iomode property for json 'file' driver utils: storage: Mark that a virStorageSource is going to be used as a floppy qemu: Move virtual FAT disk validation from command line builder qemu: block: Add support for accessing directories via the 'vvfat' driver qemu: block: Propagate 'legacy' parameter when formatting disk backing qemu: block: Validate node-names for use with qemu qemu: block: Format cache modes for disk storage backends qemu: block: Format 'read-only' attribute for JSON disk protocol [RFC] qemu: block: Always set discard for storage nodes qemu: block: Add support for creating 'format' layer for blockdev-add tests: qemublock: Rename variables in anticipation of new tests tests: Makefile: Sanitize entry for qemublocktest qemu: domain: Export qemuDomainDeviceDefValidateDisk qemu: domain: Tolerate NULL 'cfg' in qemuDomainPrepareDiskSourceChain tests: qemublock: Add testing of blockdev JSON property generator tests: qemublock: Add basic 'raw' file test tests: qemublock: Add tests for all other format without special options tests: qemublock: Add tests for basic backing chain formats tests: qemublock: Add test-case for the 'vvfat' driver in qemu tests: qemublock: Add test cases for 'aio' options of 'file' storage tests: qemublock: Add test for raw luks disk format tests: qemublock: basic qcow2 tests tests: qemublock: Add test combining authentication and encryption tests: qemublock: Test handling of 'unmap' and 'detect-zeroes' options tests: qemublock: Test handling of all cache modes src/conf/domain_conf.c | 3 + src/qemu/qemu_block.c | 422 ++++++++++++++++++++- src/qemu/qemu_block.h | 6 +- src/qemu/qemu_command.c | 16 +- src/qemu/qemu_domain.c | 53 ++- src/qemu/qemu_domain.h | 3 + src/qemu/qemu_driver.c | 3 + src/util/virstoragefile.c | 5 + src/util/virstoragefile.h | 11 + tests/Makefile.am | 11 +- tests/qemublocktest.c | 312 ++++++++++++++- .../qemublocktestdata/xml2json/dir-fat-cache.json | 22 ++ tests/qemublocktestdata/xml2json/dir-fat-cache.xml | 10 + .../qemublocktestdata/xml2json/dir-fat-floppy.json | 14 + .../qemublocktestdata/xml2json/dir-fat-floppy.xml | 11 + .../xml2json/dir-fat-readonly.json | 14 + .../xml2json/dir-fat-readonly.xml | 10 + .../xml2json/file-backing_basic-aio_threads.json | 62 +++ .../xml2json/file-backing_basic-aio_threads.xml | 35 ++ .../file-backing_basic-cache-directsync.json | 91 +++++ .../file-backing_basic-cache-directsync.xml | 35 ++ .../xml2json/file-backing_basic-cache-none.json | 91 +++++ .../xml2json/file-backing_basic-cache-none.xml | 35 ++ .../xml2json/file-backing_basic-cache-unsafe.json | 91 +++++ .../xml2json/file-backing_basic-cache-unsafe.xml | 35 ++ .../file-backing_basic-cache-writeback.json | 91 +++++ .../file-backing_basic-cache-writeback.xml | 35 ++ .../file-backing_basic-cache-writethrough.json | 91 +++++ .../file-backing_basic-cache-writethrough.xml | 35 ++ .../xml2json/file-backing_basic-detect.json | 60 +++ .../xml2json/file-backing_basic-detect.xml | 35 ++ .../xml2json/file-backing_basic-noopts.json | 51 +++ .../xml2json/file-backing_basic-noopts.xml | 34 ++ .../xml2json/file-backing_basic-unmap-detect.json | 64 ++++ .../xml2json/file-backing_basic-unmap-detect.xml | 35 ++ .../xml2json/file-backing_basic-unmap-discard.json | 0 .../xml2json/file-backing_basic-unmap-ignore.json | 64 ++++ .../xml2json/file-backing_basic-unmap-ignore.xml | 35 ++ .../xml2json/file-backing_basic-unmap.json | 63 +++ .../xml2json/file-backing_basic-unmap.xml | 35 ++ .../xml2json/file-bochs-noopts.json | 12 + .../xml2json/file-bochs-noopts.xml | 9 + .../xml2json/file-cloop-noopts.json | 12 + .../xml2json/file-cloop-noopts.xml | 9 + .../xml2json/file-dmg-noopts.json | 12 + .../qemublocktestdata/xml2json/file-dmg-noopts.xml | 9 + .../xml2json/file-ploop-noopts.json | 12 + .../xml2json/file-ploop-noopts.xml | 9 + .../file-qcow2-backing-chain-encryption.json | 34 ++ .../file-qcow2-backing-chain-encryption.xml | 25 ++ .../xml2json/file-qcow2-backing-chain-noopts.json | 130 +++++++ .../xml2json/file-qcow2-backing-chain-noopts.xml | 83 ++++ .../file-qcow2-backing-chain-unterminated.json | 25 ++ .../file-qcow2-backing-chain-unterminated.xml | 18 + .../xml2json/file-raw-aio_native.json | 21 + .../xml2json/file-raw-aio_native.xml | 9 + .../qemublocktestdata/xml2json/file-raw-luks.json | 13 + tests/qemublocktestdata/xml2json/file-raw-luks.xml | 12 + .../xml2json/file-raw-noopts.json | 12 + .../qemublocktestdata/xml2json/file-raw-noopts.xml | 9 + .../xml2json/file-vdi-noopts.json | 12 + .../qemublocktestdata/xml2json/file-vdi-noopts.xml | 9 + .../xml2json/file-vhd-noopts.json | 12 + .../qemublocktestdata/xml2json/file-vhd-noopts.xml | 9 + .../xml2json/file-vpc-noopts.json | 12 + .../qemublocktestdata/xml2json/file-vpc-noopts.xml | 9 + .../network-qcow2-backing-chain-cache-unsafe.json | 57 +++ .../network-qcow2-backing-chain-cache-unsafe.xml | 25 ++ ...etwork-qcow2-backing-chain-encryption_auth.json | 51 +++ ...network-qcow2-backing-chain-encryption_auth.xml | 34 ++ .../xml2json/nodename-long-format.xml | 9 + .../xml2json/nodename-long-protocol.xml | 9 + 72 files changed, 2816 insertions(+), 36 deletions(-) create mode 100644 tests/qemublocktestdata/xml2json/dir-fat-cache.json create mode 100644 tests/qemublocktestdata/xml2json/dir-fat-cache.xml create mode 100644 tests/qemublocktestdata/xml2json/dir-fat-floppy.json create mode 100644 tests/qemublocktestdata/xml2json/dir-fat-floppy.xml create mode 100644 tests/qemublocktestdata/xml2json/dir-fat-readonly.json create mode 100644 tests/qemublocktestdata/xml2json/dir-fat-readonly.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-none.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-none.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-detect.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-detect.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap-discard.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap.xml create mode 100644 tests/qemublocktestdata/xml2json/file-bochs-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-bochs-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-cloop-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-cloop-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-dmg-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-dmg-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-ploop-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-ploop-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption.json create mode 100644 tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption.xml create mode 100644 tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated.json create mode 100644 tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated.xml create mode 100644 tests/qemublocktestdata/xml2json/file-raw-aio_native.json create mode 100644 tests/qemublocktestdata/xml2json/file-raw-aio_native.xml create mode 100644 tests/qemublocktestdata/xml2json/file-raw-luks.json create mode 100644 tests/qemublocktestdata/xml2json/file-raw-luks.xml create mode 100644 tests/qemublocktestdata/xml2json/file-raw-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-raw-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-vdi-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-vdi-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-vhd-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-vhd-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-vpc-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-vpc-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe.json create mode 100644 tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe.xml create mode 100644 tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth.json create mode 100644 tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth.xml create mode 100644 tests/qemublocktestdata/xml2json/nodename-long-format.xml create mode 100644 tests/qemublocktestdata/xml2json/nodename-long-protocol.xml -- 2.14.3

Everything besides the top of the chain is readonly. Track this when parsing the XML and detecting the chain from the disk. Also fix the state when taking snapshots. All other cases where the top image is changed already preserve the readonly state from the original image. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 3 +++ src/qemu/qemu_driver.c | 3 +++ src/util/virstoragefile.c | 1 + 3 files changed, 7 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 35666c1347..e2c10c7757 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -8711,6 +8711,9 @@ virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt, if (VIR_ALLOC(backingStore) < 0) goto cleanup; + /* backing store is always read-only */ + backingStore->readonly = true; + /* terminator does not have a type */ if (!(type = virXMLPropString(ctxt->node, "type"))) { VIR_STEAL_PTR(src->backingStore, backingStore); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 5673d9fd8d..d5374541e0 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -14671,6 +14671,9 @@ qemuDomainSnapshotUpdateDiskSources(qemuDomainSnapshotDiskDataPtr dd, if (dd->initialized) virStorageFileDeinit(dd->src); + /* the old disk image is now readonly */ + dd->disk->src->readonly = true; + VIR_STEAL_PTR(dd->disk->src->relPath, dd->relPath); VIR_STEAL_PTR(dd->src->backingStore, dd->disk->src); VIR_STEAL_PTR(dd->disk->src, dd->src); diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index 531540ac91..d6ad6e1d0f 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -3425,6 +3425,7 @@ virStorageSourceNewFromBacking(virStorageSourcePtr parent) if (virStorageSourceInitChainElement(ret, parent, true) < 0) goto error; + ret->readonly = true; ret->detected = true; } -- 2.14.3

Save and restore node names if we know them in the status XML so that we don't need to recalculate them or don't lose them in some cases. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e2a8450e2e..224b3b0478 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1934,6 +1934,9 @@ static int qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt, virStorageSourcePtr src) { + src->nodestorage = virXPathString("string(./nodename/@storage)", ctxt); + src->nodeformat = virXPathString("string(./nodename/@format)", ctxt); + if (virStorageSourcePrivateDataParseRelPath(ctxt, src) < 0) return -1; @@ -1945,6 +1948,15 @@ static int qemuStorageSourcePrivateDataFormat(virStorageSourcePtr src, virBufferPtr buf) { + if (src->nodestorage || src->nodeformat) { + virBufferAddLit(buf, "<nodename"); + if (src->nodestorage) + virBufferAsprintf(buf, " storage='%s'", src->nodestorage); + if (src->nodeformat) + virBufferAsprintf(buf, " format='%s'", src->nodeformat); + virBufferAddLit(buf, "/>\n"); + } + if (virStorageSourcePrivateDataFormatRelPath(src, buf) < 0) return -1; -- 2.14.3

Am 19.04.2018 um 17:24 hat Peter Krempa geschrieben:
Save and restore node names if we know them in the status XML so that we don't need to recalculate them or don't lose them in some cases.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e2a8450e2e..224b3b0478 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1934,6 +1934,9 @@ static int qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt, virStorageSourcePtr src) { + src->nodestorage = virXPathString("string(./nodename/@storage)", ctxt); + src->nodeformat = virXPathString("string(./nodename/@format)", ctxt); + if (virStorageSourcePrivateDataParseRelPath(ctxt, src) < 0) return -1;
This format doesn't look very future-proof. I can see that using x->nodestorage and x->nodeformat internally are probably easier for now, but while the assumption of exactly two layers (except for backing files) is probably correct for most cases, it will become less and less common the more we use filter drivers. Representing an arbitrary tree (or even non-tree graph) in the XML may be unpractical now, but please be aware that you'll probably need this change in the long run. Kevin

On Fri, Apr 20, 2018 at 09:30:16 +0200, Kevin Wolf wrote:
Am 19.04.2018 um 17:24 hat Peter Krempa geschrieben:
Save and restore node names if we know them in the status XML so that we don't need to recalculate them or don't lose them in some cases.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e2a8450e2e..224b3b0478 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1934,6 +1934,9 @@ static int qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt, virStorageSourcePtr src) { + src->nodestorage = virXPathString("string(./nodename/@storage)", ctxt); + src->nodeformat = virXPathString("string(./nodename/@format)", ctxt); + if (virStorageSourcePrivateDataParseRelPath(ctxt, src) < 0) return -1;
This format doesn't look very future-proof. I can see that using x->nodestorage and x->nodeformat internally are probably easier for now, but while the assumption of exactly two layers (except for backing files) is probably correct for most cases, it will become less and less common the more we use filter drivers.
Representing an arbitrary tree (or even non-tree graph) in the XML may be unpractical now, but please be aware that you'll probably need this change in the long run.
Yes. It will need to change e.g. if we allow IO throttling for other than the top layer. On the other hand it would be impractical to change to the topology qemu uses where a storage file is two layers minimum, so we will need to track everyting for one layer of XML. As the above uses attributes in the XML we can add an arbitrary amount of them if required.

Am 20.04.2018 um 09:45 hat Peter Krempa geschrieben:
On Fri, Apr 20, 2018 at 09:30:16 +0200, Kevin Wolf wrote:
Am 19.04.2018 um 17:24 hat Peter Krempa geschrieben:
Save and restore node names if we know them in the status XML so that we don't need to recalculate them or don't lose them in some cases.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e2a8450e2e..224b3b0478 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1934,6 +1934,9 @@ static int qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt, virStorageSourcePtr src) { + src->nodestorage = virXPathString("string(./nodename/@storage)", ctxt); + src->nodeformat = virXPathString("string(./nodename/@format)", ctxt); + if (virStorageSourcePrivateDataParseRelPath(ctxt, src) < 0) return -1;
This format doesn't look very future-proof. I can see that using x->nodestorage and x->nodeformat internally are probably easier for now, but while the assumption of exactly two layers (except for backing files) is probably correct for most cases, it will become less and less common the more we use filter drivers.
Representing an arbitrary tree (or even non-tree graph) in the XML may be unpractical now, but please be aware that you'll probably need this change in the long run.
Yes. It will need to change e.g. if we allow IO throttling for other than the top layer. On the other hand it would be impractical to change to the topology qemu uses where a storage file is two layers minimum, so we will need to track everyting for one layer of XML.
The two layers minimum is not correct as far as QEMU is concerned. A two-layer setup is what -drive creates by default if you don't specify a protocol driver as driver=... (or format=... for older versions) explicitly, but if you want, you can directly assign a 'file' node to a guest device without adding a format layer on top.
As the above uses attributes in the XML we can add an arbitrary amount of them if required.
Quorum takes an array of children, and VMDK needs a number of extents that depends on the image file, so attributes probably won't do. If we didn't have to consider compatibility, I think I'd choose something like: <child-nodes> <child-node name="file" ref="my-file-node" /> <child-node name="backing" ref="my-backing-node" /> </child-nodes> Kevin

On Fri, Apr 20, 2018 at 10:32:11 +0200, Kevin Wolf wrote:
Am 20.04.2018 um 09:45 hat Peter Krempa geschrieben:
On Fri, Apr 20, 2018 at 09:30:16 +0200, Kevin Wolf wrote:
Am 19.04.2018 um 17:24 hat Peter Krempa geschrieben:
Save and restore node names if we know them in the status XML so that we don't need to recalculate them or don't lose them in some cases.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e2a8450e2e..224b3b0478 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1934,6 +1934,9 @@ static int qemuStorageSourcePrivateDataParse(xmlXPathContextPtr ctxt, virStorageSourcePtr src) { + src->nodestorage = virXPathString("string(./nodename/@storage)", ctxt); + src->nodeformat = virXPathString("string(./nodename/@format)", ctxt); + if (virStorageSourcePrivateDataParseRelPath(ctxt, src) < 0) return -1;
This format doesn't look very future-proof. I can see that using x->nodestorage and x->nodeformat internally are probably easier for now, but while the assumption of exactly two layers (except for backing files) is probably correct for most cases, it will become less and less common the more we use filter drivers.
Representing an arbitrary tree (or even non-tree graph) in the XML may be unpractical now, but please be aware that you'll probably need this change in the long run.
Yes. It will need to change e.g. if we allow IO throttling for other than the top layer. On the other hand it would be impractical to change to the topology qemu uses where a storage file is two layers minimum, so we will need to track everyting for one layer of XML.
The two layers minimum is not correct as far as QEMU is concerned. A two-layer setup is what -drive creates by default if you don't specify a protocol driver as driver=... (or format=... for older versions) explicitly, but if you want, you can directly assign a 'file' node to a guest device without adding a format layer on top.
As the above uses attributes in the XML we can add an arbitrary amount of them if required.
Quorum takes an array of children, and VMDK needs a number of extents that depends on the image file, so attributes probably won't do. If
Adding support for quorum will not be much fun for the poor soul having to do it since the XML design will be very hard to do. The problem is in the fact that the <disk> element contains few things related to the source image outside of the <source> tag.
we didn't have to consider compatibility, I think I'd choose something like:
Well this is private data, so as long as we add a compatibility layer with the old format we can change it anytime we want. I'll try to use a more modular approach though in the next version.
<child-nodes> <child-node name="file" ref="my-file-node" /> <child-node name="backing" ref="my-backing-node" /> </child-nodes>
Kevin

Few things which are currently stored the virDomainDiskDef structure are actually relevant for the storage source as well. Add the fields with a note that they are just mirror of the values from the disk. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/util/virstoragefile.c | 4 ++++ src/util/virstoragefile.h | 8 ++++++++ 2 files changed, 12 insertions(+) diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c index d6ad6e1d0f..72584404da 100644 --- a/src/util/virstoragefile.c +++ b/src/util/virstoragefile.c @@ -2042,6 +2042,10 @@ virStorageSourceCopy(const virStorageSource *src, ret->detected = src->detected; ret->debugLevel = src->debugLevel; ret->debug = src->debug; + ret->iomode = src->iomode; + ret->cachemode = src->cachemode; + ret->discard = src->discard; + ret->detect_zeroes = src->detect_zeroes; /* storage driver metadata are not copied */ ret->drv = NULL; diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index d129e81978..b450da55ae 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -305,6 +305,14 @@ struct _virStorageSource { unsigned int debugLevel; bool debug; + + /* Libvirt currently stores the following properities in virDomainDiskDef. + * These instances are currently just copies from the parent definition and + * are not mapped back to the XML */ + int iomode; /* enum virDomainDiskIo */ + int cachemode; /* enum virDomainDiskCache */ + int discard; /* enum virDomainDiskDiscard */ + int detect_zeroes; /* enum virDomainDiskDetectZeroes */ }; -- 2.14.3

Some properties don't make sense to be configured for every single layer of the backing chain, but to avoid needing to pass the disk structure we will copy them to the individual virStorageSource-s Zero detection is applied only for the top layer image, while caching and iomode for all layers. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 224b3b0478..288bdb86ad 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11833,6 +11833,9 @@ qemuDomainPrepareDiskSourceChain(virDomainDiskDefPtr disk, if (!src) src = disk->src; + /* transfer properties valid only for the top level image */ + src->detect_zeroes = disk->detect_zeroes; + for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) { if (n->type == VIR_STORAGE_TYPE_NETWORK && n->protocol == VIR_STORAGE_NET_PROTOCOL_GLUSTER && @@ -11843,6 +11846,11 @@ qemuDomainPrepareDiskSourceChain(virDomainDiskDefPtr disk, if (qemuDomainValidateStorageSource(n, qemuCaps) < 0) return -1; + + /* transfer properties valid for the full chain */ + n->iomode = disk->iomode; + n->cachemode = disk->cachemode; + n->discard = disk->discard; } return 0; -- 2.14.3

'file' backend in qemu supports few more options than the current implementation. Extract it so that changes don't pollute the code. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index c0cf6a95ad..e7bd6c909d 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -974,6 +974,18 @@ qemuBlockStorageSourceGetSshProps(virStorageSourcePtr src) } +static virJSONValuePtr +qemuBlockStorageSourceGetFileProps(virStorageSourcePtr src) +{ + virJSONValuePtr ret = NULL; + + ignore_value(virJSONValueObjectCreate(&ret, + "s:driver", "file", + "s:filename", src->path, NULL) < 0); + return ret; +} + + /** * qemuBlockStorageSourceGetBackendProps: * @src: disk source @@ -991,9 +1003,7 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src) case VIR_STORAGE_TYPE_BLOCK: case VIR_STORAGE_TYPE_FILE: case VIR_STORAGE_TYPE_DIR: - if (virJSONValueObjectCreate(&fileprops, - "s:driver", "file", - "s:filename", src->path, NULL) < 0) + if (!(fileprops = qemuBlockStorageSourceGetFileProps(src))) return NULL; break; -- 2.14.3

Am 19.04.2018 um 17:25 hat Peter Krempa geschrieben:
'file' backend in qemu supports few more options than the current implementation. Extract it so that changes don't pollute the code.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index c0cf6a95ad..e7bd6c909d 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -974,6 +974,18 @@ qemuBlockStorageSourceGetSshProps(virStorageSourcePtr src) }
+static virJSONValuePtr +qemuBlockStorageSourceGetFileProps(virStorageSourcePtr src) +{ + virJSONValuePtr ret = NULL; + + ignore_value(virJSONValueObjectCreate(&ret, + "s:driver", "file", + "s:filename", src->path, NULL) < 0); + return ret; +} + + /** * qemuBlockStorageSourceGetBackendProps: * @src: disk source @@ -991,9 +1003,7 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src) case VIR_STORAGE_TYPE_BLOCK: case VIR_STORAGE_TYPE_FILE: case VIR_STORAGE_TYPE_DIR: - if (virJSONValueObjectCreate(&fileprops, - "s:driver", "file", - "s:filename", src->path, NULL) < 0) + if (!(fileprops = qemuBlockStorageSourceGetFileProps(src))) return NULL;
Preexisting, but I wonder whether 'driver': 'file' is correct for all these cases. I see that you handle _DIR separately with a vvfat function later in this series, but shouldn't _BLOCK be 'host_device' rather than 'file', too? Kevin

On Fri, Apr 20, 2018 at 09:45:40 +0200, Kevin Wolf wrote:
Am 19.04.2018 um 17:25 hat Peter Krempa geschrieben:
'file' backend in qemu supports few more options than the current implementation. Extract it so that changes don't pollute the code.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index c0cf6a95ad..e7bd6c909d 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -974,6 +974,18 @@ qemuBlockStorageSourceGetSshProps(virStorageSourcePtr src) }
+static virJSONValuePtr +qemuBlockStorageSourceGetFileProps(virStorageSourcePtr src) +{ + virJSONValuePtr ret = NULL; + + ignore_value(virJSONValueObjectCreate(&ret, + "s:driver", "file", + "s:filename", src->path, NULL) < 0); + return ret; +} + + /** * qemuBlockStorageSourceGetBackendProps: * @src: disk source @@ -991,9 +1003,7 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src) case VIR_STORAGE_TYPE_BLOCK: case VIR_STORAGE_TYPE_FILE: case VIR_STORAGE_TYPE_DIR: - if (virJSONValueObjectCreate(&fileprops, - "s:driver", "file", - "s:filename", src->path, NULL) < 0) + if (!(fileprops = qemuBlockStorageSourceGetFileProps(src))) return NULL;
Preexisting, but I wonder whether 'driver': 'file' is correct for all these cases. I see that you handle _DIR separately with a vvfat function later in this series, but shouldn't _BLOCK be 'host_device' rather than 'file', too?
It should. I just did not notice it. If I try the block storage now I get: { "iops_rd": 0, "detect_zeroes": "off", "image": { "virtual-size": 10737418240, "filename": "/dev/mapper/angien--storage-ble", "format": "host_device", "actual-size": 0, "dirty-flag": false }, "iops_wr": 0, "ro": false, "node-name": "#block093", "backing_file_depth": 0, "drv": "host_device", "iops": 0, "bps_wr": 0, "write_threshold": 0, "encrypted": true, "bps": 0, "bps_rd": 0, "cache": { "no-flush": false, "direct": true, "writeback": true }, "file": "/dev/mapper/angien--storage-ble", "encryption_key_missing": false } Is there a special need to use 'host_cdrom' explicitly if the CDROM drive is used? That would complicate things since we don't know when that will happen.

Am 20.04.2018 um 09:56 hat Peter Krempa geschrieben:
Is there a special need to use 'host_cdrom' explicitly if the CDROM drive is used? That would complicate things since we don't know when that will happen.
You don't get the full CD-ROM passthrough functionality with host_device. Specifically, if you eject the virtual drive, the physical drive will only be ejected with host_cdrom, and the same is true for lock_medium. I think we may also make an attempt at detecting physical media change ocassionally with host_cdrom, but I doubt that this is working reliably anyway (the driver function is .bdrv_is_inserted, so it would be polling rather than processing an event; and I'm not sure when it's called). Kevin

On Fri, Apr 20, 2018 at 10:41:50 +0200, Kevin Wolf wrote:
Am 20.04.2018 um 09:56 hat Peter Krempa geschrieben:
Is there a special need to use 'host_cdrom' explicitly if the CDROM drive is used? That would complicate things since we don't know when that will happen.
You don't get the full CD-ROM passthrough functionality with host_device. Specifically, if you eject the virtual drive, the physical drive will only be ejected with host_cdrom, and the same is true for lock_medium.
I think we may also make an attempt at detecting physical media change ocassionally with host_cdrom, but I doubt that this is working reliably anyway (the driver function is .bdrv_is_inserted, so it would be polling rather than processing an event; and I'm not sure when it's called).
Hmm, okay, it seems that we in fact should use it. Is there any drawback if host_cdrom is used with a device which is not a CDROM? (e.g. a logical volume containing the image?) Basically the question is whether we need to add some "smart" handling or we can just assume that if the guest device is a block-backed CDROM we can use that.

Am 20.04.2018 um 10:50 hat Peter Krempa geschrieben:
On Fri, Apr 20, 2018 at 10:41:50 +0200, Kevin Wolf wrote:
Am 20.04.2018 um 09:56 hat Peter Krempa geschrieben:
Is there a special need to use 'host_cdrom' explicitly if the CDROM drive is used? That would complicate things since we don't know when that will happen.
You don't get the full CD-ROM passthrough functionality with host_device. Specifically, if you eject the virtual drive, the physical drive will only be ejected with host_cdrom, and the same is true for lock_medium.
I think we may also make an attempt at detecting physical media change ocassionally with host_cdrom, but I doubt that this is working reliably anyway (the driver function is .bdrv_is_inserted, so it would be polling rather than processing an event; and I'm not sure when it's called).
Hmm, okay, it seems that we in fact should use it. Is there any drawback if host_cdrom is used with a device which is not a CDROM? (e.g. a logical volume containing the image?)
Basically the question is whether we need to add some "smart" handling or we can just assume that if the guest device is a block-backed CDROM we can use that.
Hm, looking at the code, it seems that failure is silently ignored in .bdrv_eject and .bdrv_lock_medium, but .bdrv_is_inserted is implemented like this: ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT); return ret == CDS_DISC_OK; Which probably means that a block device not supporting that ioctl won't be functional at all because the block layer will return -ENOMEDIUM almost everywhere. Kevin

Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index e7bd6c909d..6cf41cf544 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -977,11 +977,17 @@ qemuBlockStorageSourceGetSshProps(virStorageSourcePtr src) static virJSONValuePtr qemuBlockStorageSourceGetFileProps(virStorageSourcePtr src) { + const char *iomode = NULL; virJSONValuePtr ret = NULL; + if (src->iomode != VIR_DOMAIN_DISK_IO_DEFAULT) + iomode = virDomainDiskIoTypeToString(src->iomode); + ignore_value(virJSONValueObjectCreate(&ret, "s:driver", "file", - "s:filename", src->path, NULL) < 0); + "s:filename", src->path, + "S:aio", iomode, + NULL) < 0); return ret; } -- 2.14.3

Add a flag denoting that a virStorageSource is going to be used as a floppy image. This will be useful in cases where the user passes in files which shall be exposed as an image to the guest. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 3 +++ src/util/virstoragefile.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 288bdb86ad..6d7ab4ff80 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11851,6 +11851,9 @@ qemuDomainPrepareDiskSourceChain(virDomainDiskDefPtr disk, n->iomode = disk->iomode; n->cachemode = disk->cachemode; n->discard = disk->discard; + + if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) + n->floppyimg = true; } return 0; diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h index b450da55ae..57d39f98c2 100644 --- a/src/util/virstoragefile.h +++ b/src/util/virstoragefile.h @@ -313,6 +313,9 @@ struct _virStorageSource { int cachemode; /* enum virDomainDiskCache */ int discard; /* enum virDomainDiskDiscard */ int detect_zeroes; /* enum virDomainDiskDetectZeroes */ + + bool floppyimg; /* set to true if the storage source is going to be used + as a source for floppy drive */ }; -- 2.14.3

Move it to the validation callback and make it more robust. This will also put the checks in the correct place to use with -blockdev. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_command.c | 14 -------------- src/qemu/qemu_domain.c | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index b666f3715f..6de2fc56d5 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1512,20 +1512,6 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk, /* for now the DIR based storage is handled by the magic FAT format */ if (actualType == VIR_STORAGE_TYPE_DIR) { - if (disk->src->format > 0 && - disk->src->format != VIR_STORAGE_FILE_FAT) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unsupported disk driver type for '%s'"), - virStorageFileFormatTypeToString(disk->src->format)); - goto cleanup; - } - - if (!disk->src->readonly) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("cannot create virtual FAT disks in read-write mode")); - goto cleanup; - } - virBufferAddLit(buf, "fat:"); if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 6d7ab4ff80..8f240bd66d 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4117,6 +4117,8 @@ static int qemuDomainValidateStorageSource(virStorageSourcePtr src, virQEMUCapsPtr qemuCaps) { + int actualType = virStorageSourceGetActualType(src); + if (src->format == VIR_STORAGE_FILE_COW) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("'cow' storage format is not supported")); @@ -4146,6 +4148,29 @@ qemuDomainValidateStorageSource(virStorageSourcePtr src, return -1; } + if (src->format == VIR_STORAGE_FILE_FAT && + actualType != VIR_STORAGE_TYPE_DIR) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("storage format 'fat' is supported only with 'dir' " + "storage type")); + return -1; + } + + if (actualType == VIR_STORAGE_TYPE_DIR) { + if (src->format > 0 && + src->format != VIR_STORAGE_FILE_FAT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("storage type 'dir' requires use of storage format 'fat'")); + return -1; + } + + if (!src->readonly) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("virtual FAT storage can't be accessed in read-write mode")); + return -1; + } + } + return 0; } -- 2.14.3

Handle VIR_STORAGE_TYPE_DIR in qemuBlockStorageSourceGetBackendProps so that a 'vvfat' driver is used, which emulates a FAT filesystem containing the folders. qemu requires us to add it as a storage layer, since a 'raw' layer is usually put on top of it. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 6cf41cf544..516b006ce9 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -992,6 +992,25 @@ qemuBlockStorageSourceGetFileProps(virStorageSourcePtr src) } +static virJSONValuePtr +qemuBlockStorageSourceGetVvfatProps(virStorageSourcePtr src) +{ + virJSONValuePtr ret = NULL; + + /* libvirt currently does not handle the following attributes: + * '*fat-type': 'int' + * '*label': 'str' + */ + ignore_value(virJSONValueObjectCreate(&ret, + "s:driver", "vvfat", + "s:dir", src->path, + "b:floppy", src->floppyimg, + "b:rw", !src->readonly, NULL)); + + return ret; +} + + /** * qemuBlockStorageSourceGetBackendProps: * @src: disk source @@ -1008,11 +1027,17 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src) switch ((virStorageType) actualType) { case VIR_STORAGE_TYPE_BLOCK: case VIR_STORAGE_TYPE_FILE: - case VIR_STORAGE_TYPE_DIR: if (!(fileprops = qemuBlockStorageSourceGetFileProps(src))) return NULL; break; + case VIR_STORAGE_TYPE_DIR: + /* qemu handles directories by exposing them as a device with emulated + * FAT filesystem */ + if (!(fileprops = qemuBlockStorageSourceGetVvfatProps(src))) + return NULL; + break; + case VIR_STORAGE_TYPE_VOLUME: case VIR_STORAGE_TYPE_NONE: case VIR_STORAGE_TYPE_LAST: -- 2.14.3

The gluster protocol in qemu uses two styles, one of which is legacy and not covered by the QAPI schema. To allow using of the new style in the blockdev-add code, add a parameter for qemuBlockStorageSourceGetBackendProps which will switch between the two modes. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 11 +++++++---- src/qemu/qemu_block.h | 3 ++- src/qemu/qemu_command.c | 2 +- tests/qemublocktest.c | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 516b006ce9..9057fe4f9a 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -655,13 +655,14 @@ qemuBlockStorageSourceBuildHostsJSONInetSocketAddress(virStorageSourcePtr src) static virJSONValuePtr -qemuBlockStorageSourceGetGlusterProps(virStorageSourcePtr src) +qemuBlockStorageSourceGetGlusterProps(virStorageSourcePtr src, + bool legacy) { virJSONValuePtr servers = NULL; virJSONValuePtr props = NULL; virJSONValuePtr ret = NULL; - if (!(servers = qemuBlockStorageSourceBuildHostsJSONSocketAddress(src, true))) + if (!(servers = qemuBlockStorageSourceBuildHostsJSONSocketAddress(src, legacy))) return NULL; /* { driver:"gluster", @@ -1014,12 +1015,14 @@ qemuBlockStorageSourceGetVvfatProps(virStorageSourcePtr src) /** * qemuBlockStorageSourceGetBackendProps: * @src: disk source + * @legacy: use legacy formatting of attributes (for -drive / old qemus) * * Creates a JSON object describing the underlying storage or protocol of a * storage source. Returns NULL on error and reports an appropriate error message. */ virJSONValuePtr -qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src) +qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, + bool legacy) { int actualType = virStorageSourceGetActualType(src); virJSONValuePtr fileprops = NULL; @@ -1046,7 +1049,7 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src) case VIR_STORAGE_TYPE_NETWORK: switch ((virStorageNetProtocol) src->protocol) { case VIR_STORAGE_NET_PROTOCOL_GLUSTER: - if (!(fileprops = qemuBlockStorageSourceGetGlusterProps(src))) + if (!(fileprops = qemuBlockStorageSourceGetGlusterProps(src, legacy))) return NULL; break; diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index 45485733fc..0e674437f4 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -58,7 +58,8 @@ bool qemuBlockStorageSourceSupportsConcurrentAccess(virStorageSourcePtr src); virJSONValuePtr -qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src); +qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, + bool legacy); virURIPtr qemuBlockStorageSourceGetURI(virStorageSourcePtr src); diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6de2fc56d5..6ca83b8383 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1450,7 +1450,7 @@ qemuDiskSourceGetProps(virStorageSourcePtr src) virJSONValuePtr props; virJSONValuePtr ret; - if (!(props = qemuBlockStorageSourceGetBackendProps(src))) + if (!(props = qemuBlockStorageSourceGetBackendProps(src, true))) return NULL; if (virJSONValueObjectCreate(&ret, "a:file", &props, NULL) < 0) { diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 99584c759c..bd628295ff 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -62,7 +62,7 @@ testBackingXMLjsonXML(const void *args) goto cleanup; } - if (!(backendprops = qemuBlockStorageSourceGetBackendProps(xmlsrc))) { + if (!(backendprops = qemuBlockStorageSourceGetBackendProps(xmlsrc, true))) { fprintf(stderr, "failed to format disk source json\n"); goto cleanup; } -- 2.14.3

qemu declares node-name as a 32 byte buffer and silently truncates anything longer than that. This is unacceptable for libvirt, so we need to make sure that we won't ever supply a node-name exceeding 31 chars. Add a function which will do the validation and use it to validate storage-protocol node names. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 9057fe4f9a..cf6025ac7b 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -27,6 +27,24 @@ #define VIR_FROM_THIS VIR_FROM_QEMU +/* qemu declares the buffer for node names as a 32 byte array */ +static const size_t qemuBlockNodeNameBufSize = 32; + +static int +qemuBlockNodeNameValidate(const char *nn) +{ + if (!nn) + return 0; + + if (strlen(nn) >= qemuBlockNodeNameBufSize) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("node-name '%s' too long for qemu"), nn); + return -1; + } + + return 0; +} + static int qemuBlockNamedNodesArrayToHash(size_t pos ATTRIBUTE_UNUSED, @@ -1099,7 +1117,8 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, break; } - if (virJSONValueObjectAdd(fileprops, "S:node-name", src->nodestorage, NULL) < 0) { + if (qemuBlockNodeNameValidate(src->nodestorage) < 0 || + virJSONValueObjectAdd(fileprops, "S:node-name", src->nodestorage, NULL) < 0) { virJSONValueFree(fileprops); return NULL; } -- 2.14.3

When used directly with blockdev-add/-blockdev the cache mode will need to be specified directly for every image rather than just for the disk itself. This implements the backing options 'direct' and 'no-flush'. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index cf6025ac7b..eb246ebd60 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1030,6 +1030,35 @@ qemuBlockStorageSourceGetVvfatProps(virStorageSourcePtr src) } +static int +qemuBlockStorageSourceGetBlockdevGetCacheProps(virStorageSourcePtr src, + virJSONValuePtr props) +{ + virJSONValuePtr cacheobj; + bool direct = false; + bool noflush = false; + + if (src->cachemode == VIR_DOMAIN_DISK_CACHE_DEFAULT) + return 0; + + if (qemuDomainDiskCachemodeFlags(src->cachemode, NULL, &direct, &noflush) < 0) + return -1; + + if (virJSONValueObjectCreate(&cacheobj, + "b:direct", direct, + "b:no-flush", noflush, + NULL) < 0) + return -1; + + if (virJSONValueObjectAppend(props, "cache", cacheobj) < 0) { + virJSONValueFree(cacheobj); + return -1; + } + + return 0; +} + + /** * qemuBlockStorageSourceGetBackendProps: * @src: disk source @@ -1044,6 +1073,7 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, { int actualType = virStorageSourceGetActualType(src); virJSONValuePtr fileprops = NULL; + virJSONValuePtr ret = NULL; switch ((virStorageType) actualType) { case VIR_STORAGE_TYPE_BLOCK: @@ -1118,10 +1148,17 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, } if (qemuBlockNodeNameValidate(src->nodestorage) < 0 || - virJSONValueObjectAdd(fileprops, "S:node-name", src->nodestorage, NULL) < 0) { - virJSONValueFree(fileprops); - return NULL; + virJSONValueObjectAdd(fileprops, "S:node-name", src->nodestorage, NULL) < 0) + goto cleanup; + + if (!legacy) { + if (qemuBlockStorageSourceGetBlockdevGetCacheProps(src, fileprops) < 0) + goto cleanup; } - return fileprops; + VIR_STEAL_PTR(ret, fileprops); + + cleanup: + virJSONValueFree(fileprops); + return ret; } -- 2.14.3

This will be required when doing blockdev-add to conform with the approach qemu would chose to create the disks. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index eb246ebd60..44662a4603 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1154,6 +1154,9 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, if (!legacy) { if (qemuBlockStorageSourceGetBlockdevGetCacheProps(src, fileprops) < 0) goto cleanup; + + if (virJSONValueObjectAdd(fileprops, "b:read-only", src->readonly, NULL) < 0) + goto cleanup; } VIR_STEAL_PTR(ret, fileprops); -- 2.14.3

According to my research it seems that qemu always sets discard for the storage nodes. Replicate this in our generator. --- src/qemu/qemu_block.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 44662a4603..0357d93384 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1155,7 +1155,10 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, if (qemuBlockStorageSourceGetBlockdevGetCacheProps(src, fileprops) < 0) goto cleanup; - if (virJSONValueObjectAdd(fileprops, "b:read-only", src->readonly, NULL) < 0) + if (virJSONValueObjectAdd(fileprops, + "b:read-only", src->readonly, + "s:discard", "unmap", + NULL) < 0) goto cleanup; } -- 2.14.3

Am 19.04.2018 um 17:25 hat Peter Krempa geschrieben:
According to my research it seems that qemu always sets discard for the storage nodes. Replicate this in our generator. --- src/qemu/qemu_block.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 44662a4603..0357d93384 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1155,7 +1155,10 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, if (qemuBlockStorageSourceGetBlockdevGetCacheProps(src, fileprops) < 0) goto cleanup;
- if (virJSONValueObjectAdd(fileprops, "b:read-only", src->readonly, NULL) < 0) + if (virJSONValueObjectAdd(fileprops, + "b:read-only", src->readonly, + "s:discard", "unmap", + NULL) < 0) goto cleanup; }
Looks correct to me. The QEMU default means that discard requests made by the guest are ignored (already at the format level), but discard requests made by a format driver to the protocol layer are honoured (e.g. qcow2 discarding data when an internal snapshot is deleted). Kevin

When using blockdev-add and friends, libvirt will need to create also properties for the qcow2/raw/... format handler in qemu. This patch adds the infrastructure and implements all formats known to libvirt including all properties which are expressed at the format level in qemu. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_block.h | 3 + 2 files changed, 299 insertions(+) diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 0357d93384..87f3cf9cbe 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1168,3 +1168,299 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, virJSONValueFree(fileprops); return ret; } + + +static int +qemuBlockStorageSourceGetFormatRawProps(virStorageSourcePtr src, + virJSONValuePtr props) +{ + qemuDomainStorageSourcePrivatePtr srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src); + const char *driver = "raw"; + const char *secretalias = NULL; + + if (src->encryption && + src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS && + srcPriv && + srcPriv->encinfo) { + driver = "luks"; + secretalias = srcPriv->encinfo->s.aes.alias; + } + + /* currently unhandled properties for the 'raw' driver: + * 'offset' + * 'size' + */ + + if (virJSONValueObjectAdd(props, + "s:driver", driver, + "S:key-secret", secretalias, NULL) < 0) + return -1; + + return 0; +} + + +static int +qemuBlockStorageSourceGetCryptoProps(virStorageSourcePtr src, + virJSONValuePtr *encprops) +{ + qemuDomainStorageSourcePrivatePtr srcpriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src); + const char *encformat = NULL; + + *encprops = NULL; + + /* qemu requires encrypted secrets regardless of encryption method used when + * passed using the blockdev infrastructure, thus only + * VIR_DOMAIN_SECRET_INFO_TYPE_AES works here. The correct type needs to be + * instantiated elsewhere. */ + if (!src->encryption || + !srcpriv || + !srcpriv->encinfo || + srcpriv->encinfo->type != VIR_DOMAIN_SECRET_INFO_TYPE_AES) + return 0; + + switch ((virStorageEncryptionFormatType) src->encryption->format) { + case VIR_STORAGE_ENCRYPTION_FORMAT_QCOW: + encformat = "aes"; + break; + + case VIR_STORAGE_ENCRYPTION_FORMAT_LUKS: + encformat = "luks"; + break; + + case VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT: + case VIR_STORAGE_ENCRYPTION_FORMAT_LAST: + default: + virReportEnumRangeError(virStorageEncryptionFormatType, + src->encryption->format); + return -1; + } + + return virJSONValueObjectCreate(encprops, + "s:format", encformat, + "s:key-secret", srcpriv->encinfo->s.aes.alias, + NULL); +} + + +static int +qemuBlockStorageSourceGetFormatQcowGenericProps(virStorageSourcePtr src, + const char *format, + virJSONValuePtr props) +{ + virJSONValuePtr encprops = NULL; + int ret = -1; + + if (qemuBlockStorageSourceGetCryptoProps(src, &encprops) < 0) + return -1; + + if (virJSONValueObjectAdd(props, + "s:driver", format, + "A:encrypt", &encprops, NULL) < 0) + goto cleanup; + + ret = 0; + + cleanup: + virJSONValueFree(encprops); + return ret; +} + + +static int +qemuBlockStorageSourceGetFormatQcow2Props(virStorageSourcePtr src, + virJSONValuePtr props) +{ + /* currently unhandled qcow2 props: + * + * 'lazy-refcounts' + * 'pass-discard-request' + * 'pass-discard-snapshot' + * 'pass-discard-other' + * 'overlap-check' + * 'l2-cache-size' + * 'l2-cache-entry-size' + * 'refcount-cache-size' + * 'cache-clean-interval' + */ + + if (qemuBlockStorageSourceGetFormatQcowGenericProps(src, "qcow2", props) < 0) + return -1; + + return 0; +} + + +static virJSONValuePtr +qemuBlockStorageSourceGetBlockdevFormatCommonProps(virStorageSourcePtr src) +{ + const char *detectZeroes = NULL; + const char *discard = NULL; + int detectZeroesMode = virDomainDiskGetDetectZeroesMode(src->discard, + src->detect_zeroes); + virJSONValuePtr props = NULL; + virJSONValuePtr ret = NULL; + + if (qemuBlockNodeNameValidate(src->nodeformat) < 0) + return NULL; + + if (src->discard) + discard = virDomainDiskDiscardTypeToString(src->discard); + + if (detectZeroesMode) + detectZeroes = virDomainDiskDetectZeroesTypeToString(detectZeroesMode); + + /* currently unhandled global properties: + * '*force-share': 'bool' + */ + + if (virJSONValueObjectCreate(&props, + "s:node-name", src->nodeformat, + "b:read-only", src->readonly, + "S:discard", discard, + "S:detect-zeroes", detectZeroes, + NULL) < 0) + return NULL; + + if (qemuBlockStorageSourceGetBlockdevGetCacheProps(src, props) < 0) + goto cleanup; + + VIR_STEAL_PTR(ret, props); + + cleanup: + virJSONValueFree(props); + return ret; +} + + +static virJSONValuePtr +qemuBlockStorageSourceGetBlockdevFormatProps(virStorageSourcePtr src) +{ + const char *driver = NULL; + virJSONValuePtr props = NULL; + virJSONValuePtr ret = NULL; + + if (!(props = qemuBlockStorageSourceGetBlockdevFormatCommonProps(src))) + goto cleanup; + + switch ((virStorageFileFormat) src->format) { + case VIR_STORAGE_FILE_FAT: + /* The fat layer is emulated by the storage access layer, so we need to + * put a raw layer on top */ + case VIR_STORAGE_FILE_RAW: + if (qemuBlockStorageSourceGetFormatRawProps(src, props) < 0) + goto cleanup; + + break; + + case VIR_STORAGE_FILE_QCOW2: + if (qemuBlockStorageSourceGetFormatQcow2Props(src, props) < 0) + goto cleanup; + break; + + case VIR_STORAGE_FILE_QCOW: + if (qemuBlockStorageSourceGetFormatQcowGenericProps(src, "qcow", props) < 0) + goto cleanup; + break; + + /* formats without any special parameters */ + case VIR_STORAGE_FILE_PLOOP: + driver = "parallels"; + break; + case VIR_STORAGE_FILE_VHD: + driver = "vhdx"; + break; + case VIR_STORAGE_FILE_BOCHS: + case VIR_STORAGE_FILE_CLOOP: + case VIR_STORAGE_FILE_DMG: + case VIR_STORAGE_FILE_VDI: + case VIR_STORAGE_FILE_VPC: + case VIR_STORAGE_FILE_QED: + case VIR_STORAGE_FILE_VMDK: + driver = virStorageFileFormatTypeToString(src->format); + break; + + case VIR_STORAGE_FILE_AUTO_SAFE: + case VIR_STORAGE_FILE_AUTO: + case VIR_STORAGE_FILE_NONE: + case VIR_STORAGE_FILE_COW: + case VIR_STORAGE_FILE_ISO: + case VIR_STORAGE_FILE_DIR: + virReportError(VIR_ERR_INTERNAL_ERROR, + _("mishandled storage format '%s'"), + virStorageFileFormatTypeToString(src->format)); + goto cleanup; + + case VIR_STORAGE_FILE_LAST: + default: + virReportEnumRangeError(virStorageFileFormat, src->format); + goto cleanup; + } + + if (driver && + virJSONValueObjectAdd(props, "s:driver", driver, NULL) < 0) + goto cleanup; + + VIR_STEAL_PTR(ret, props); + + cleanup: + virJSONValueFree(props); + + return ret; +} + + +/** + * qemuBlockStorageSourceGetBlockdevProps: + * + * @src: storage source to format + * + * Formats @src into a JSON object which can be used with blockdev-add or + * -blockdev. The formatted object contains both the storage and format layer + * in nested form including link to the backing chain layer if necessary. + */ +virJSONValuePtr +qemuBlockStorageSourceGetBlockdevProps(virStorageSourcePtr src) +{ + bool backingSupported = src->format >= VIR_STORAGE_FILE_BACKING; + virJSONValuePtr storage = NULL; + virJSONValuePtr props = NULL; + virJSONValuePtr ret = NULL; + + if (virStorageSourceHasBacking(src) && !backingSupported) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("storage format '%s' does not support backing store"), + virStorageFileFormatTypeToString(src->format)); + goto cleanup; + } + + if (!(props = qemuBlockStorageSourceGetBlockdevFormatProps(src))) + goto cleanup; + + if (!(storage = qemuBlockStorageSourceGetBackendProps(src, false))) + goto cleanup; + + if (virJSONValueObjectAppend(props, "file", storage) < 0) + goto cleanup; + storage = NULL; + + if (src->backingStore && backingSupported) { + if (virStorageSourceHasBacking(src)) { + if (virJSONValueObjectAppendString(props, "backing", + src->backingStore->nodeformat) < 0) + goto cleanup; + } else { + /* chain is terminated, indicate that no detection should happen + * in qemu */ + if (virJSONValueObjectAppendNull(props, "backing") < 0) + goto cleanup; + } + } + + VIR_STEAL_PTR(ret, props); + + cleanup: + virJSONValueFree(storage); + virJSONValueFree(props); + return ret; +} diff --git a/src/qemu/qemu_block.h b/src/qemu/qemu_block.h index 0e674437f4..f819c6f907 100644 --- a/src/qemu/qemu_block.h +++ b/src/qemu/qemu_block.h @@ -64,4 +64,7 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, virURIPtr qemuBlockStorageSourceGetURI(virStorageSourcePtr src); +virJSONValuePtr +qemuBlockStorageSourceGetBlockdevProps(virStorageSourcePtr src); + #endif /* __QEMU_BLOCK_H__ */ -- 2.14.3

Am 19.04.2018 um 17:25 hat Peter Krempa geschrieben:
When using blockdev-add and friends, libvirt will need to create also properties for the qcow2/raw/... format handler in qemu. This patch adds the infrastructure and implements all formats known to libvirt including all properties which are expressed at the format level in qemu.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_block.c | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_block.h | 3 + 2 files changed, 299 insertions(+)
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c index 0357d93384..87f3cf9cbe 100644 --- a/src/qemu/qemu_block.c +++ b/src/qemu/qemu_block.c @@ -1168,3 +1168,299 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, virJSONValueFree(fileprops); return ret; } + + +static int +qemuBlockStorageSourceGetFormatRawProps(virStorageSourcePtr src, + virJSONValuePtr props) +{ + qemuDomainStorageSourcePrivatePtr srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src); + const char *driver = "raw"; + const char *secretalias = NULL; + + if (src->encryption && + src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS && + srcPriv && + srcPriv->encinfo) { + driver = "luks"; + secretalias = srcPriv->encinfo->s.aes.alias; + }
Hm, so libvirt treats luks images as "encrypted raw" (which is a contradiction in itself)? I suppose it's too late to change this, but it's a bit unfortunate, because...
+ /* currently unhandled properties for the 'raw' driver: + * 'offset' + * 'size' + */
...if you ever want to implement these features, the luks driver won't be offering them and you'll need to create two layers at once in this function (raw over luks, or luks over raw - and it's not clear which one). Kevin

New tests will add new data structures so rename the 'data' structure. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index bd628295ff..7eef9f286a 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -117,15 +117,16 @@ static int mymain(void) { int ret = 0; - struct testBackingXMLjsonXMLdata data; + struct testBackingXMLjsonXMLdata xmljsonxmldata; virTestCounterReset("qemu storage source xml->json->xml "); #define TEST_JSON_FORMAT(tpe, xmlstr) \ do { \ - data.type = tpe; \ - data.xml = xmlstr; \ - if (virTestRun(virTestCounterNext(), testBackingXMLjsonXML, &data) < 0) \ + xmljsonxmldata.type = tpe; \ + xmljsonxmldata.xml = xmlstr; \ + if (virTestRun(virTestCounterNext(), testBackingXMLjsonXML, \ + &xmljsonxmldata) < 0) \ ret = -1; \ } while (0) -- 2.14.3

Remove gnulib from _LDADD and move LDADDS to replace it. Also reformat the _SOURCES so that they can be easily extended. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/Makefile.am | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 7b93fbde69..67850349de 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -655,12 +655,14 @@ qemuhotplugtest_SOURCES = \ qemuhotplugtest_LDADD = libqemumonitortestutils.la $(qemu_LDADDS) $(LDADDS) qemublocktest_SOURCES = \ - qemublocktest.c testutils.h testutils.c -qemublocktest_LDADD = $(LDADDS) \ + qemublocktest.c \ + testutils.h testutils.c \ + $(NULL) +qemublocktest_LDADD = \ ../src/libvirt_conf.la \ ../src/libvirt_util.la \ $(qemu_LDADDS) \ - ../gnulib/lib/libgnu.la \ + $(LDADDS) \ $(NULL) domainsnapshotxml2xmltest_SOURCES = \ -- 2.14.3

It will be used in the qemublocktest. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 2 +- src/qemu/qemu_domain.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 8f240bd66d..b8abae1afb 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4175,7 +4175,7 @@ qemuDomainValidateStorageSource(virStorageSourcePtr src, } -static int +int qemuDomainDeviceDefValidateDisk(const virDomainDiskDef *disk, virQEMUCapsPtr qemuCaps) { diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 2c27dfb9f3..2dccec264b 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -862,6 +862,9 @@ int qemuDomainSecretPrepare(virQEMUDriverPtr driver, int qemuDomainDefValidateDiskLunSource(const virStorageSource *src) ATTRIBUTE_NONNULL(1); +int qemuDomainDeviceDefValidateDisk(const virDomainDiskDef *disk, + virQEMUCapsPtr qemuCaps); + int qemuDomainPrepareChannel(virDomainChrDefPtr chr, const char *domainChannelTargetDir) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); -- 2.14.3

The function will be reused in the test code where we don't care much that the gluster debug level can't be populated from the qemu config. Set the level only when 'cfg' is passed. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index b8abae1afb..8fbc793e92 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -11862,7 +11862,8 @@ qemuDomainPrepareDiskSourceChain(virDomainDiskDefPtr disk, src->detect_zeroes = disk->detect_zeroes; for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) { - if (n->type == VIR_STORAGE_TYPE_NETWORK && + if (cfg && + n->type == VIR_STORAGE_TYPE_NETWORK && n->protocol == VIR_STORAGE_NET_PROTOCOL_GLUSTER && virQEMUCapsGet(qemuCaps, QEMU_CAPS_GLUSTER_DEBUG_LEVEL)) { n->debug = true; -- 2.14.3

Add a test infrastructure that will allow testing the JSON object generator used for generating data to use with blockdev-add. The resulting disk including the backing chain is validated to conform to the QAPI schema and the expected output files. The first test cases make sure that libvirt will not allow nodenames exceeding 31 chars. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/Makefile.am | 3 + tests/qemublocktest.c | 227 +++++++++++++++++++++ .../xml2json/nodename-long-format.xml | 9 + .../xml2json/nodename-long-protocol.xml | 9 + 4 files changed, 248 insertions(+) create mode 100644 tests/qemublocktestdata/xml2json/nodename-long-format.xml create mode 100644 tests/qemublocktestdata/xml2json/nodename-long-protocol.xml diff --git a/tests/Makefile.am b/tests/Makefile.am index 67850349de..6a61296c44 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -119,6 +119,7 @@ EXTRA_DIST = \ oomtrace.pl \ qemuagentdata \ qemuargv2xmldata \ + qemublocktestdata \ qemucapabilitiesdata \ qemucaps2xmldata \ qemuhotplugtestcpus \ @@ -657,8 +658,10 @@ qemuhotplugtest_LDADD = libqemumonitortestutils.la $(qemu_LDADDS) $(LDADDS) qemublocktest_SOURCES = \ qemublocktest.c \ testutils.h testutils.c \ + testutilsqemu.h testutilsqemu.c \ $(NULL) qemublocktest_LDADD = \ + libqemumonitortestutils.la \ ../src/libvirt_conf.la \ ../src/libvirt_util.la \ $(qemu_LDADDS) \ diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 7eef9f286a..161053a717 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -19,10 +19,15 @@ #include <stdlib.h> #include "testutils.h" +#include "testutilsqemu.h" +#include "testutilsqemuschema.h" #include "virstoragefile.h" #include "virstring.h" #include "virlog.h" #include "qemu/qemu_block.h" +#include "qemu/qemu_qapi.h" + +#include "qemu/qemu_command.h" #define VIR_FROM_THIS VIR_FROM_NONE @@ -113,11 +118,190 @@ testBackingXMLjsonXML(const void *args) } +struct testQemuDiskXMLToJSONData { + virQEMUDriverPtr driver; + virHashTablePtr schema; + virJSONValuePtr schemaroot; + const char *name; + bool fail; + + virJSONValuePtr *props; + size_t nprops; + + virQEMUCapsPtr qemuCaps; +}; + + +static void +testQemuDiskXMLToPropsClear(struct testQemuDiskXMLToJSONData *data) +{ + size_t i; + + for (i = 0; i < data->nprops; i++) + virJSONValueFree(data->props[i]); + + data->nprops = 0; + VIR_FREE(data->props); +} + + +static const char *testQemuDiskXMLToJSONPath = abs_srcdir "/qemublocktestdata/xml2json/"; + +static int +testQemuDiskXMLToProps(const void *opaque) +{ + struct testQemuDiskXMLToJSONData *data = (void *) opaque; + virDomainDiskDefPtr disk = NULL; + virStorageSourcePtr n; + virJSONValuePtr props = NULL; + char *xmlpath = NULL; + char *xmlstr = NULL; + int ret = -1; + + if (virAsprintf(&xmlpath, "%s%s.xml", + testQemuDiskXMLToJSONPath, data->name) < 0) + goto cleanup; + + if (virTestLoadFile(xmlpath, &xmlstr) < 0) + goto cleanup; + + /* qemu stores node names in the status XML portion */ + if (!(disk = virDomainDiskDefParse(xmlstr, NULL, data->driver->xmlopt, + VIR_DOMAIN_DEF_PARSE_STATUS))) + goto cleanup; + + if (qemuCheckDiskConfig(disk, data->qemuCaps) < 0 || + qemuDomainDeviceDefValidateDisk(disk, data->qemuCaps) < 0) { + VIR_TEST_VERBOSE("invalid configuration for disk\n"); + goto cleanup; + } + + if (qemuDomainPrepareDiskSourceChain(disk, NULL, NULL, data->qemuCaps) < 0) + goto cleanup; + + for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) { + if (!(props = qemuBlockStorageSourceGetBlockdevProps(n))) { + if (!data->fail) { + VIR_TEST_VERBOSE("failed to generate qemu blockdev props\n"); + goto cleanup; + } + } else if (data->fail) { + VIR_TEST_VERBOSE("qemu blockdev props should have failed\n"); + goto cleanup; + } + + if (VIR_APPEND_ELEMENT(data->props, data->nprops, props) < 0) + goto cleanup; + } + + ret = 0; + + cleanup: + virDomainDiskDefFree(disk); + VIR_FREE(xmlpath); + VIR_FREE(xmlstr); + return ret; +} + + +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; + + if (data->fail) + return EXIT_AM_SKIP; + + for (i = 0; i < data->nprops; i++) { + if (testQEMUSchemaValidate(data->props[i], data->schemaroot, + data->schema, &debug) < 0) { + debugmsg = virBufferContentAndReset(&debug); + 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); + } + return ret; +} + + +static int +testQemuDiskXMLToPropsValidateFile(const void *opaque) +{ + struct testQemuDiskXMLToJSONData *data = (void *) opaque; + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *jsonpath = NULL; + char *jsonstr = NULL; + char *actual = NULL; + int ret = -1; + size_t i; + + if (data->fail) + return EXIT_AM_SKIP; + + if (virAsprintf(&jsonpath, "%s%s.json", + testQemuDiskXMLToJSONPath, data->name) < 0) + goto cleanup; + + for (i = 0; i < data->nprops; i++) { + if (!(jsonstr = virJSONValueToString(data->props[i], true))) + goto cleanup; + + virBufferAdd(&buf, jsonstr, -1); + } + + if (virBufferCheckError(&buf) < 0) + goto cleanup; + + actual = virBufferContentAndReset(&buf); + + ret = virTestCompareToFile(actual, jsonpath); + + cleanup: + VIR_FREE(jsonpath); + VIR_FREE(jsonstr); + VIR_FREE(actual); + return ret; +} + + static int mymain(void) { int ret = 0; + virQEMUDriver driver; struct testBackingXMLjsonXMLdata xmljsonxmldata; + struct testQemuDiskXMLToJSONData diskxmljsondata; + char *capslatest_x86_64 = NULL; + virQEMUCapsPtr caps_x86_64 = NULL; + + if (qemuTestDriverInit(&driver) < 0) + return EXIT_FAILURE; + + diskxmljsondata.driver = &driver; + + if (!(capslatest_x86_64 = testQemuGetLatestCapsForArch(abs_srcdir "/qemucapabilitiesdata", + "x86_64", "xml"))) + return EXIT_FAILURE; + + VIR_TEST_VERBOSE("\nlatest caps x86_64: %s\n", capslatest_x86_64); + + if (!(caps_x86_64 = qemuTestParseCapabilitiesArch(virArchFromString("x86_64"), + capslatest_x86_64))) + return EXIT_FAILURE; + + diskxmljsondata.qemuCaps = caps_x86_64; virTestCounterReset("qemu storage source xml->json->xml "); @@ -183,6 +367,49 @@ mymain(void) " <host name='example.com' port='9999'/>\n" "</source>\n"); +#define TEST_DISK_TO_JSON_FULL(nme, fl) \ + do { \ + diskxmljsondata.name = nme; \ + diskxmljsondata.props = NULL; \ + diskxmljsondata.nprops = 0; \ + diskxmljsondata.fail = fl; \ + if (virTestRun("disk xml to props " nme, testQemuDiskXMLToProps, \ + &diskxmljsondata) < 0) \ + ret = -1; \ + if (virTestRun("disk xml to props validate schema " nme, \ + testQemuDiskXMLToPropsValidateSchema, &diskxmljsondata) < 0) \ + ret = -1; \ + if (virTestRun("disk xml to props validate file " nme, \ + testQemuDiskXMLToPropsValidateFile, &diskxmljsondata) < 0) \ + ret = -1; \ + testQemuDiskXMLToPropsClear(&diskxmljsondata); \ + } while (0) + +#define TEST_DISK_TO_JSON(nme) TEST_DISK_TO_JSON_FULL(nme, false) + + if (!(diskxmljsondata.schema = testQEMUSchemaLoad())) { + ret = -1; + goto cleanup; + } + + if (virQEMUQAPISchemaPathGet("blockdev-add/arg-type", + diskxmljsondata.schema, + &diskxmljsondata.schemaroot) < 0 || + !diskxmljsondata.schemaroot) { + VIR_TEST_VERBOSE("failed to find schema entry for blockdev-add\n"); + ret = -1; + goto cleanup; + } + + TEST_DISK_TO_JSON_FULL("nodename-long-format", true); + TEST_DISK_TO_JSON_FULL("nodename-long-protocol", true); + + cleanup: + virHashFree(diskxmljsondata.schema); + qemuTestDriverFree(&driver); + VIR_FREE(capslatest_x86_64); + virObjectUnref(caps_x86_64); + return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/qemublocktestdata/xml2json/nodename-long-format.xml b/tests/qemublocktestdata/xml2json/nodename-long-format.xml new file mode 100644 index 0000000000..e1d9473508 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/nodename-long-format.xml @@ -0,0 +1,9 @@ +<disk device='disk'> + <driver name='qemu' type='raw'/> + <source file='/path'> + <privateData> + <nodename format='0123456789ABCDEF0123456789ABCDEF' storage='test2'/> + </privateData> + </source> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/nodename-long-protocol.xml b/tests/qemublocktestdata/xml2json/nodename-long-protocol.xml new file mode 100644 index 0000000000..a4b7eba826 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/nodename-long-protocol.xml @@ -0,0 +1,9 @@ +<disk device='disk'> + <driver name='qemu' type='raw'/> + <source file='/path'> + <privateData> + <nodename format='test1' storage='0123456789ABCDEF0123456789ABCDEF0'/> + </privateData> + </source> + <target dev='vda'/> +</disk> -- 2.14.3

Test the JSON props generator with a very simple 'raw' image with no other options. The node-names for the image are 31 bytes long so that we validate our node name detector. The top level disk image would generate the following '-drive' cmdline: -drive file=/var/lib/libvirt/images/i.img,format=raw,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 2 ++ tests/qemublocktestdata/xml2json/file-raw-noopts.json | 12 ++++++++++++ tests/qemublocktestdata/xml2json/file-raw-noopts.xml | 9 +++++++++ 3 files changed, 23 insertions(+) create mode 100644 tests/qemublocktestdata/xml2json/file-raw-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-raw-noopts.xml diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 161053a717..c9a2f91992 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -404,6 +404,8 @@ mymain(void) TEST_DISK_TO_JSON_FULL("nodename-long-format", true); TEST_DISK_TO_JSON_FULL("nodename-long-protocol", true); + TEST_DISK_TO_JSON("file-raw-noopts"); + cleanup: virHashFree(diskxmljsondata.schema); qemuTestDriverFree(&driver); diff --git a/tests/qemublocktestdata/xml2json/file-raw-noopts.json b/tests/qemublocktestdata/xml2json/file-raw-noopts.json new file mode 100644 index 0000000000..25de571428 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-raw-noopts.json @@ -0,0 +1,12 @@ +{ + "node-name": "0123456789ABCDEF0123456789ABCDE", + "read-only": false, + "driver": "raw", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/i.img", + "node-name": "0123456789ABCDEF0123456789ABCDE", + "read-only": false, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-raw-noopts.xml b/tests/qemublocktestdata/xml2json/file-raw-noopts.xml new file mode 100644 index 0000000000..f6e3d38bad --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-raw-noopts.xml @@ -0,0 +1,9 @@ +<disk device='disk'> + <driver name='qemu' type='raw'/> + <source file='/var/lib/libvirt/images/i.img'> + <privateData> + <nodename format='0123456789ABCDEF0123456789ABCDE' storage='0123456789ABCDEF0123456789ABCDE'/> + </privateData> + </source> + <target dev='vda'/> +</disk> -- 2.14.3

Similarly to the 'raw' case add tests for bochs, cloop, dmg, ploop, vdi vhd, and vpc. Covering all supproted non-backing formats. Note that the JSON name for 'ploop' maps to 'parallels' and 'vhd' maps to 'vhdx'. Files added here would result in the followint configs: file-bochs-noopts.xml: -drive file=/path/to/i.img,format=bochs,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy file-cloop-noopts.xml: -drive file=/path/to/i.img,format=cloop,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy file-dmg-noopts.xml: -drive file=/path/to/i.img,format=dmg,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy file-ploop-noopts.xml: -drive file=/path/to/i.img,format=ploop,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy file-vdi-noopts.xml: -drive file=/path/to/i.img,format=vdi,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy file-vhd-noopts.xml: -drive file=/path/to/i.img,format=vhd,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy file-vpc-noopts.xml: -drive file=/path/to/i.img,format=vpc,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 7 +++++++ tests/qemublocktestdata/xml2json/file-bochs-noopts.json | 12 ++++++++++++ tests/qemublocktestdata/xml2json/file-bochs-noopts.xml | 9 +++++++++ tests/qemublocktestdata/xml2json/file-cloop-noopts.json | 12 ++++++++++++ tests/qemublocktestdata/xml2json/file-cloop-noopts.xml | 9 +++++++++ tests/qemublocktestdata/xml2json/file-dmg-noopts.json | 12 ++++++++++++ tests/qemublocktestdata/xml2json/file-dmg-noopts.xml | 9 +++++++++ tests/qemublocktestdata/xml2json/file-ploop-noopts.json | 12 ++++++++++++ tests/qemublocktestdata/xml2json/file-ploop-noopts.xml | 9 +++++++++ tests/qemublocktestdata/xml2json/file-vdi-noopts.json | 12 ++++++++++++ tests/qemublocktestdata/xml2json/file-vdi-noopts.xml | 9 +++++++++ tests/qemublocktestdata/xml2json/file-vhd-noopts.json | 12 ++++++++++++ tests/qemublocktestdata/xml2json/file-vhd-noopts.xml | 9 +++++++++ tests/qemublocktestdata/xml2json/file-vpc-noopts.json | 12 ++++++++++++ tests/qemublocktestdata/xml2json/file-vpc-noopts.xml | 9 +++++++++ 15 files changed, 154 insertions(+) create mode 100644 tests/qemublocktestdata/xml2json/file-bochs-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-bochs-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-cloop-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-cloop-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-dmg-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-dmg-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-ploop-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-ploop-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-vdi-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-vdi-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-vhd-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-vhd-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-vpc-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-vpc-noopts.xml diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index c9a2f91992..feb25c69e3 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -405,6 +405,13 @@ mymain(void) TEST_DISK_TO_JSON_FULL("nodename-long-protocol", true); TEST_DISK_TO_JSON("file-raw-noopts"); + TEST_DISK_TO_JSON("file-bochs-noopts"); + TEST_DISK_TO_JSON("file-cloop-noopts"); + TEST_DISK_TO_JSON("file-dmg-noopts"); + TEST_DISK_TO_JSON("file-ploop-noopts"); + TEST_DISK_TO_JSON("file-vdi-noopts"); + TEST_DISK_TO_JSON("file-vhd-noopts"); + TEST_DISK_TO_JSON("file-vpc-noopts"); cleanup: virHashFree(diskxmljsondata.schema); diff --git a/tests/qemublocktestdata/xml2json/file-bochs-noopts.json b/tests/qemublocktestdata/xml2json/file-bochs-noopts.json new file mode 100644 index 0000000000..22e2560998 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-bochs-noopts.json @@ -0,0 +1,12 @@ +{ + "node-name": "test1", + "read-only": false, + "driver": "bochs", + "file": { + "driver": "file", + "filename": "/path/to/i.img", + "node-name": "test2", + "read-only": false, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-bochs-noopts.xml b/tests/qemublocktestdata/xml2json/file-bochs-noopts.xml new file mode 100644 index 0000000000..ebe9da438c --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-bochs-noopts.xml @@ -0,0 +1,9 @@ +<disk device='disk'> + <driver name='qemu' type='bochs'/> + <source file='/path/to/i.img'> + <privateData> + <nodename format='test1' storage='test2'/> + </privateData> + </source> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-cloop-noopts.json b/tests/qemublocktestdata/xml2json/file-cloop-noopts.json new file mode 100644 index 0000000000..b72bb5df56 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-cloop-noopts.json @@ -0,0 +1,12 @@ +{ + "node-name": "test1", + "read-only": false, + "driver": "cloop", + "file": { + "driver": "file", + "filename": "/path/to/i.img", + "node-name": "test2", + "read-only": false, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-cloop-noopts.xml b/tests/qemublocktestdata/xml2json/file-cloop-noopts.xml new file mode 100644 index 0000000000..d48219145d --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-cloop-noopts.xml @@ -0,0 +1,9 @@ +<disk device='disk'> + <driver name='qemu' type='cloop'/> + <source file='/path/to/i.img'> + <privateData> + <nodename format='test1' storage='test2'/> + </privateData> + </source> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-dmg-noopts.json b/tests/qemublocktestdata/xml2json/file-dmg-noopts.json new file mode 100644 index 0000000000..9f2912b8d3 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-dmg-noopts.json @@ -0,0 +1,12 @@ +{ + "node-name": "test1", + "read-only": false, + "driver": "dmg", + "file": { + "driver": "file", + "filename": "/path/to/i.img", + "node-name": "test2", + "read-only": false, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-dmg-noopts.xml b/tests/qemublocktestdata/xml2json/file-dmg-noopts.xml new file mode 100644 index 0000000000..27f4fa8cd6 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-dmg-noopts.xml @@ -0,0 +1,9 @@ +<disk device='disk'> + <driver name='qemu' type='dmg'/> + <source file='/path/to/i.img'> + <privateData> + <nodename format='test1' storage='test2'/> + </privateData> + </source> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-ploop-noopts.json b/tests/qemublocktestdata/xml2json/file-ploop-noopts.json new file mode 100644 index 0000000000..64006d28a3 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-ploop-noopts.json @@ -0,0 +1,12 @@ +{ + "node-name": "test1", + "read-only": false, + "driver": "parallels", + "file": { + "driver": "file", + "filename": "/path/to/i.img", + "node-name": "test2", + "read-only": false, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-ploop-noopts.xml b/tests/qemublocktestdata/xml2json/file-ploop-noopts.xml new file mode 100644 index 0000000000..5f47f6b73b --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-ploop-noopts.xml @@ -0,0 +1,9 @@ +<disk device='disk'> + <driver name='qemu' type='ploop'/> + <source file='/path/to/i.img'> + <privateData> + <nodename format='test1' storage='test2'/> + </privateData> + </source> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-vdi-noopts.json b/tests/qemublocktestdata/xml2json/file-vdi-noopts.json new file mode 100644 index 0000000000..ce8e359c91 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-vdi-noopts.json @@ -0,0 +1,12 @@ +{ + "node-name": "test1", + "read-only": false, + "driver": "vdi", + "file": { + "driver": "file", + "filename": "/path/to/i.img", + "node-name": "test2", + "read-only": false, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-vdi-noopts.xml b/tests/qemublocktestdata/xml2json/file-vdi-noopts.xml new file mode 100644 index 0000000000..5d2e76656b --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-vdi-noopts.xml @@ -0,0 +1,9 @@ +<disk device='disk'> + <driver name='qemu' type='vdi'/> + <source file='/path/to/i.img'> + <privateData> + <nodename format='test1' storage='test2'/> + </privateData> + </source> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-vhd-noopts.json b/tests/qemublocktestdata/xml2json/file-vhd-noopts.json new file mode 100644 index 0000000000..d4b8e1f55a --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-vhd-noopts.json @@ -0,0 +1,12 @@ +{ + "node-name": "test1", + "read-only": false, + "driver": "vhdx", + "file": { + "driver": "file", + "filename": "/path/to/i.img", + "node-name": "test2", + "read-only": false, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-vhd-noopts.xml b/tests/qemublocktestdata/xml2json/file-vhd-noopts.xml new file mode 100644 index 0000000000..c6a9686a95 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-vhd-noopts.xml @@ -0,0 +1,9 @@ +<disk device='disk'> + <driver name='qemu' type='vhd'/> + <source file='/path/to/i.img'> + <privateData> + <nodename format='test1' storage='test2'/> + </privateData> + </source> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-vpc-noopts.json b/tests/qemublocktestdata/xml2json/file-vpc-noopts.json new file mode 100644 index 0000000000..be1ec795a7 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-vpc-noopts.json @@ -0,0 +1,12 @@ +{ + "node-name": "test1", + "read-only": false, + "driver": "vpc", + "file": { + "driver": "file", + "filename": "/path/to/i.img", + "node-name": "test2", + "read-only": false, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-vpc-noopts.xml b/tests/qemublocktestdata/xml2json/file-vpc-noopts.xml new file mode 100644 index 0000000000..5f79c4a826 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-vpc-noopts.xml @@ -0,0 +1,9 @@ +<disk device='disk'> + <driver name='qemu' type='vpc'/> + <source file='/path/to/i.img'> + <privateData> + <nodename format='test1' storage='test2'/> + </privateData> + </source> + <target dev='vda'/> +</disk> -- 2.14.3

Am 19.04.2018 um 17:25 hat Peter Krempa geschrieben:
Similarly to the 'raw' case add tests for bochs, cloop, dmg, ploop, vdi vhd, and vpc. Covering all supproted non-backing formats.
Note that the JSON name for 'ploop' maps to 'parallels' and 'vhd' maps to 'vhdx'.
Your -drive lines below mention format=ploop/vhd, though. That wouldn't actually work. (Also 'vhd' as an alias for 'vhdx' is super confusing, because VHD is really the name of the format implemented by QEMU's 'vpc' driver - which is already a source of confusion on its own.)
Files added here would result in the followint configs:
file-bochs-noopts.xml: -drive file=/path/to/i.img,format=bochs,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy
file-cloop-noopts.xml: -drive file=/path/to/i.img,format=cloop,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy
file-dmg-noopts.xml: -drive file=/path/to/i.img,format=dmg,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy
file-ploop-noopts.xml: -drive file=/path/to/i.img,format=ploop,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy
file-vdi-noopts.xml: -drive file=/path/to/i.img,format=vdi,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy
file-vhd-noopts.xml: -drive file=/path/to/i.img,format=vhd,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy
file-vpc-noopts.xml: -drive file=/path/to/i.img,format=vpc,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Some of the cases tested here or in later patches are for configurations that wouldn't work, but I guess for a test of parsing and storing XML, that doesn't matter. Kevin

On Fri, Apr 20, 2018 at 13:55:35 +0200, Kevin Wolf wrote:
Am 19.04.2018 um 17:25 hat Peter Krempa geschrieben:
Similarly to the 'raw' case add tests for bochs, cloop, dmg, ploop, vdi vhd, and vpc. Covering all supproted non-backing formats.
Note that the JSON name for 'ploop' maps to 'parallels' and 'vhd' maps to 'vhdx'.
Your -drive lines below mention format=ploop/vhd, though. That wouldn't actually work.
So, is it something that we should actually forbid? I did not actually try all of the weird formats, so I just assumed that if we'd happily generate the -drive command line and the 'blockdev' version exists it's equivalent.
(Also 'vhd' as an alias for 'vhdx' is super confusing, because VHD is really the name of the format implemented by QEMU's 'vpc' driver - which is already a source of confusion on its own.)
Hmmm, maybe that is a bug in my implementation. Since libvirt has a VPC format and also a VHD format I thohght that VHD is just another name for 'vhxd'. If they are different, we maybe should forbid it altogether. I confess that I did a simple prefix match rather than any complex analysis.

Am 20.04.2018 um 21:20 hat Peter Krempa geschrieben:
On Fri, Apr 20, 2018 at 13:55:35 +0200, Kevin Wolf wrote:
Am 19.04.2018 um 17:25 hat Peter Krempa geschrieben:
Similarly to the 'raw' case add tests for bochs, cloop, dmg, ploop, vdi vhd, and vpc. Covering all supproted non-backing formats.
Note that the JSON name for 'ploop' maps to 'parallels' and 'vhd' maps to 'vhdx'.
Your -drive lines below mention format=ploop/vhd, though. That wouldn't actually work.
So, is it something that we should actually forbid? I did not actually try all of the weird formats, so I just assumed that if we'd happily generate the -drive command line and the 'blockdev' version exists it's equivalent.
I thought it's just a mistake in the commit message and that libvirt actually does the translation described here. So it would use -drive format=parallels instead of ploop.
(Also 'vhd' as an alias for 'vhdx' is super confusing, because VHD is really the name of the format implemented by QEMU's 'vpc' driver - which is already a source of confusion on its own.)
Hmmm, maybe that is a bug in my implementation. Since libvirt has a VPC format and also a VHD format I thohght that VHD is just another name for 'vhxd'. If they are different, we maybe should forbid it altogether. I confess that I did a simple prefix match rather than any complex analysis.
Maybe double-check, but your assumption might be right. There would be little reason to have both VPC and VHD, when both are names for the same thing (except as aliases, possibly). Kevin

Formats supporting backing chain such as qed, vmdk, don't have any other parameters than the backing store and 'qcow' has only encryption params which will be tested extra. Add this test case so they are covered since any further test cases will mainly care about 'qcow2' and 'raw'. The top level disk image would generate the following '-drive' cmdline: -drive file=/var/lib/libvirt/images/a,format=qed,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 2 + .../xml2json/file-backing_basic-noopts.json | 51 ++++++++++++++++++++++ .../xml2json/file-backing_basic-noopts.xml | 34 +++++++++++++++ 3 files changed, 87 insertions(+) create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-noopts.xml diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index feb25c69e3..881d7c17ee 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -413,6 +413,8 @@ mymain(void) TEST_DISK_TO_JSON("file-vhd-noopts"); TEST_DISK_TO_JSON("file-vpc-noopts"); + TEST_DISK_TO_JSON("file-backing_basic-noopts"); + cleanup: virHashFree(diskxmljsondata.schema); qemuTestDriverFree(&driver); diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-noopts.json b/tests/qemublocktestdata/xml2json/file-backing_basic-noopts.json new file mode 100644 index 0000000000..3285a6ec67 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-noopts.json @@ -0,0 +1,51 @@ +{ + "node-name": "node-a-f", + "read-only": false, + "driver": "qed", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/a", + "node-name": "node-a-s", + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "driver": "qcow", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/b", + "node-name": "node-b-s", + "read-only": true, + "discard": "unmap" + }, + "backing": "node-c-f" +} +{ + "node-name": "node-c-f", + "read-only": true, + "driver": "vmdk", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/c", + "node-name": "node-c-s", + "read-only": true, + "discard": "unmap" + }, + "backing": "node-d-f" +} +{ + "node-name": "node-d-f", + "read-only": true, + "driver": "raw", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/d", + "node-name": "node-d-s", + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-noopts.xml b/tests/qemublocktestdata/xml2json/file-backing_basic-noopts.xml new file mode 100644 index 0000000000..daa9423dcc --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-noopts.xml @@ -0,0 +1,34 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qed'/> + <source file='/var/lib/libvirt/images/a'> + <privateData> + <nodename storage='node-a-s' format='node-a-f'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qcow'/> + <source file='/var/lib/libvirt/images/b'> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='file' index='2'> + <format type='vmdk'/> + <source file='/var/lib/libvirt/images/c'> + <privateData> + <nodename storage='node-c-s' format='node-c-f'/> + </privateData> + </source> + <backingStore type='file' index='3'> + <format type='raw'/> + <source file='/var/lib/libvirt/images/d'> + <privateData> + <nodename storage='node-d-s' format='node-d-f'/> + </privateData> + </source> + <backingStore/> + </backingStore> + </backingStore> + </backingStore> + <target dev='vda'/> +</disk> -- 2.14.3

Test mapping of the 'FAT' disk format to 'vvfat' in qemu. The top level disk image would generate the following '-drive' cmdline: dir-fat-readonly.xml: -drive file=fat:/var/somefiles,if=none,id=drive-dummy,readonly=on -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 2 ++ tests/qemublocktestdata/xml2json/dir-fat-floppy.json | 14 ++++++++++++++ tests/qemublocktestdata/xml2json/dir-fat-floppy.xml | 11 +++++++++++ tests/qemublocktestdata/xml2json/dir-fat-readonly.json | 14 ++++++++++++++ tests/qemublocktestdata/xml2json/dir-fat-readonly.xml | 10 ++++++++++ 5 files changed, 51 insertions(+) create mode 100644 tests/qemublocktestdata/xml2json/dir-fat-floppy.json create mode 100644 tests/qemublocktestdata/xml2json/dir-fat-floppy.xml create mode 100644 tests/qemublocktestdata/xml2json/dir-fat-readonly.json create mode 100644 tests/qemublocktestdata/xml2json/dir-fat-readonly.xml diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 881d7c17ee..81a2261dab 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -414,6 +414,8 @@ mymain(void) TEST_DISK_TO_JSON("file-vpc-noopts"); TEST_DISK_TO_JSON("file-backing_basic-noopts"); + TEST_DISK_TO_JSON("dir-fat-readonly"); + TEST_DISK_TO_JSON("dir-fat-floppy"); cleanup: virHashFree(diskxmljsondata.schema); diff --git a/tests/qemublocktestdata/xml2json/dir-fat-floppy.json b/tests/qemublocktestdata/xml2json/dir-fat-floppy.json new file mode 100644 index 0000000000..9685acaa8b --- /dev/null +++ b/tests/qemublocktestdata/xml2json/dir-fat-floppy.json @@ -0,0 +1,14 @@ +{ + "node-name": "node-f", + "read-only": true, + "driver": "raw", + "file": { + "driver": "vvfat", + "dir": "/var/somefiles", + "floppy": true, + "rw": false, + "node-name": "node-s", + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/dir-fat-floppy.xml b/tests/qemublocktestdata/xml2json/dir-fat-floppy.xml new file mode 100644 index 0000000000..b7f2d9f8a6 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/dir-fat-floppy.xml @@ -0,0 +1,11 @@ +<disk type='dir' device='floppy'> + <driver name='qemu' type='fat'/> + <source dir='/var/somefiles'> + <privateData> + <nodename storage='node-s' format='node-f'/> + </privateData> + </source> + <target dev='fda'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + <readonly/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/dir-fat-readonly.json b/tests/qemublocktestdata/xml2json/dir-fat-readonly.json new file mode 100644 index 0000000000..7d35d255cc --- /dev/null +++ b/tests/qemublocktestdata/xml2json/dir-fat-readonly.json @@ -0,0 +1,14 @@ +{ + "node-name": "node-f", + "read-only": true, + "driver": "raw", + "file": { + "driver": "vvfat", + "dir": "/var/somefiles", + "floppy": false, + "rw": false, + "node-name": "node-s", + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/dir-fat-readonly.xml b/tests/qemublocktestdata/xml2json/dir-fat-readonly.xml new file mode 100644 index 0000000000..bdb291e412 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/dir-fat-readonly.xml @@ -0,0 +1,10 @@ +<disk type='dir' device='disk'> + <driver name='qemu' type='fat'/> + <source dir='/var/somefiles'> + <privateData> + <nodename storage='node-s' format='node-f'/> + </privateData> + </source> + <target dev='vda'/> + <readonly/> +</disk> -- 2.14.3

Test that the 'aio' option is applied correctly for the 'file' protocol backend and across the backing chain. The top level disk image would generate the following '-drive' cmdline: file-backing_basic-aio_threads: -drive file=/var/lib/libvirt/images/a,format=qcow,if=none,id=drive-dummy,aio=threads -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy file-raw-aio_native: -drive file=/path/to/i.img,format=raw,if=none,id=drive-dummy,cache=none,aio=native -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy,write-cache=on Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 2 + .../xml2json/file-backing_basic-aio_threads.json | 62 ++++++++++++++++++++++ .../xml2json/file-backing_basic-aio_threads.xml | 35 ++++++++++++ .../xml2json/file-raw-aio_native.json | 21 ++++++++ .../xml2json/file-raw-aio_native.xml | 9 ++++ 5 files changed, 129 insertions(+) create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads.xml create mode 100644 tests/qemublocktestdata/xml2json/file-raw-aio_native.json create mode 100644 tests/qemublocktestdata/xml2json/file-raw-aio_native.xml diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 81a2261dab..a79ffa90d8 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -416,6 +416,8 @@ mymain(void) TEST_DISK_TO_JSON("file-backing_basic-noopts"); TEST_DISK_TO_JSON("dir-fat-readonly"); TEST_DISK_TO_JSON("dir-fat-floppy"); + TEST_DISK_TO_JSON("file-raw-aio_native"); + TEST_DISK_TO_JSON("file-backing_basic-aio_threads"); cleanup: virHashFree(diskxmljsondata.schema); diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads.json b/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads.json new file mode 100644 index 0000000000..dcaf905085 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads.json @@ -0,0 +1,62 @@ +{ + "node-name": "node-a-f", + "read-only": false, + "driver": "qcow", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/a", + "aio": "threads", + "node-name": "node-a-s", + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "driver": "qed", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/b", + "aio": "threads", + "node-name": "node-b-s", + "read-only": true, + "discard": "unmap" + }, + "backing": "node-c-f" +} +{ + "node-name": "node-c-f", + "read-only": true, + "driver": "vmdk", + "file": { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ], + "node-name": "node-c-s", + "read-only": true, + "discard": "unmap" + }, + "backing": "node-d-f" +} +{ + "node-name": "node-d-f", + "read-only": true, + "driver": "raw", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/d", + "aio": "threads", + "node-name": "node-d-s", + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads.xml b/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads.xml new file mode 100644 index 0000000000..0bd1388f0f --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-aio_threads.xml @@ -0,0 +1,35 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qcow' io='threads'/> + <source file='/var/lib/libvirt/images/a'> + <privateData> + <nodename storage='node-a-s' format='node-a-f'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qed'/> + <source file='/var/lib/libvirt/images/b'> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='network' index='2'> + <format type='vmdk'/> + <source protocol='gluster' name='images/c'> + <host name='test.org'/> + <privateData> + <nodename storage='node-c-s' format='node-c-f'/> + </privateData> + </source> + <backingStore type='file' index='3'> + <format type='raw'/> + <source file='/var/lib/libvirt/images/d'> + <privateData> + <nodename storage='node-d-s' format='node-d-f'/> + </privateData> + </source> + <backingStore/> + </backingStore> + </backingStore> + </backingStore> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-raw-aio_native.json b/tests/qemublocktestdata/xml2json/file-raw-aio_native.json new file mode 100644 index 0000000000..2752e0b204 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-raw-aio_native.json @@ -0,0 +1,21 @@ +{ + "node-name": "test1", + "read-only": false, + "cache": { + "direct": true, + "no-flush": false + }, + "driver": "raw", + "file": { + "driver": "file", + "filename": "/path/to/i.img", + "aio": "native", + "node-name": "test2", + "cache": { + "direct": true, + "no-flush": false + }, + "read-only": false, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-raw-aio_native.xml b/tests/qemublocktestdata/xml2json/file-raw-aio_native.xml new file mode 100644 index 0000000000..d1b98ff992 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-raw-aio_native.xml @@ -0,0 +1,9 @@ +<disk device='disk'> + <driver name='qemu' type='raw' io='native' cache='none'/> + <source file='/path/to/i.img'> + <privateData> + <nodename format='test1' storage='test2'/> + </privateData> + </source> + <target dev='vda'/> +</disk> -- 2.14.3

Apart from adding test data add a function which sets up fake secrets for the test. The top level disk image would generate the following '-drive' cmdline: -drive file=/path/luks.img,key-secret=test1-encalias,format=luks,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 42 ++++++++++++++++++++++ .../qemublocktestdata/xml2json/file-raw-luks.json | 13 +++++++ tests/qemublocktestdata/xml2json/file-raw-luks.xml | 12 +++++++ 3 files changed, 67 insertions(+) create mode 100644 tests/qemublocktestdata/xml2json/file-raw-luks.json create mode 100644 tests/qemublocktestdata/xml2json/file-raw-luks.xml diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index a79ffa90d8..55d028e9fb 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -145,6 +145,44 @@ testQemuDiskXMLToPropsClear(struct testQemuDiskXMLToJSONData *data) } +static int +testQemuDiskXMLToJSONFakeSecrets(virStorageSourcePtr src) +{ + qemuDomainStorageSourcePrivatePtr srcpriv; + + if (!src->privateData && + !(src->privateData = qemuDomainStorageSourcePrivateNew())) + return -1; + + srcpriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src); + + if (src->auth) { + if (VIR_ALLOC(srcpriv->secinfo) < 0) + return -1; + + srcpriv->secinfo->type = VIR_DOMAIN_SECRET_INFO_TYPE_AES; + if (VIR_STRDUP(srcpriv->secinfo->s.aes.username, src->auth->username) < 0) + return -1; + + if (virAsprintf(&srcpriv->secinfo->s.aes.alias, "%s-secalias", + NULLSTR(src->nodestorage)) < 0) + return -1; + } + + if (src->encryption) { + if (VIR_ALLOC(srcpriv->encinfo) < 0) + return -1; + + srcpriv->encinfo->type = VIR_DOMAIN_SECRET_INFO_TYPE_AES; + if (virAsprintf(&srcpriv->encinfo->s.aes.alias, "%s-encalias", + NULLSTR(src->nodeformat)) < 0) + return -1; + } + + return 0; +} + + static const char *testQemuDiskXMLToJSONPath = abs_srcdir "/qemublocktestdata/xml2json/"; static int @@ -180,6 +218,9 @@ testQemuDiskXMLToProps(const void *opaque) goto cleanup; for (n = disk->src; virStorageSourceIsBacking(n); n = n->backingStore) { + if (testQemuDiskXMLToJSONFakeSecrets(n) < 0) + goto cleanup; + if (!(props = qemuBlockStorageSourceGetBlockdevProps(n))) { if (!data->fail) { VIR_TEST_VERBOSE("failed to generate qemu blockdev props\n"); @@ -418,6 +459,7 @@ mymain(void) TEST_DISK_TO_JSON("dir-fat-floppy"); TEST_DISK_TO_JSON("file-raw-aio_native"); TEST_DISK_TO_JSON("file-backing_basic-aio_threads"); + TEST_DISK_TO_JSON("file-raw-luks"); cleanup: virHashFree(diskxmljsondata.schema); diff --git a/tests/qemublocktestdata/xml2json/file-raw-luks.json b/tests/qemublocktestdata/xml2json/file-raw-luks.json new file mode 100644 index 0000000000..e3d9c4c26b --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-raw-luks.json @@ -0,0 +1,13 @@ +{ + "node-name": "test1", + "read-only": false, + "driver": "luks", + "key-secret": "test1-encalias", + "file": { + "driver": "file", + "filename": "/path/luks.img", + "node-name": "test2", + "read-only": false, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-raw-luks.xml b/tests/qemublocktestdata/xml2json/file-raw-luks.xml new file mode 100644 index 0000000000..1cbff5c83f --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-raw-luks.xml @@ -0,0 +1,12 @@ +<disk device='disk'> + <driver name='qemu' type='raw'/> + <source file='/path/luks.img'> + <encryption format='luks'> + <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> + </encryption> + <privateData> + <nodename format='test1' storage='test2'/> + </privateData> + </source> + <target dev='vda'/> +</disk> -- 2.14.3

Add tests for backing chain handling, including a very long chain which is fully specified in the XML and an unterminated chain. The top level disk image would generate the following '-drive': file-qcow2-backing-chain-encryption.xml: -drive file=/var/lib/libvirt/images/a,encrypt.format=luks, encrypt.key-secret=node-b-f-encalias,format=qcow2,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy file-qcow2-backing-chain-noopts.xml: -drive file=/var/lib/libvirt/images/rhel7.3.1507297895,format=qcow2,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy file-qcow2-backing-chain-unterminated.xml: -drive file=/var/lib/libvirt/images/rhel7.3.1507297895,format=qcow2,if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 3 + .../file-qcow2-backing-chain-encryption.json | 34 ++++++ .../file-qcow2-backing-chain-encryption.xml | 25 ++++ .../xml2json/file-qcow2-backing-chain-noopts.json | 130 +++++++++++++++++++++ .../xml2json/file-qcow2-backing-chain-noopts.xml | 83 +++++++++++++ .../file-qcow2-backing-chain-unterminated.json | 25 ++++ .../file-qcow2-backing-chain-unterminated.xml | 18 +++ 7 files changed, 318 insertions(+) create mode 100644 tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption.json create mode 100644 tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption.xml create mode 100644 tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts.json create mode 100644 tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts.xml create mode 100644 tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated.json create mode 100644 tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated.xml diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 55d028e9fb..44d76bebbb 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -460,6 +460,9 @@ mymain(void) TEST_DISK_TO_JSON("file-raw-aio_native"); TEST_DISK_TO_JSON("file-backing_basic-aio_threads"); TEST_DISK_TO_JSON("file-raw-luks"); + TEST_DISK_TO_JSON("file-qcow2-backing-chain-noopts"); + TEST_DISK_TO_JSON("file-qcow2-backing-chain-unterminated"); + TEST_DISK_TO_JSON("file-qcow2-backing-chain-encryption"); cleanup: virHashFree(diskxmljsondata.schema); diff --git a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption.json b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption.json new file mode 100644 index 0000000000..94e2ecd1e2 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption.json @@ -0,0 +1,34 @@ +{ + "node-name": "node-b-f", + "read-only": false, + "driver": "qcow2", + "encrypt": { + "format": "luks", + "key-secret": "node-b-f-encalias" + }, + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/a", + "node-name": "node-a-s", + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "driver": "qcow2", + "encrypt": { + "format": "aes", + "key-secret": "node-b-f-encalias" + }, + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/b", + "node-name": "node-b-s", + "read-only": true, + "discard": "unmap" + }, + "backing": null +} diff --git a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption.xml b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption.xml new file mode 100644 index 0000000000..4e49be9bef --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-encryption.xml @@ -0,0 +1,25 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qcow2'/> + <source file='/var/lib/libvirt/images/a'> + <encryption format='luks'> + <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> + </encryption> + <privateData> + <nodename storage='node-a-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/b'> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + <encryption format='qcow'> + <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> + </encryption> + </source> + <backingStore/> + </backingStore> + <target dev='vda' bus='virtio'/> + <alias name='virtio-disk0'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts.json b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts.json new file mode 100644 index 0000000000..3e7c08f080 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts.json @@ -0,0 +1,130 @@ +{ + "node-name": "#block126", + "read-only": false, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1507297895", + "node-name": "#block004", + "read-only": false, + "discard": "unmap" + }, + "backing": "#block313" +} +{ + "node-name": "#block313", + "read-only": true, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1484071872", + "node-name": "#block256", + "read-only": true, + "discard": "unmap" + }, + "backing": "#block556" +} +{ + "node-name": "#block556", + "read-only": true, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483615252", + "node-name": "#block418", + "read-only": true, + "discard": "unmap" + }, + "backing": "#block767" +} +{ + "node-name": "#block767", + "read-only": true, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483605924", + "node-name": "#block624", + "read-only": true, + "discard": "unmap" + }, + "backing": "#block937" +} +{ + "node-name": "#block937", + "read-only": true, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483605920", + "node-name": "#block869", + "read-only": true, + "discard": "unmap" + }, + "backing": "#block1157" +} +{ + "node-name": "#block1157", + "read-only": true, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483546244", + "node-name": "#block1047", + "read-only": true, + "discard": "unmap" + }, + "backing": "#block1392" +} +{ + "node-name": "#block1392", + "read-only": true, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483545901", + "node-name": "#block1279", + "read-only": true, + "discard": "unmap" + }, + "backing": "#block1523" +} +{ + "node-name": "#block1523", + "read-only": true, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483545313", + "node-name": "#block1444", + "read-only": true, + "discard": "unmap" + }, + "backing": "#block1742" +} +{ + "node-name": "#block1742", + "read-only": true, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1483536402", + "node-name": "#block1602", + "read-only": true, + "discard": "unmap" + }, + "backing": "#block1909" +} +{ + "node-name": "#block1909", + "read-only": true, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.qcow2", + "node-name": "#block1864", + "read-only": true, + "discard": "unmap" + }, + "backing": null +} diff --git a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts.xml b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts.xml new file mode 100644 index 0000000000..d69d51ebfb --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-noopts.xml @@ -0,0 +1,83 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qcow2'/> + <source file='/var/lib/libvirt/images/rhel7.3.1507297895'> + <privateData> + <nodename storage='#block004' format='#block126'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/rhel7.3.1484071872'> + <privateData> + <nodename storage='#block256' format='#block313'/> + </privateData> + </source> + <backingStore type='file' index='2'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/rhel7.3.1483615252'> + <privateData> + <nodename storage='#block418' format='#block556'/> + </privateData> + </source> + <backingStore type='file' index='3'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/rhel7.3.1483605924'> + <privateData> + <nodename storage='#block624' format='#block767'/> + </privateData> + </source> + <backingStore type='file' index='4'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/rhel7.3.1483605920'> + <privateData> + <nodename storage='#block869' format='#block937'/> + </privateData> + </source> + <backingStore type='file' index='5'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/rhel7.3.1483546244'> + <privateData> + <nodename storage='#block1047' format='#block1157'/> + </privateData> + </source> + <backingStore type='file' index='6'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/rhel7.3.1483545901'> + <privateData> + <nodename storage='#block1279' format='#block1392'/> + </privateData> + </source> + <backingStore type='file' index='7'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/rhel7.3.1483545313'> + <privateData> + <nodename storage='#block1444' format='#block1523'/> + </privateData> + </source> + <backingStore type='file' index='8'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/rhel7.3.1483536402'> + <privateData> + <nodename storage='#block1602' format='#block1742'/> + </privateData> + </source> + <backingStore type='file' index='9'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/rhel7.3.qcow2'> + <privateData> + <nodename storage='#block1864' format='#block1909'/> + </privateData> + </source> + <backingStore/> + </backingStore> + </backingStore> + </backingStore> + </backingStore> + </backingStore> + </backingStore> + </backingStore> + </backingStore> + </backingStore> + <target dev='vda' bus='virtio'/> + <alias name='virtio-disk0'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated.json b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated.json new file mode 100644 index 0000000000..8fcdc48bb0 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated.json @@ -0,0 +1,25 @@ +{ + "node-name": "#block126", + "read-only": false, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1507297895", + "node-name": "#block004", + "read-only": false, + "discard": "unmap" + }, + "backing": "#block313" +} +{ + "node-name": "#block313", + "read-only": true, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/rhel7.3.1484071872", + "node-name": "#block256", + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated.xml b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated.xml new file mode 100644 index 0000000000..29ed9665df --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-qcow2-backing-chain-unterminated.xml @@ -0,0 +1,18 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qcow2'/> + <source file='/var/lib/libvirt/images/rhel7.3.1507297895'> + <privateData> + <nodename storage='#block004' format='#block126'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/rhel7.3.1484071872'> + <privateData> + <nodename storage='#block256' format='#block313'/> + </privateData> + </source> + </backingStore> + <target dev='vda' bus='virtio'/> + <alias name='virtio-disk0'/> +</disk> -- 2.14.3

iscsi and rbd support authentication of the connection. Combine it with encryption of qcow2. The top level disk image would generate the following '-drive' cmdline: -drive file=rbd:rbdpool/rbdimg:id=testuser-rbd:auth_supported=cephx\;none: mon_host=host1.example.com\;host2.example.com, file.password-secret=node-a-s-secalias,encrypt.format=luks, encrypt.key-secret=node-b-f-encalias,format=qcow2, if=none,id=drive-dummy -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- tests/qemublocktest.c | 1 + ...etwork-qcow2-backing-chain-encryption_auth.json | 51 ++++++++++++++++++++++ ...network-qcow2-backing-chain-encryption_auth.xml | 34 +++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth.json create mode 100644 tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth.xml diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 44d76bebbb..34509be543 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -463,6 +463,7 @@ mymain(void) TEST_DISK_TO_JSON("file-qcow2-backing-chain-noopts"); TEST_DISK_TO_JSON("file-qcow2-backing-chain-unterminated"); TEST_DISK_TO_JSON("file-qcow2-backing-chain-encryption"); + TEST_DISK_TO_JSON("network-qcow2-backing-chain-encryption_auth"); cleanup: virHashFree(diskxmljsondata.schema); diff --git a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth.json b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth.json new file mode 100644 index 0000000000..f307ba8805 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth.json @@ -0,0 +1,51 @@ +{ + "node-name": "node-b-f", + "read-only": false, + "driver": "qcow2", + "encrypt": { + "format": "luks", + "key-secret": "node-b-f-encalias" + }, + "file": { + "driver": "rbd", + "pool": "rbdpool", + "image": "rbdimg", + "server": [ + { + "host": "host1.example.com", + "port": "0" + }, + { + "host": "host2.example.com", + "port": "0" + } + ], + "user": "testuser-rbd", + "node-name": "node-a-s", + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "driver": "qcow2", + "encrypt": { + "format": "aes", + "key-secret": "node-b-f-encalias" + }, + "file": { + "driver": "iscsi", + "portal": "example.org:3260", + "target": "iscsitarget", + "lun": 1, + "transport": "tcp", + "user": "testuser-iscsi", + "password-secret": "node-b-s-secalias", + "node-name": "node-b-s", + "read-only": true, + "discard": "unmap" + }, + "backing": null +} diff --git a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth.xml b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth.xml new file mode 100644 index 0000000000..d8cd38866b --- /dev/null +++ b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-encryption_auth.xml @@ -0,0 +1,34 @@ +<disk type='network' device='disk'> + <driver name='qemu' type='qcow2'/> + <source protocol='rbd' name='rbdpool/rbdimg'> + <host name='host1.example.com'/> + <host name='host2.example.com'/> + <encryption format='luks'> + <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> + </encryption> + <auth username='testuser-rbd'> + <secret type='ceph' usage='testuser-rbd-secret'/> + </auth> + <privateData> + <nodename storage='node-a-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='network' index='1'> + <format type='qcow2'/> + <source protocol='iscsi' name='iscsitarget/1'> + <host name='example.org'/> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + <encryption format='qcow'> + <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccc2f80d6f'/> + </encryption> + <auth username='testuser-iscsi'> + <secret type='iscsi' usage='testuser-iscsi-secret'/> + </auth> + </source> + <backingStore/> + </backingStore> + <target dev='vda' bus='virtio'/> + <alias name='virtio-disk0'/> +</disk> -- 2.14.3

The test cases would correspond to the following -drive command lines: file-backing_basic-detect.xml: -drive file=/var/lib/libvirt/images/a,format=qcow,if=none,id=drive-dummy,detect-zeroes=on -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy file-backing_basic-unmap-detect.xml: -drive file=/var/lib/libvirt/images/a,format=qcow,if=none,id=drive-dummy,discard=unmap,detect-zeroes=unmap -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy file-backing_basic-unmap-ignore.xml: -drive file=/var/lib/libvirt/images/a,format=qcow,if=none,id=drive-dummy,discard=ignore,detect-zeroes=on -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy file-backing_basic-unmap.xml: -drive file=/var/lib/libvirt/images/a,format=qcow,if=none,id=drive-dummy,discard=unmap -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy --- tests/qemublocktest.c | 5 ++ .../xml2json/file-backing_basic-detect.json | 60 ++++++++++++++++++++ .../xml2json/file-backing_basic-detect.xml | 35 ++++++++++++ .../xml2json/file-backing_basic-unmap-detect.json | 64 ++++++++++++++++++++++ .../xml2json/file-backing_basic-unmap-detect.xml | 35 ++++++++++++ .../xml2json/file-backing_basic-unmap-discard.json | 0 .../xml2json/file-backing_basic-unmap-ignore.json | 64 ++++++++++++++++++++++ .../xml2json/file-backing_basic-unmap-ignore.xml | 35 ++++++++++++ .../xml2json/file-backing_basic-unmap.json | 63 +++++++++++++++++++++ .../xml2json/file-backing_basic-unmap.xml | 35 ++++++++++++ 10 files changed, 396 insertions(+) create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-detect.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-detect.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap-discard.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-unmap.xml diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 34509be543..4a2051da57 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -465,6 +465,11 @@ mymain(void) TEST_DISK_TO_JSON("file-qcow2-backing-chain-encryption"); TEST_DISK_TO_JSON("network-qcow2-backing-chain-encryption_auth"); + TEST_DISK_TO_JSON("file-backing_basic-unmap"); + TEST_DISK_TO_JSON("file-backing_basic-unmap-detect"); + TEST_DISK_TO_JSON("file-backing_basic-unmap-ignore"); + TEST_DISK_TO_JSON("file-backing_basic-detect"); + cleanup: virHashFree(diskxmljsondata.schema); qemuTestDriverFree(&driver); diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-detect.json b/tests/qemublocktestdata/xml2json/file-backing_basic-detect.json new file mode 100644 index 0000000000..c1e4c40757 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-detect.json @@ -0,0 +1,60 @@ +{ + "node-name": "node-a-f", + "read-only": false, + "detect-zeroes": "on", + "driver": "qcow", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/a", + "node-name": "node-a-s", + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "driver": "qed", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/b", + "node-name": "node-b-s", + "read-only": true, + "discard": "unmap" + }, + "backing": "node-c-f" +} +{ + "node-name": "node-c-f", + "read-only": true, + "driver": "vmdk", + "file": { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ], + "node-name": "node-c-s", + "read-only": true, + "discard": "unmap" + }, + "backing": "node-d-f" +} +{ + "node-name": "node-d-f", + "read-only": true, + "driver": "raw", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/d", + "node-name": "node-d-s", + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-detect.xml b/tests/qemublocktestdata/xml2json/file-backing_basic-detect.xml new file mode 100644 index 0000000000..99c4d58534 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-detect.xml @@ -0,0 +1,35 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qcow' detect_zeroes='unmap'/> + <source file='/var/lib/libvirt/images/a'> + <privateData> + <nodename storage='node-a-s' format='node-a-f'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qed'/> + <source file='/var/lib/libvirt/images/b'> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='network' index='2'> + <format type='vmdk'/> + <source protocol='gluster' name='images/c'> + <host name='test.org'/> + <privateData> + <nodename storage='node-c-s' format='node-c-f'/> + </privateData> + </source> + <backingStore type='file' index='3'> + <format type='raw'/> + <source file='/var/lib/libvirt/images/d'> + <privateData> + <nodename storage='node-d-s' format='node-d-f'/> + </privateData> + </source> + <backingStore/> + </backingStore> + </backingStore> + </backingStore> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect.json b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect.json new file mode 100644 index 0000000000..b00008dd54 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect.json @@ -0,0 +1,64 @@ +{ + "node-name": "node-a-f", + "read-only": false, + "discard": "unmap", + "detect-zeroes": "unmap", + "driver": "qcow", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/a", + "node-name": "node-a-s", + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "discard": "unmap", + "driver": "qed", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/b", + "node-name": "node-b-s", + "read-only": true, + "discard": "unmap" + }, + "backing": "node-c-f" +} +{ + "node-name": "node-c-f", + "read-only": true, + "discard": "unmap", + "driver": "vmdk", + "file": { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ], + "node-name": "node-c-s", + "read-only": true, + "discard": "unmap" + }, + "backing": "node-d-f" +} +{ + "node-name": "node-d-f", + "read-only": true, + "discard": "unmap", + "driver": "raw", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/d", + "node-name": "node-d-s", + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect.xml b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect.xml new file mode 100644 index 0000000000..afccea8b61 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-detect.xml @@ -0,0 +1,35 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qcow' discard='unmap' detect_zeroes='unmap'/> + <source file='/var/lib/libvirt/images/a'> + <privateData> + <nodename storage='node-a-s' format='node-a-f'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qed'/> + <source file='/var/lib/libvirt/images/b'> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='network' index='2'> + <format type='vmdk'/> + <source protocol='gluster' name='images/c'> + <host name='test.org'/> + <privateData> + <nodename storage='node-c-s' format='node-c-f'/> + </privateData> + </source> + <backingStore type='file' index='3'> + <format type='raw'/> + <source file='/var/lib/libvirt/images/d'> + <privateData> + <nodename storage='node-d-s' format='node-d-f'/> + </privateData> + </source> + <backingStore/> + </backingStore> + </backingStore> + </backingStore> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-discard.json b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-discard.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore.json b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore.json new file mode 100644 index 0000000000..5419deafc0 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore.json @@ -0,0 +1,64 @@ +{ + "node-name": "node-a-f", + "read-only": false, + "discard": "ignore", + "detect-zeroes": "on", + "driver": "qcow", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/a", + "node-name": "node-a-s", + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "discard": "ignore", + "driver": "qed", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/b", + "node-name": "node-b-s", + "read-only": true, + "discard": "unmap" + }, + "backing": "node-c-f" +} +{ + "node-name": "node-c-f", + "read-only": true, + "discard": "ignore", + "driver": "vmdk", + "file": { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ], + "node-name": "node-c-s", + "read-only": true, + "discard": "unmap" + }, + "backing": "node-d-f" +} +{ + "node-name": "node-d-f", + "read-only": true, + "discard": "ignore", + "driver": "raw", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/d", + "node-name": "node-d-s", + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore.xml b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore.xml new file mode 100644 index 0000000000..8cd4bb90e4 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap-ignore.xml @@ -0,0 +1,35 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qcow' discard='ignore' detect_zeroes='on'/> + <source file='/var/lib/libvirt/images/a'> + <privateData> + <nodename storage='node-a-s' format='node-a-f'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qed'/> + <source file='/var/lib/libvirt/images/b'> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='network' index='2'> + <format type='vmdk'/> + <source protocol='gluster' name='images/c'> + <host name='test.org'/> + <privateData> + <nodename storage='node-c-s' format='node-c-f'/> + </privateData> + </source> + <backingStore type='file' index='3'> + <format type='raw'/> + <source file='/var/lib/libvirt/images/d'> + <privateData> + <nodename storage='node-d-s' format='node-d-f'/> + </privateData> + </source> + <backingStore/> + </backingStore> + </backingStore> + </backingStore> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap.json b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap.json new file mode 100644 index 0000000000..1efc462c06 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap.json @@ -0,0 +1,63 @@ +{ + "node-name": "node-a-f", + "read-only": false, + "discard": "unmap", + "driver": "qcow", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/a", + "node-name": "node-a-s", + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "discard": "unmap", + "driver": "qed", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/b", + "node-name": "node-b-s", + "read-only": true, + "discard": "unmap" + }, + "backing": "node-c-f" +} +{ + "node-name": "node-c-f", + "read-only": true, + "discard": "unmap", + "driver": "vmdk", + "file": { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ], + "node-name": "node-c-s", + "read-only": true, + "discard": "unmap" + }, + "backing": "node-d-f" +} +{ + "node-name": "node-d-f", + "read-only": true, + "discard": "unmap", + "driver": "raw", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/d", + "node-name": "node-d-s", + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-unmap.xml b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap.xml new file mode 100644 index 0000000000..4c7356b178 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-unmap.xml @@ -0,0 +1,35 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qcow' discard='unmap'/> + <source file='/var/lib/libvirt/images/a'> + <privateData> + <nodename storage='node-a-s' format='node-a-f'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qed'/> + <source file='/var/lib/libvirt/images/b'> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='network' index='2'> + <format type='vmdk'/> + <source protocol='gluster' name='images/c'> + <host name='test.org'/> + <privateData> + <nodename storage='node-c-s' format='node-c-f'/> + </privateData> + </source> + <backingStore type='file' index='3'> + <format type='raw'/> + <source file='/var/lib/libvirt/images/d'> + <privateData> + <nodename storage='node-d-s' format='node-d-f'/> + </privateData> + </source> + <backingStore/> + </backingStore> + </backingStore> + </backingStore> + <target dev='vda'/> +</disk> -- 2.14.3

The test cases would correspond to the following -drive command lines: dir-fat-cache.xml: -drive file=fat:/var/somefiles,if=none,id=drive-dummy,readonly=on,cache=directsync -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy,write-cache=off file-backing_basic-cache-directsync.xml: -drive file=/var/lib/libvirt/images/a,format=qcow2,if=none,id=drive-dummy,cache=directsync -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy,write-cache=off file-backing_basic-cache-none.xml: -drive file=/var/lib/libvirt/images/a,format=qcow2,if=none,id=drive-dummy,cache=none -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy,write-cache=on file-backing_basic-cache-unsafe.xml: -drive file=/var/lib/libvirt/images/a,format=qcow2,if=none,id=drive-dummy,cache=unsafe -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy,write-cache=on file-backing_basic-cache-writeback.xml: -drive file=/var/lib/libvirt/images/a,format=qcow2,if=none,id=drive-dummy,cache=writeback -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy,write-cache=on file-backing_basic-cache-writethrough.xml: -drive file=/var/lib/libvirt/images/a,format=qcow2,if=none,id=drive-dummy,cache=writethrough -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy,write-cache=off network-qcow2-backing-chain-cache-unsafe.xml: -drive file=rbd:rbdpool/rbdimg:id=testuser-rbd:auth_supported=cephx\;none: mon_host=host1.example.com\;host2.example.com, file.password-secret=node-a-s-secalias,format=qcow2, if=none,id=drive-dummy,cache=directsync -device virtio-blk-pci,scsi=off,drive=drive-dummy,id=dummy,write-cache=off --- tests/qemublocktest.c | 8 ++ .../qemublocktestdata/xml2json/dir-fat-cache.json | 22 ++++++ tests/qemublocktestdata/xml2json/dir-fat-cache.xml | 10 +++ .../file-backing_basic-cache-directsync.json | 91 ++++++++++++++++++++++ .../file-backing_basic-cache-directsync.xml | 35 +++++++++ .../xml2json/file-backing_basic-cache-none.json | 91 ++++++++++++++++++++++ .../xml2json/file-backing_basic-cache-none.xml | 35 +++++++++ .../xml2json/file-backing_basic-cache-unsafe.json | 91 ++++++++++++++++++++++ .../xml2json/file-backing_basic-cache-unsafe.xml | 35 +++++++++ .../file-backing_basic-cache-writeback.json | 91 ++++++++++++++++++++++ .../file-backing_basic-cache-writeback.xml | 35 +++++++++ .../file-backing_basic-cache-writethrough.json | 91 ++++++++++++++++++++++ .../file-backing_basic-cache-writethrough.xml | 35 +++++++++ .../network-qcow2-backing-chain-cache-unsafe.json | 57 ++++++++++++++ .../network-qcow2-backing-chain-cache-unsafe.xml | 25 ++++++ 15 files changed, 752 insertions(+) create mode 100644 tests/qemublocktestdata/xml2json/dir-fat-cache.json create mode 100644 tests/qemublocktestdata/xml2json/dir-fat-cache.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-none.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-none.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback.xml create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough.json create mode 100644 tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough.xml create mode 100644 tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe.json create mode 100644 tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe.xml diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index 4a2051da57..a888eab524 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -470,6 +470,14 @@ mymain(void) TEST_DISK_TO_JSON("file-backing_basic-unmap-ignore"); TEST_DISK_TO_JSON("file-backing_basic-detect"); + TEST_DISK_TO_JSON("file-backing_basic-cache-none"); + TEST_DISK_TO_JSON("file-backing_basic-cache-writethrough"); + TEST_DISK_TO_JSON("file-backing_basic-cache-writeback"); + TEST_DISK_TO_JSON("file-backing_basic-cache-directsync"); + TEST_DISK_TO_JSON("file-backing_basic-cache-unsafe"); + TEST_DISK_TO_JSON("network-qcow2-backing-chain-cache-unsafe"); + TEST_DISK_TO_JSON("dir-fat-cache"); + cleanup: virHashFree(diskxmljsondata.schema); qemuTestDriverFree(&driver); diff --git a/tests/qemublocktestdata/xml2json/dir-fat-cache.json b/tests/qemublocktestdata/xml2json/dir-fat-cache.json new file mode 100644 index 0000000000..8c0a045ed5 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/dir-fat-cache.json @@ -0,0 +1,22 @@ +{ + "node-name": "node-f", + "read-only": true, + "cache": { + "direct": true, + "no-flush": false + }, + "driver": "raw", + "file": { + "driver": "vvfat", + "dir": "/var/somefiles", + "floppy": false, + "rw": false, + "node-name": "node-s", + "cache": { + "direct": true, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/dir-fat-cache.xml b/tests/qemublocktestdata/xml2json/dir-fat-cache.xml new file mode 100644 index 0000000000..32143512d1 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/dir-fat-cache.xml @@ -0,0 +1,10 @@ +<disk type='dir' device='disk'> + <driver name='qemu' type='fat' cache='directsync'/> + <source dir='/var/somefiles'> + <privateData> + <nodename storage='node-s' format='node-f'/> + </privateData> + </source> + <target dev='vda'/> + <readonly/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync.json new file mode 100644 index 0000000000..023caf013f --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync.json @@ -0,0 +1,91 @@ +{ + "node-name": "node-a-f", + "read-only": false, + "cache": { + "direct": true, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/a", + "node-name": "node-a-s", + "cache": { + "direct": true, + "no-flush": false + }, + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "cache": { + "direct": true, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/b", + "node-name": "node-b-s", + "cache": { + "direct": true, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + }, + "backing": "node-c-f" +} +{ + "node-name": "node-c-f", + "read-only": true, + "cache": { + "direct": true, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ], + "node-name": "node-c-s", + "cache": { + "direct": true, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + }, + "backing": "node-d-f" +} +{ + "node-name": "node-d-f", + "read-only": true, + "cache": { + "direct": true, + "no-flush": false + }, + "driver": "raw", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/d", + "node-name": "node-d-s", + "cache": { + "direct": true, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync.xml b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync.xml new file mode 100644 index 0000000000..208a3a6c40 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-directsync.xml @@ -0,0 +1,35 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qcow2' cache='directsync'/> + <source file='/var/lib/libvirt/images/a'> + <privateData> + <nodename storage='node-a-s' format='node-a-f'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/b'> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='network' index='2'> + <format type='qcow2'/> + <source protocol='gluster' name='images/c'> + <host name='test.org'/> + <privateData> + <nodename storage='node-c-s' format='node-c-f'/> + </privateData> + </source> + <backingStore type='file' index='3'> + <format type='raw'/> + <source file='/var/lib/libvirt/images/d'> + <privateData> + <nodename storage='node-d-s' format='node-d-f'/> + </privateData> + </source> + <backingStore/> + </backingStore> + </backingStore> + </backingStore> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none.json new file mode 100644 index 0000000000..023caf013f --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none.json @@ -0,0 +1,91 @@ +{ + "node-name": "node-a-f", + "read-only": false, + "cache": { + "direct": true, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/a", + "node-name": "node-a-s", + "cache": { + "direct": true, + "no-flush": false + }, + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "cache": { + "direct": true, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/b", + "node-name": "node-b-s", + "cache": { + "direct": true, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + }, + "backing": "node-c-f" +} +{ + "node-name": "node-c-f", + "read-only": true, + "cache": { + "direct": true, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ], + "node-name": "node-c-s", + "cache": { + "direct": true, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + }, + "backing": "node-d-f" +} +{ + "node-name": "node-d-f", + "read-only": true, + "cache": { + "direct": true, + "no-flush": false + }, + "driver": "raw", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/d", + "node-name": "node-d-s", + "cache": { + "direct": true, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none.xml b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none.xml new file mode 100644 index 0000000000..c7b020684f --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-none.xml @@ -0,0 +1,35 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qcow2' cache='none'/> + <source file='/var/lib/libvirt/images/a'> + <privateData> + <nodename storage='node-a-s' format='node-a-f'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/b'> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='network' index='2'> + <format type='qcow2'/> + <source protocol='gluster' name='images/c'> + <host name='test.org'/> + <privateData> + <nodename storage='node-c-s' format='node-c-f'/> + </privateData> + </source> + <backingStore type='file' index='3'> + <format type='raw'/> + <source file='/var/lib/libvirt/images/d'> + <privateData> + <nodename storage='node-d-s' format='node-d-f'/> + </privateData> + </source> + <backingStore/> + </backingStore> + </backingStore> + </backingStore> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe.json new file mode 100644 index 0000000000..5f6b94a9d5 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe.json @@ -0,0 +1,91 @@ +{ + "node-name": "node-a-f", + "read-only": false, + "cache": { + "direct": false, + "no-flush": true + }, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/a", + "node-name": "node-a-s", + "cache": { + "direct": false, + "no-flush": true + }, + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "cache": { + "direct": false, + "no-flush": true + }, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/b", + "node-name": "node-b-s", + "cache": { + "direct": false, + "no-flush": true + }, + "read-only": true, + "discard": "unmap" + }, + "backing": "node-c-f" +} +{ + "node-name": "node-c-f", + "read-only": true, + "cache": { + "direct": false, + "no-flush": true + }, + "driver": "qcow2", + "file": { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ], + "node-name": "node-c-s", + "cache": { + "direct": false, + "no-flush": true + }, + "read-only": true, + "discard": "unmap" + }, + "backing": "node-d-f" +} +{ + "node-name": "node-d-f", + "read-only": true, + "cache": { + "direct": false, + "no-flush": true + }, + "driver": "raw", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/d", + "node-name": "node-d-s", + "cache": { + "direct": false, + "no-flush": true + }, + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe.xml b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe.xml new file mode 100644 index 0000000000..ff0f37280a --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-unsafe.xml @@ -0,0 +1,35 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qcow2' cache='unsafe'/> + <source file='/var/lib/libvirt/images/a'> + <privateData> + <nodename storage='node-a-s' format='node-a-f'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/b'> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='network' index='2'> + <format type='qcow2'/> + <source protocol='gluster' name='images/c'> + <host name='test.org'/> + <privateData> + <nodename storage='node-c-s' format='node-c-f'/> + </privateData> + </source> + <backingStore type='file' index='3'> + <format type='raw'/> + <source file='/var/lib/libvirt/images/d'> + <privateData> + <nodename storage='node-d-s' format='node-d-f'/> + </privateData> + </source> + <backingStore/> + </backingStore> + </backingStore> + </backingStore> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback.json new file mode 100644 index 0000000000..9dc7d38850 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback.json @@ -0,0 +1,91 @@ +{ + "node-name": "node-a-f", + "read-only": false, + "cache": { + "direct": false, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/a", + "node-name": "node-a-s", + "cache": { + "direct": false, + "no-flush": false + }, + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "cache": { + "direct": false, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/b", + "node-name": "node-b-s", + "cache": { + "direct": false, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + }, + "backing": "node-c-f" +} +{ + "node-name": "node-c-f", + "read-only": true, + "cache": { + "direct": false, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ], + "node-name": "node-c-s", + "cache": { + "direct": false, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + }, + "backing": "node-d-f" +} +{ + "node-name": "node-d-f", + "read-only": true, + "cache": { + "direct": false, + "no-flush": false + }, + "driver": "raw", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/d", + "node-name": "node-d-s", + "cache": { + "direct": false, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback.xml b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback.xml new file mode 100644 index 0000000000..35dd653adc --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writeback.xml @@ -0,0 +1,35 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qcow2' cache='writeback'/> + <source file='/var/lib/libvirt/images/a'> + <privateData> + <nodename storage='node-a-s' format='node-a-f'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/b'> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='network' index='2'> + <format type='qcow2'/> + <source protocol='gluster' name='images/c'> + <host name='test.org'/> + <privateData> + <nodename storage='node-c-s' format='node-c-f'/> + </privateData> + </source> + <backingStore type='file' index='3'> + <format type='raw'/> + <source file='/var/lib/libvirt/images/d'> + <privateData> + <nodename storage='node-d-s' format='node-d-f'/> + </privateData> + </source> + <backingStore/> + </backingStore> + </backingStore> + </backingStore> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough.json b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough.json new file mode 100644 index 0000000000..9dc7d38850 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough.json @@ -0,0 +1,91 @@ +{ + "node-name": "node-a-f", + "read-only": false, + "cache": { + "direct": false, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/a", + "node-name": "node-a-s", + "cache": { + "direct": false, + "no-flush": false + }, + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "cache": { + "direct": false, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/b", + "node-name": "node-b-s", + "cache": { + "direct": false, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + }, + "backing": "node-c-f" +} +{ + "node-name": "node-c-f", + "read-only": true, + "cache": { + "direct": false, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "gluster", + "volume": "images", + "path": "c", + "server": [ + { + "type": "inet", + "host": "test.org", + "port": "24007" + } + ], + "node-name": "node-c-s", + "cache": { + "direct": false, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + }, + "backing": "node-d-f" +} +{ + "node-name": "node-d-f", + "read-only": true, + "cache": { + "direct": false, + "no-flush": false + }, + "driver": "raw", + "file": { + "driver": "file", + "filename": "/var/lib/libvirt/images/d", + "node-name": "node-d-s", + "cache": { + "direct": false, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + } +} diff --git a/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough.xml b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough.xml new file mode 100644 index 0000000000..1b4d9b6697 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/file-backing_basic-cache-writethrough.xml @@ -0,0 +1,35 @@ +<disk type='file' device='disk'> + <driver name='qemu' type='qcow2' cache='writethrough'/> + <source file='/var/lib/libvirt/images/a'> + <privateData> + <nodename storage='node-a-s' format='node-a-f'/> + </privateData> + </source> + <backingStore type='file' index='1'> + <format type='qcow2'/> + <source file='/var/lib/libvirt/images/b'> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='network' index='2'> + <format type='qcow2'/> + <source protocol='gluster' name='images/c'> + <host name='test.org'/> + <privateData> + <nodename storage='node-c-s' format='node-c-f'/> + </privateData> + </source> + <backingStore type='file' index='3'> + <format type='raw'/> + <source file='/var/lib/libvirt/images/d'> + <privateData> + <nodename storage='node-d-s' format='node-d-f'/> + </privateData> + </source> + <backingStore/> + </backingStore> + </backingStore> + </backingStore> + <target dev='vda'/> +</disk> diff --git a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe.json b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe.json new file mode 100644 index 0000000000..de4be359cb --- /dev/null +++ b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe.json @@ -0,0 +1,57 @@ +{ + "node-name": "node-b-f", + "read-only": false, + "cache": { + "direct": true, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "rbd", + "pool": "rbdpool", + "image": "rbdimg", + "server": [ + { + "host": "host1.example.com", + "port": "0" + }, + { + "host": "host2.example.com", + "port": "0" + } + ], + "user": "testuser-rbd", + "node-name": "node-a-s", + "cache": { + "direct": true, + "no-flush": false + }, + "read-only": false, + "discard": "unmap" + }, + "backing": "node-b-f" +} +{ + "node-name": "node-b-f", + "read-only": true, + "cache": { + "direct": true, + "no-flush": false + }, + "driver": "qcow2", + "file": { + "driver": "iscsi", + "portal": "example.org:3260", + "target": "iscsitarget", + "lun": 1, + "transport": "tcp", + "node-name": "node-b-s", + "cache": { + "direct": true, + "no-flush": false + }, + "read-only": true, + "discard": "unmap" + }, + "backing": null +} diff --git a/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe.xml b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe.xml new file mode 100644 index 0000000000..abd48227e3 --- /dev/null +++ b/tests/qemublocktestdata/xml2json/network-qcow2-backing-chain-cache-unsafe.xml @@ -0,0 +1,25 @@ +<disk type='network' device='disk'> + <driver name='qemu' type='qcow2' cache='directsync'/> + <source protocol='rbd' name='rbdpool/rbdimg'> + <host name='host1.example.com'/> + <host name='host2.example.com'/> + <auth username='testuser-rbd'> + <secret type='ceph' usage='testuser-rbd-secret'/> + </auth> + <privateData> + <nodename storage='node-a-s' format='node-b-f'/> + </privateData> + </source> + <backingStore type='network' index='1'> + <format type='qcow2'/> + <source protocol='iscsi' name='iscsitarget/1'> + <host name='example.org'/> + <privateData> + <nodename storage='node-b-s' format='node-b-f'/> + </privateData> + </source> + <backingStore/> + </backingStore> + <target dev='vda' bus='virtio'/> + <alias name='virtio-disk0'/> +</disk> -- 2.14.3
participants (2)
-
Kevin Wolf
-
Peter Krempa