diff options
Diffstat (limited to 'tests')
31 files changed, 990 insertions, 167 deletions
diff --git a/tests/Makefile.include b/tests/Makefile.include index e60488da7d..370de59974 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -70,6 +70,7 @@ check-unit-y += tests/test-throttle$(EXESUF) check-unit-y += tests/test-thread-pool$(EXESUF) check-unit-y += tests/test-hbitmap$(EXESUF) check-unit-y += tests/test-bdrv-drain$(EXESUF) +check-unit-y += tests/test-bdrv-graph-mod$(EXESUF) check-unit-y += tests/test-blockjob$(EXESUF) check-unit-y += tests/test-blockjob-txn$(EXESUF) check-unit-y += tests/test-block-backend$(EXESUF) @@ -561,6 +562,7 @@ tests/test-aio$(EXESUF): tests/test-aio.o $(test-block-obj-y) tests/test-aio-multithread$(EXESUF): tests/test-aio-multithread.o $(test-block-obj-y) tests/test-throttle$(EXESUF): tests/test-throttle.o $(test-block-obj-y) tests/test-bdrv-drain$(EXESUF): tests/test-bdrv-drain.o $(test-block-obj-y) $(test-util-obj-y) +tests/test-bdrv-graph-mod$(EXESUF): tests/test-bdrv-graph-mod.o $(test-block-obj-y) $(test-util-obj-y) tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-util-obj-y) tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y) tests/test-block-backend$(EXESUF): tests/test-block-backend.o $(test-block-obj-y) $(test-util-obj-y) diff --git a/tests/qemu-iotests/045 b/tests/qemu-iotests/045 index 55a5d31ca8..d5484a0ee1 100755 --- a/tests/qemu-iotests/045 +++ b/tests/qemu-iotests/045 @@ -132,7 +132,7 @@ class TestSCMFd(iotests.QMPTestCase): qemu_img('create', '-f', iotests.imgfmt, image0, '128K') # Add an unused monitor, to verify it works fine when two monitor # instances present - self.vm.add_monitor_telnet("0",4445) + self.vm.add_monitor_null() self.vm.launch() def tearDown(self): diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out index 793af2ab96..b900935fbc 100644 --- a/tests/qemu-iotests/051.out +++ b/tests/qemu-iotests/051.out @@ -82,7 +82,7 @@ QEMU X.Y.Z monitor - type 'help' for more information Testing: -drive file=TEST_DIR/t.qcow2,driver=qcow2,backing.file.filename=TEST_DIR/t.qcow2.orig,if=none,id=drive0 -nodefaults QEMU X.Y.Z monitor - type 'help' for more information (qemu) info block -drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) +drive0 (NODE_NAME): json:{"backing": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2.orig"}}, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2"}} (qcow2) Removable device: not locked, tray closed Cache mode: writeback Backing file: TEST_DIR/t.qcow2.orig (chain depth: 1) @@ -172,7 +172,7 @@ QEMU_PROG: -drive driver=null-co,cache=invalid_value: invalid cache option Testing: -drive file=TEST_DIR/t.qcow2,cache=writeback,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults QEMU X.Y.Z monitor - type 'help' for more information (qemu) info block -drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) +drive0 (NODE_NAME): json:{"backing": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2.base"}}, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2"}} (qcow2) Removable device: not locked, tray closed Cache mode: writeback Backing file: TEST_DIR/t.qcow2.base (chain depth: 1) @@ -192,7 +192,7 @@ backing-file: TEST_DIR/t.qcow2.base (file, read-only) Testing: -drive file=TEST_DIR/t.qcow2,cache=writethrough,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults QEMU X.Y.Z monitor - type 'help' for more information (qemu) info block -drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) +drive0 (NODE_NAME): json:{"backing": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2.base"}}, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2"}} (qcow2) Removable device: not locked, tray closed Cache mode: writethrough Backing file: TEST_DIR/t.qcow2.base (chain depth: 1) @@ -212,7 +212,7 @@ backing-file: TEST_DIR/t.qcow2.base (file, read-only) Testing: -drive file=TEST_DIR/t.qcow2,cache=unsafe,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults QEMU X.Y.Z monitor - type 'help' for more information (qemu) info block -drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) +drive0 (NODE_NAME): json:{"backing": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2.base"}}, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2"}} (qcow2) Removable device: not locked, tray closed Cache mode: writeback, ignore flushes Backing file: TEST_DIR/t.qcow2.base (chain depth: 1) diff --git a/tests/qemu-iotests/051.pc.out b/tests/qemu-iotests/051.pc.out index ca64edae6a..8c5c735dfd 100644 --- a/tests/qemu-iotests/051.pc.out +++ b/tests/qemu-iotests/051.pc.out @@ -82,7 +82,7 @@ QEMU X.Y.Z monitor - type 'help' for more information Testing: -drive file=TEST_DIR/t.qcow2,driver=qcow2,backing.file.filename=TEST_DIR/t.qcow2.orig,if=none,id=drive0 -nodefaults QEMU X.Y.Z monitor - type 'help' for more information (qemu) info block -drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) +drive0 (NODE_NAME): json:{"backing": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2.orig"}}, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2"}} (qcow2) Removable device: not locked, tray closed Cache mode: writeback Backing file: TEST_DIR/t.qcow2.orig (chain depth: 1) @@ -244,7 +244,7 @@ QEMU_PROG: -drive driver=null-co,cache=invalid_value: invalid cache option Testing: -drive file=TEST_DIR/t.qcow2,cache=writeback,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults QEMU X.Y.Z monitor - type 'help' for more information (qemu) info block -drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) +drive0 (NODE_NAME): json:{"backing": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2.base"}}, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2"}} (qcow2) Removable device: not locked, tray closed Cache mode: writeback Backing file: TEST_DIR/t.qcow2.base (chain depth: 1) @@ -264,7 +264,7 @@ backing-file: TEST_DIR/t.qcow2.base (file, read-only) Testing: -drive file=TEST_DIR/t.qcow2,cache=writethrough,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults QEMU X.Y.Z monitor - type 'help' for more information (qemu) info block -drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) +drive0 (NODE_NAME): json:{"backing": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2.base"}}, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2"}} (qcow2) Removable device: not locked, tray closed Cache mode: writethrough Backing file: TEST_DIR/t.qcow2.base (chain depth: 1) @@ -284,7 +284,7 @@ backing-file: TEST_DIR/t.qcow2.base (file, read-only) Testing: -drive file=TEST_DIR/t.qcow2,cache=unsafe,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults QEMU X.Y.Z monitor - type 'help' for more information (qemu) info block -drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2) +drive0 (NODE_NAME): json:{"backing": {"driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2.base"}}, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/t.qcow2"}} (qcow2) Removable device: not locked, tray closed Cache mode: writeback, ignore flushes Backing file: TEST_DIR/t.qcow2.base (chain depth: 1) diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110 index b64b3b215a..185ad5437e 100755 --- a/tests/qemu-iotests/110 +++ b/tests/qemu-iotests/110 @@ -29,6 +29,7 @@ status=1 # failure is the default! _cleanup() { _cleanup_test_img + rm -f "$TEST_IMG.copy" } trap "_cleanup; exit \$status" 0 1 2 3 15 @@ -60,7 +61,8 @@ echo '=== Non-reconstructable filename ===' echo # Across blkdebug without a config file, you cannot reconstruct filenames, so -# qemu is incapable of knowing the directory of the top image +# qemu is incapable of knowing the directory of the top image from the filename +# alone. However, using bdrv_dirname(), it should still work. TEST_IMG="json:{ 'driver': '$IMGFMT', 'file': { @@ -85,6 +87,31 @@ echo # omit the image size; it should work anyway _make_test_img -b "$TEST_IMG_REL.base" +echo +echo '=== Nodes without a common directory ===' +echo + +cp "$TEST_IMG" "$TEST_IMG.copy" + +# Should inform us that the actual path of the backing file cannot be determined +TEST_IMG="json:{ + 'driver': '$IMGFMT', + 'file': { + 'driver': 'quorum', + 'vote-threshold': 1, + 'children': [ + { + 'driver': 'file', + 'filename': '$TEST_IMG' + }, + { + 'driver': 'file', + 'filename': '$TEST_IMG.copy' + } + ] + } +}" _img_info | _filter_img_info + # success, all done echo '*** done' diff --git a/tests/qemu-iotests/110.out b/tests/qemu-iotests/110.out index b3584ff87f..46e6a60510 100644 --- a/tests/qemu-iotests/110.out +++ b/tests/qemu-iotests/110.out @@ -14,9 +14,16 @@ backing file: t.IMGFMT.base (actual path: TEST_DIR/t.IMGFMT.base) image: json:{"driver": "IMGFMT", "file": {"set-state.0.event": "read_aio", "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "set-state.0.new_state": 42}} file format: IMGFMT virtual size: 64M (67108864 bytes) -backing file: t.IMGFMT.base (cannot determine actual path) +backing file: t.IMGFMT.base (actual path: TEST_DIR/t.IMGFMT.base) === Backing name is always relative to the backed image === Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=t.IMGFMT.base + +=== Nodes without a common directory === + +image: json:{"driver": "IMGFMT", "file": {"children": [{"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.copy"}], "driver": "quorum", "vote-threshold": 1}} +file format: IMGFMT +virtual size: 64M (67108864 bytes) +backing file: t.IMGFMT.base (cannot determine actual path) *** done diff --git a/tests/qemu-iotests/178 b/tests/qemu-iotests/178 index 3f4b4a4564..927bf06e4d 100755 --- a/tests/qemu-iotests/178 +++ b/tests/qemu-iotests/178 @@ -142,6 +142,14 @@ for ofmt in human json; do # The backing file doesn't need to exist :) $QEMU_IMG measure --output=$ofmt -o backing_file=x \ -f "$fmt" -O "$IMGFMT" "$TEST_IMG" + + echo + echo "== $fmt input image and LUKS encryption ==" + echo + $QEMU_IMG measure --output=$ofmt \ + --object secret,id=sec0,data=base \ + -o encrypt.format=luks,encrypt.key-secret=sec0,encrypt.iter-time=10 \ + -f "$fmt" -O "$IMGFMT" "$TEST_IMG" fi echo diff --git a/tests/qemu-iotests/178.out.qcow2 b/tests/qemu-iotests/178.out.qcow2 index d42d4a4597..55a8dc926f 100644 --- a/tests/qemu-iotests/178.out.qcow2 +++ b/tests/qemu-iotests/178.out.qcow2 @@ -68,6 +68,11 @@ converted image file size in bytes: 458752 required size: 1074135040 fully allocated size: 1074135040 +== qcow2 input image and LUKS encryption == + +required size: 2686976 +fully allocated size: 1076232192 + == qcow2 input image and preallocation (human) == required size: 1074135040 @@ -114,6 +119,11 @@ converted image file size in bytes: 524288 required size: 1074135040 fully allocated size: 1074135040 +== raw input image and LUKS encryption == + +required size: 2686976 +fully allocated size: 1076232192 + == raw input image and preallocation (human) == required size: 1074135040 @@ -205,6 +215,13 @@ converted image file size in bytes: 458752 "fully-allocated": 1074135040 } +== qcow2 input image and LUKS encryption == + +{ + "required": 2686976, + "fully-allocated": 1076232192 +} + == qcow2 input image and preallocation (json) == { @@ -263,6 +280,13 @@ converted image file size in bytes: 524288 "fully-allocated": 1074135040 } +== raw input image and LUKS encryption == + +{ + "required": 2686976, + "fully-allocated": 1076232192 +} + == raw input image and preallocation (json) == { diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out index 91f4db55d3..0f1c23babb 100644 --- a/tests/qemu-iotests/206.out +++ b/tests/qemu-iotests/206.out @@ -1,13 +1,13 @@ === Successful image creation (defaults) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2", "node_name": "imgfile"}} +{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2", "node-name": "imgfile"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "qcow2", "file": "imgfile", "size": 134217728}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "imgfile", "size": 134217728}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -24,12 +24,12 @@ Format specific information: === Successful image creation (inline blockdev-add, explicit defaults) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2", "nocow": false, "preallocation": "off", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2", "nocow": false, "preallocation": "off", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 65536, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2"}, "lazy-refcounts": false, "preallocation": "off", "refcount-bits": 16, "size": 67108864, "version": "v3"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 65536, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2"}, "lazy-refcounts": false, "preallocation": "off", "refcount-bits": 16, "size": 67108864, "version": "v3"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -46,12 +46,12 @@ Format specific information: === Successful image creation (v3 non-default options) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2", "nocow": true, "preallocation": "falloc", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2", "nocow": true, "preallocation": "falloc", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 2097152, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2"}, "lazy-refcounts": true, "preallocation": "metadata", "refcount-bits": 1, "size": 33554432, "version": "v3"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 2097152, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2"}, "lazy-refcounts": true, "preallocation": "metadata", "refcount-bits": 1, "size": 33554432, "version": "v3"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -68,12 +68,12 @@ Format specific information: === Successful image creation (v2 non-default options) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"backing-file": "TEST_DIR/PID-t.qcow2.base", "backing-fmt": "qcow2", "cluster-size": 512, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2"}, "size": 33554432, "version": "v2"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"backing-file": "TEST_DIR/PID-t.qcow2.base", "backing-fmt": "qcow2", "cluster-size": 512, "driver": "qcow2", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2"}, "size": 33554432, "version": "v2"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -90,7 +90,7 @@ Format specific information: === Successful image creation (encrypted) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "qcow2", "encrypt": {"cipher-alg": "twofish-128", "cipher-mode": "ctr", "format": "luks", "hash-alg": "sha1", "iter-time": 10, "ivgen-alg": "plain64", "ivgen-hash-alg": "md5", "key-secret": "keysec0"}, "file": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2"}, "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "encrypt": {"cipher-alg": "twofish-128", "cipher-mode": "ctr", "format": "luks", "hash-alg": "sha1", "iter-time": 10, "ivgen-alg": "plain64", "ivgen-hash-alg": "md5", "key-secret": "keysec0"}, "file": {"driver": "file", "filename": "TEST_DIR/PID-t.qcow2"}, "size": 33554432}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -144,111 +144,111 @@ Format specific information: === Invalid BlockdevRef === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "qcow2", "file": "this doesn't exist", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "this doesn't exist", "size": 33554432}}} {"return": {}} Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} === Invalid sizes === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 1234}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 1234}}} {"return": {}} Job failed: Image size must be a multiple of 512 bytes {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 18446744073709551104}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 18446744073709551104}}} {"return": {}} Job failed: Could not resize image: Image size cannot be negative {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 9223372036854775808}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 9223372036854775808}}} {"return": {}} Job failed: Could not resize image: Image size cannot be negative {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 9223372036854775296}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 9223372036854775296}}} {"return": {}} Job failed: Could not resize image: Failed to grow the L1 table: File too large {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} === Invalid version === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 67108864, "version": "v1"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "size": 67108864, "version": "v1"}}} {"error": {"class": "GenericError", "desc": "Invalid parameter 'v1'"}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "qcow2", "file": "node0", "lazy-refcounts": true, "size": 67108864, "version": "v2"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "lazy-refcounts": true, "size": 67108864, "version": "v2"}}} {"return": {}} Job failed: Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater) {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "qcow2", "file": "node0", "refcount-bits": 8, "size": 67108864, "version": "v2"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "refcount-bits": 8, "size": 67108864, "version": "v2"}}} {"return": {}} Job failed: Different refcount widths than 16 bits require compatibility level 1.1 or above (use version=v3 or greater) {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} === Invalid backing file options === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"backing-file": "/dev/null", "driver": "qcow2", "file": "node0", "preallocation": "full", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"backing-file": "/dev/null", "driver": "qcow2", "file": "node0", "preallocation": "full", "size": 67108864}}} {"return": {}} Job failed: Backing file and preallocation cannot be used at the same time {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"backing-fmt": "qcow2", "driver": "qcow2", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"backing-fmt": "qcow2", "driver": "qcow2", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Backing format cannot be used without backing file {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} === Invalid cluster size === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 1234, "driver": "qcow2", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 1234, "driver": "qcow2", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Cluster size must be a power of two between 512 and 2048k {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 128, "driver": "qcow2", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 128, "driver": "qcow2", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Cluster size must be a power of two between 512 and 2048k {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 4194304, "driver": "qcow2", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 4194304, "driver": "qcow2", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Cluster size must be a power of two between 512 and 2048k {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 0, "driver": "qcow2", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 0, "driver": "qcow2", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Cluster size must be a power of two between 512 and 2048k {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 512, "driver": "qcow2", "file": "node0", "size": 281474976710656}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 512, "driver": "qcow2", "file": "node0", "size": 281474976710656}}} {"return": {}} Job failed: Could not resize image: Failed to grow the L1 table: File too large {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} === Invalid refcount width === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "qcow2", "file": "node0", "refcount-bits": 128, "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "refcount-bits": 128, "size": 67108864}}} {"return": {}} Job failed: Refcount width must be a power of two and may not exceed 64 bits {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "qcow2", "file": "node0", "refcount-bits": 0, "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "refcount-bits": 0, "size": 67108864}}} {"return": {}} Job failed: Refcount width must be a power of two and may not exceed 64 bits {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "qcow2", "file": "node0", "refcount-bits": 7, "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "node0", "refcount-bits": 7, "size": 67108864}}} {"return": {}} Job failed: Refcount width must be a power of two and may not exceed 64 bits {"execute": "job-dismiss", "arguments": {"id": "job0"}} diff --git a/tests/qemu-iotests/207 b/tests/qemu-iotests/207 index c617ee7453..dfd3c51bd1 100755 --- a/tests/qemu-iotests/207 +++ b/tests/qemu-iotests/207 @@ -27,12 +27,16 @@ import re iotests.verify_image_format(supported_fmts=['raw']) iotests.verify_protocol(supported=['ssh']) -def filter_hash(msg): - return re.sub('"hash": "[0-9a-f]+"', '"hash": HASH', msg) +def filter_hash(qmsg): + def _filter(key, value): + if key == 'hash' and re.match('[0-9a-f]+', value): + return 'HASH' + return value + return iotests.filter_qmp(qmsg, _filter) def blockdev_create(vm, options): result = vm.qmp_log('blockdev-create', job_id='job0', options=options, - filters=[iotests.filter_testfiles, filter_hash]) + filters=[iotests.filter_qmp_testfiles, filter_hash]) if 'return' in result: assert result['return'] == {} diff --git a/tests/qemu-iotests/207.out b/tests/qemu-iotests/207.out index 45ac7c2a8f..568e8619d0 100644 --- a/tests/qemu-iotests/207.out +++ b/tests/qemu-iotests/207.out @@ -1,6 +1,6 @@ === Successful image creation (defaults) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "ssh", "location": {"path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -16,7 +16,7 @@ virtual size: 4.0M (4194304 bytes) === Test host-key-check options === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "none"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 8388608}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "none"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 8388608}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -25,7 +25,7 @@ image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.po file format: IMGFMT virtual size: 8.0M (8388608 bytes) -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "known_hosts"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "known_hosts"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -34,13 +34,13 @@ image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.po file format: IMGFMT virtual size: 4.0M (4194304 bytes) -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "wrong", "mode": "hash", "type": "md5"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 2097152}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "wrong", "mode": "hash", "type": "md5"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 2097152}}} {"return": {}} Job failed: remote host key does not match host_key_check 'wrong' {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": HASH, "mode": "hash", "type": "md5"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 8388608}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "HASH", "mode": "hash", "type": "md5"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 8388608}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -49,13 +49,13 @@ image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.po file format: IMGFMT virtual size: 8.0M (8388608 bytes) -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "wrong", "mode": "hash", "type": "sha1"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 2097152}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "wrong", "mode": "hash", "type": "sha1"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 2097152}}} {"return": {}} Job failed: remote host key does not match host_key_check 'wrong' {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": HASH, "mode": "hash", "type": "sha1"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"hash": "HASH", "mode": "hash", "type": "sha1"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -66,13 +66,13 @@ virtual size: 4.0M (4194304 bytes) === Invalid path and user === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "none"}, "path": "/this/is/not/an/existing/path", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "none"}, "path": "/this/is/not/an/existing/path", "server": {"host": "127.0.0.1", "port": "22"}}, "size": 4194304}}} {"return": {}} Job failed: failed to open remote file '/this/is/not/an/existing/path': Failed opening remote file (libssh2 error code: -31) {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "none"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}, "user": "invalid user"}, "size": 4194304}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "ssh", "location": {"host-key-check": {"mode": "none"}, "path": "TEST_DIR/PID-t.img", "server": {"host": "127.0.0.1", "port": "22"}, "user": "invalid user"}, "size": 4194304}}} {"return": {}} Job failed: failed to authenticate using publickey authentication and the identities held by your ssh-agent {"execute": "job-dismiss", "arguments": {"id": "job0"}} diff --git a/tests/qemu-iotests/210 b/tests/qemu-iotests/210 index d142841e2b..565e3b7b9b 100755 --- a/tests/qemu-iotests/210 +++ b/tests/qemu-iotests/210 @@ -27,7 +27,8 @@ iotests.verify_image_format(supported_fmts=['luks']) iotests.verify_protocol(supported=['file']) def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', job_id='job0', options=options) + result = vm.qmp_log('blockdev-create', job_id='job0', options=options, + filters=[iotests.filter_qmp_testfiles]) if 'return' in result: assert result['return'] == {} @@ -53,7 +54,7 @@ with iotests.FilePath('t.luks') as disk_path, \ 'size': 0 }) vm.qmp_log('blockdev-add', driver='file', filename=disk_path, - node_name='imgfile') + node_name='imgfile', filters=[iotests.filter_qmp_testfiles]) blockdev_create(vm, { 'driver': imgfmt, 'file': 'imgfile', diff --git a/tests/qemu-iotests/210.out b/tests/qemu-iotests/210.out index 923cb05117..a3692ce00d 100644 --- a/tests/qemu-iotests/210.out +++ b/tests/qemu-iotests/210.out @@ -1,13 +1,13 @@ === Successful image creation (defaults) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.luks", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.luks", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.luks", "node_name": "imgfile"}} +{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.luks", "node-name": "imgfile"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "luks", "file": "imgfile", "iter-time": 10, "key-secret": "keysec0", "size": 134217728}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "luks", "file": "imgfile", "iter-time": 10, "key-secret": "keysec0", "size": 134217728}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -54,12 +54,12 @@ Format specific information: === Successful image creation (with non-default options) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.luks", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.luks", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cipher-alg": "twofish-128", "cipher-mode": "ctr", "driver": "luks", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.luks"}, "hash-alg": "sha1", "iter-time": 10, "ivgen-alg": "plain64", "ivgen-hash-alg": "md5", "key-secret": "keysec0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cipher-alg": "twofish-128", "cipher-mode": "ctr", "driver": "luks", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.luks"}, "hash-alg": "sha1", "iter-time": 10, "ivgen-alg": "plain64", "ivgen-hash-alg": "md5", "key-secret": "keysec0", "size": 67108864}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -106,7 +106,7 @@ Format specific information: === Invalid BlockdevRef === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "luks", "file": "this doesn't exist", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "luks", "file": "this doesn't exist", "size": 67108864}}} {"return": {}} Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist {"execute": "job-dismiss", "arguments": {"id": "job0"}} @@ -114,7 +114,7 @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi === Zero size === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "luks", "file": "node0", "iter-time": 10, "key-secret": "keysec0", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "luks", "file": "node0", "iter-time": 10, "key-secret": "keysec0", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -161,19 +161,19 @@ Format specific information: === Invalid sizes === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "luks", "file": "node0", "key-secret": "keysec0", "size": 18446744073709551104}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "luks", "file": "node0", "key-secret": "keysec0", "size": 18446744073709551104}}} {"return": {}} Job failed: The requested file size is too large {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "luks", "file": "node0", "key-secret": "keysec0", "size": 9223372036854775808}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "luks", "file": "node0", "key-secret": "keysec0", "size": 9223372036854775808}}} {"return": {}} Job failed: The requested file size is too large {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "luks", "file": "node0", "key-secret": "keysec0", "size": 9223372036854775296}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "luks", "file": "node0", "key-secret": "keysec0", "size": 9223372036854775296}}} {"return": {}} Job failed: The requested file size is too large {"execute": "job-dismiss", "arguments": {"id": "job0"}} @@ -181,13 +181,13 @@ Job failed: The requested file size is too large === Resize image with invalid sizes === -{"execute": "block_resize", "arguments": {"node_name": "node1", "size": 9223372036854775296}} +{"execute": "block_resize", "arguments": {"node-name": "node1", "size": 9223372036854775296}} {"error": {"class": "GenericError", "desc": "The requested file size is too large"}} -{"execute": "block_resize", "arguments": {"node_name": "node1", "size": 9223372036854775808}} +{"execute": "block_resize", "arguments": {"node-name": "node1", "size": 9223372036854775808}} {"error": {"class": "GenericError", "desc": "Invalid parameter type for 'size', expected: integer"}} -{"execute": "block_resize", "arguments": {"node_name": "node1", "size": 18446744073709551104}} +{"execute": "block_resize", "arguments": {"node-name": "node1", "size": 18446744073709551104}} {"error": {"class": "GenericError", "desc": "Invalid parameter type for 'size', expected: integer"}} -{"execute": "block_resize", "arguments": {"node_name": "node1", "size": -9223372036854775808}} +{"execute": "block_resize", "arguments": {"node-name": "node1", "size": -9223372036854775808}} {"error": {"class": "GenericError", "desc": "Parameter 'size' expects a >0 size"}} image: json:{"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_IMG"}, "key-secret": "keysec0"} file format: IMGFMT diff --git a/tests/qemu-iotests/211 b/tests/qemu-iotests/211 index 7b7985db6c..6afc894f76 100755 --- a/tests/qemu-iotests/211 +++ b/tests/qemu-iotests/211 @@ -27,11 +27,14 @@ iotests.verify_image_format(supported_fmts=['vdi']) iotests.verify_protocol(supported=['file']) def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', job_id='job0', options=options) + result = vm.qmp_log('blockdev-create', job_id='job0', options=options, + filters=[iotests.filter_qmp_testfiles]) if 'return' in result: assert result['return'] == {} - vm.run_job('job0') + error = vm.run_job('job0') + if error and 'Could not allocate bmap' in error: + iotests.notrun('Insufficient memory') iotests.log("") with iotests.FilePath('t.vdi') as disk_path, \ @@ -51,7 +54,7 @@ with iotests.FilePath('t.vdi') as disk_path, \ 'size': 0 }) vm.qmp_log('blockdev-add', driver='file', filename=disk_path, - node_name='imgfile') + node_name='imgfile', filters=[iotests.filter_qmp_testfiles]) blockdev_create(vm, { 'driver': imgfmt, 'file': 'imgfile', diff --git a/tests/qemu-iotests/211.out b/tests/qemu-iotests/211.out index eebb0ea086..682adc2a10 100644 --- a/tests/qemu-iotests/211.out +++ b/tests/qemu-iotests/211.out @@ -1,13 +1,13 @@ === Successful image creation (defaults) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vdi", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vdi", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vdi", "node_name": "imgfile"}} +{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vdi", "node-name": "imgfile"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vdi", "file": "imgfile", "size": 134217728}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vdi", "file": "imgfile", "size": 134217728}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -21,12 +21,12 @@ cluster_size: 1048576 === Successful image creation (explicit defaults) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vdi", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vdi", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vdi", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vdi"}, "preallocation": "off", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vdi", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vdi"}, "preallocation": "off", "size": 67108864}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -40,12 +40,12 @@ cluster_size: 1048576 === Successful image creation (with non-default options) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vdi", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vdi", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vdi", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vdi"}, "preallocation": "metadata", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vdi", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vdi"}, "preallocation": "metadata", "size": 33554432}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -60,7 +60,7 @@ cluster_size: 1048576 === Invalid BlockdevRef === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vdi", "file": "this doesn't exist", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vdi", "file": "this doesn't exist", "size": 33554432}}} {"return": {}} Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist {"execute": "job-dismiss", "arguments": {"id": "job0"}} @@ -68,7 +68,7 @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi === Zero size === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vdi", "file": "node0", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vdi", "file": "node0", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -80,7 +80,7 @@ cluster_size: 1048576 === Maximum size === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vdi", "file": "node0", "size": 562949819203584}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vdi", "file": "node0", "size": 562949819203584}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -92,19 +92,19 @@ cluster_size: 1048576 === Invalid sizes === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vdi", "file": "node0", "size": 18446744073709551104}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vdi", "file": "node0", "size": 18446744073709551104}}} {"return": {}} Job failed: Unsupported VDI image size (size is 0xfffffffffffffe00, max supported is 0x1fffff8000000) {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vdi", "file": "node0", "size": 9223372036854775808}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vdi", "file": "node0", "size": 9223372036854775808}}} {"return": {}} Job failed: Unsupported VDI image size (size is 0x8000000000000000, max supported is 0x1fffff8000000) {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vdi", "file": "node0", "size": 562949819203585}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vdi", "file": "node0", "size": 562949819203585}}} {"return": {}} Job failed: Unsupported VDI image size (size is 0x1fffff8000001, max supported is 0x1fffff8000000) {"execute": "job-dismiss", "arguments": {"id": "job0"}} diff --git a/tests/qemu-iotests/212 b/tests/qemu-iotests/212 index 95c8810d83..42b74f208b 100755 --- a/tests/qemu-iotests/212 +++ b/tests/qemu-iotests/212 @@ -27,7 +27,8 @@ iotests.verify_image_format(supported_fmts=['parallels']) iotests.verify_protocol(supported=['file']) def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', job_id='job0', options=options) + result = vm.qmp_log('blockdev-create', job_id='job0', options=options, + filters=[iotests.filter_qmp_testfiles]) if 'return' in result: assert result['return'] == {} @@ -51,7 +52,7 @@ with iotests.FilePath('t.parallels') as disk_path, \ 'size': 0 }) vm.qmp_log('blockdev-add', driver='file', filename=disk_path, - node_name='imgfile') + node_name='imgfile', filters=[iotests.filter_qmp_testfiles]) blockdev_create(vm, { 'driver': imgfmt, 'file': 'imgfile', diff --git a/tests/qemu-iotests/212.out b/tests/qemu-iotests/212.out index 01da467282..22810720cf 100644 --- a/tests/qemu-iotests/212.out +++ b/tests/qemu-iotests/212.out @@ -1,13 +1,13 @@ === Successful image creation (defaults) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.parallels", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.parallels", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.parallels", "node_name": "imgfile"}} +{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.parallels", "node-name": "imgfile"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "parallels", "file": "imgfile", "size": 134217728}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "parallels", "file": "imgfile", "size": 134217728}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -18,12 +18,12 @@ virtual size: 128M (134217728 bytes) === Successful image creation (explicit defaults) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.parallels", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.parallels", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 1048576, "driver": "parallels", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.parallels"}, "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 1048576, "driver": "parallels", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.parallels"}, "size": 67108864}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -34,12 +34,12 @@ virtual size: 64M (67108864 bytes) === Successful image creation (with non-default options) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.parallels", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.parallels", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 65536, "driver": "parallels", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.parallels"}, "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 65536, "driver": "parallels", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.parallels"}, "size": 33554432}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -50,7 +50,7 @@ virtual size: 32M (33554432 bytes) === Invalid BlockdevRef === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "parallels", "file": "this doesn't exist", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "parallels", "file": "this doesn't exist", "size": 33554432}}} {"return": {}} Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist {"execute": "job-dismiss", "arguments": {"id": "job0"}} @@ -58,7 +58,7 @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi === Zero size === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -69,7 +69,7 @@ virtual size: 0 (0 bytes) === Maximum size === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 4503599627369984}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 4503599627369984}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -80,31 +80,31 @@ virtual size: 4096T (4503599627369984 bytes) === Invalid sizes === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 1234}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 1234}}} {"return": {}} Job failed: Image size must be a multiple of 512 bytes {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 18446744073709551104}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 18446744073709551104}}} {"return": {}} Job failed: Image size is too large for this cluster size {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 9223372036854775808}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 9223372036854775808}}} {"return": {}} Job failed: Image size is too large for this cluster size {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 9223372036854775296}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 9223372036854775296}}} {"return": {}} Job failed: Image size is too large for this cluster size {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 4503599627370497}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "parallels", "file": "node0", "size": 4503599627370497}}} {"return": {}} Job failed: Image size is too large for this cluster size {"execute": "job-dismiss", "arguments": {"id": "job0"}} @@ -112,43 +112,43 @@ Job failed: Image size is too large for this cluster size === Invalid cluster size === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 1234, "driver": "parallels", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 1234, "driver": "parallels", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Cluster size must be a multiple of 512 bytes {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 128, "driver": "parallels", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 128, "driver": "parallels", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Cluster size must be a multiple of 512 bytes {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 4294967296, "driver": "parallels", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 4294967296, "driver": "parallels", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Cluster size is too large {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 9223372036854775808, "driver": "parallels", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 9223372036854775808, "driver": "parallels", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Cluster size is too large {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 18446744073709551104, "driver": "parallels", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 18446744073709551104, "driver": "parallels", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Cluster size is too large {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 0, "driver": "parallels", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 0, "driver": "parallels", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Image size is too large for this cluster size {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"cluster-size": 512, "driver": "parallels", "file": "node0", "size": 281474976710656}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"cluster-size": 512, "driver": "parallels", "file": "node0", "size": 281474976710656}}} {"return": {}} Job failed: Image size is too large for this cluster size {"execute": "job-dismiss", "arguments": {"id": "job0"}} diff --git a/tests/qemu-iotests/213 b/tests/qemu-iotests/213 index 4054439e3c..5604f3cebb 100755 --- a/tests/qemu-iotests/213 +++ b/tests/qemu-iotests/213 @@ -27,7 +27,8 @@ iotests.verify_image_format(supported_fmts=['vhdx']) iotests.verify_protocol(supported=['file']) def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', job_id='job0', options=options) + result = vm.qmp_log('blockdev-create', job_id='job0', options=options, + filters=[iotests.filter_qmp_testfiles]) if 'return' in result: assert result['return'] == {} @@ -51,7 +52,7 @@ with iotests.FilePath('t.vhdx') as disk_path, \ 'size': 0 }) vm.qmp_log('blockdev-add', driver='file', filename=disk_path, - node_name='imgfile') + node_name='imgfile', filters=[iotests.filter_qmp_testfiles]) blockdev_create(vm, { 'driver': imgfmt, 'file': 'imgfile', diff --git a/tests/qemu-iotests/213.out b/tests/qemu-iotests/213.out index 0c9d65b2fe..169083e08e 100644 --- a/tests/qemu-iotests/213.out +++ b/tests/qemu-iotests/213.out @@ -1,13 +1,13 @@ === Successful image creation (defaults) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vhdx", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vhdx", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vhdx", "node_name": "imgfile"}} +{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vhdx", "node-name": "imgfile"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vhdx", "file": "imgfile", "size": 134217728}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vhdx", "file": "imgfile", "size": 134217728}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -19,12 +19,12 @@ cluster_size: 8388608 === Successful image creation (explicit defaults) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vhdx", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vhdx", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"block-size": 8388608, "block-state-zero": true, "driver": "vhdx", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vhdx"}, "log-size": 1048576, "size": 67108864, "subformat": "dynamic"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"block-size": 8388608, "block-state-zero": true, "driver": "vhdx", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vhdx"}, "log-size": 1048576, "size": 67108864, "subformat": "dynamic"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -36,12 +36,12 @@ cluster_size: 8388608 === Successful image creation (with non-default options) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vhdx", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vhdx", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"block-size": 268435456, "block-state-zero": false, "driver": "vhdx", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vhdx"}, "log-size": 8388608, "size": 33554432, "subformat": "fixed"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"block-size": 268435456, "block-state-zero": false, "driver": "vhdx", "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vhdx"}, "log-size": 8388608, "size": 33554432, "subformat": "fixed"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -53,7 +53,7 @@ cluster_size: 268435456 === Invalid BlockdevRef === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vhdx", "file": "this doesn't exist", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vhdx", "file": "this doesn't exist", "size": 33554432}}} {"return": {}} Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist {"execute": "job-dismiss", "arguments": {"id": "job0"}} @@ -61,7 +61,7 @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi === Zero size === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vhdx", "file": "node0", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vhdx", "file": "node0", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -73,7 +73,7 @@ cluster_size: 8388608 === Maximum size === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vhdx", "file": "node0", "size": 70368744177664}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vhdx", "file": "node0", "size": 70368744177664}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -85,25 +85,25 @@ cluster_size: 67108864 === Invalid sizes === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vhdx", "file": "node0", "size": 18446744073709551104}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vhdx", "file": "node0", "size": 18446744073709551104}}} {"return": {}} Job failed: Image size too large; max of 64TB {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vhdx", "file": "node0", "size": 9223372036854775808}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vhdx", "file": "node0", "size": 9223372036854775808}}} {"return": {}} Job failed: Image size too large; max of 64TB {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vhdx", "file": "node0", "size": 9223372036854775296}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vhdx", "file": "node0", "size": 9223372036854775296}}} {"return": {}} Job failed: Image size too large; max of 64TB {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vhdx", "file": "node0", "size": 70368744177665}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vhdx", "file": "node0", "size": 70368744177665}}} {"return": {}} Job failed: Image size too large; max of 64TB {"execute": "job-dismiss", "arguments": {"id": "job0"}} @@ -111,31 +111,31 @@ Job failed: Image size too large; max of 64TB === Invalid block size === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"block-size": 1234567, "driver": "vhdx", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"block-size": 1234567, "driver": "vhdx", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Block size must be a multiple of 1 MB {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"block-size": 128, "driver": "vhdx", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"block-size": 128, "driver": "vhdx", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Block size must be a multiple of 1 MB {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"block-size": 3145728, "driver": "vhdx", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"block-size": 3145728, "driver": "vhdx", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Block size must be a power of two {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"block-size": 536870912, "driver": "vhdx", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"block-size": 536870912, "driver": "vhdx", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Block size must not exceed 268435456 {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"block-size": 0, "driver": "vhdx", "file": "node0", "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"block-size": 0, "driver": "vhdx", "file": "node0", "size": 67108864}}} {"return": {}} Job failed: Block size must be a multiple of 1 MB {"execute": "job-dismiss", "arguments": {"id": "job0"}} @@ -143,25 +143,25 @@ Job failed: Block size must be a multiple of 1 MB === Invalid log size === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vhdx", "file": "node0", "log-size": 1234567, "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vhdx", "file": "node0", "log-size": 1234567, "size": 67108864}}} {"return": {}} Job failed: Log size must be a multiple of 1 MB {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vhdx", "file": "node0", "log-size": 128, "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vhdx", "file": "node0", "log-size": 128, "size": 67108864}}} {"return": {}} Job failed: Log size must be a multiple of 1 MB {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vhdx", "file": "node0", "log-size": 4294967296, "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vhdx", "file": "node0", "log-size": 4294967296, "size": 67108864}}} {"return": {}} Job failed: Log size must be smaller than 4 GB {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vhdx", "file": "node0", "log-size": 0, "size": 67108864}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vhdx", "file": "node0", "log-size": 0, "size": 67108864}}} {"return": {}} Job failed: Log size must be a multiple of 1 MB {"execute": "job-dismiss", "arguments": {"id": "job0"}} diff --git a/tests/qemu-iotests/224 b/tests/qemu-iotests/224 new file mode 100755 index 0000000000..b4dfaa639f --- /dev/null +++ b/tests/qemu-iotests/224 @@ -0,0 +1,139 @@ +#!/usr/bin/env python +# +# Test json:{} filenames with qemu-internal BDSs +# (the one of commit, to be precise) +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Creator/Owner: Max Reitz <mreitz@redhat.com> + +import iotests +from iotests import log, qemu_img, qemu_io_silent, filter_qmp_testfiles, \ + filter_qmp_imgfmt +import json + +# Need backing file support (for arbitrary backing formats) +iotests.verify_image_format(supported_fmts=['qcow2', 'qcow', 'qed']) +iotests.verify_platform(['linux']) + + +# There are two variations of this test: +# (1) We do not set filter_node_name. In that case, the commit_top +# driver should not appear anywhere. +# (2) We do set filter_node_name. In that case, it should appear. +# +# This for loop executes both. +for filter_node_name in False, True: + log('') + log('--- filter_node_name: %s ---' % filter_node_name) + log('') + + with iotests.FilePath('base.img') as base_img_path, \ + iotests.FilePath('mid.img') as mid_img_path, \ + iotests.FilePath('top.img') as top_img_path, \ + iotests.VM() as vm: + + assert qemu_img('create', '-f', iotests.imgfmt, + base_img_path, '64M') == 0 + assert qemu_img('create', '-f', iotests.imgfmt, '-b', base_img_path, + mid_img_path) == 0 + assert qemu_img('create', '-f', iotests.imgfmt, '-b', mid_img_path, + top_img_path) == 0 + + # Something to commit + assert qemu_io_silent(mid_img_path, '-c', 'write -P 1 0 1M') == 0 + + vm.launch() + + # Change the bottom-most image's backing file (to null-co://) + # to enforce json:{} filenames + vm.qmp_log('blockdev-add', + node_name='top', + driver=iotests.imgfmt, + file={ + 'driver': 'file', + 'filename': top_img_path + }, + backing={ + 'node-name': 'mid', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': mid_img_path + }, + 'backing': { + 'node-name': 'base', + 'driver': iotests.imgfmt, + 'file': { + 'driver': 'file', + 'filename': base_img_path + }, + 'backing': { + 'driver': 'null-co' + } + } + }, + filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) + + # As long as block-commit does not accept node names, we have to + # get our mid/base filenames here + mid_name = vm.node_info('mid')['image']['filename'] + base_name = vm.node_info('base')['image']['filename'] + + assert mid_name[:5] == 'json:' + assert base_name[:5] == 'json:' + + # Start the block job + if filter_node_name: + vm.qmp_log('block-commit', + job_id='commit', + device='top', + filter_node_name='filter_node', + top=mid_name, + base=base_name, + speed=1, + filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) + else: + vm.qmp_log('block-commit', + job_id='commit', + device='top', + top=mid_name, + base=base_name, + speed=1, + filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) + + vm.qmp_log('job-pause', id='commit') + + # Get and parse top's json:{} filename + top_name = vm.node_info('top')['image']['filename'] + + vm.shutdown() + + assert top_name[:5] == 'json:' + top_options = json.loads(top_name[5:]) + + if filter_node_name: + # This should be present and set + assert top_options['backing']['driver'] == 'commit_top' + # And the mid image is commit_top's backing image + mid_options = top_options['backing']['backing'] + else: + # The mid image should appear as the immediate backing BDS + # of top + mid_options = top_options['backing'] + + assert mid_options['driver'] == iotests.imgfmt + assert mid_options['file']['filename'] == mid_img_path diff --git a/tests/qemu-iotests/224.out b/tests/qemu-iotests/224.out new file mode 100644 index 0000000000..23374a1d29 --- /dev/null +++ b/tests/qemu-iotests/224.out @@ -0,0 +1,18 @@ + +--- filter_node_name: False --- + +{"execute": "blockdev-add", "arguments": {"backing": {"backing": {"backing": {"driver": "null-co"}, "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-base.img"}, "node-name": "base"}, "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-mid.img"}, "node-name": "mid"}, "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top.img"}, "node-name": "top"}} +{"return": {}} +{"execute": "block-commit", "arguments": {"base": "json:{\"backing\": {\"driver\": \"null-co\"}, \"driver\": \"IMGFMT\", \"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/PID-base.img\"}}", "device": "top", "job-id": "commit", "speed": 1, "top": "json:{\"backing\": {\"backing\": {\"driver\": \"null-co\"}, \"driver\": \"IMGFMT\", \"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/PID-base.img\"}}, \"driver\": \"IMGFMT\", \"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/PID-mid.img\"}}"}} +{"return": {}} +{"execute": "job-pause", "arguments": {"id": "commit"}} +{"return": {}} + +--- filter_node_name: True --- + +{"execute": "blockdev-add", "arguments": {"backing": {"backing": {"backing": {"driver": "null-co"}, "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-base.img"}, "node-name": "base"}, "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-mid.img"}, "node-name": "mid"}, "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top.img"}, "node-name": "top"}} +{"return": {}} +{"execute": "block-commit", "arguments": {"base": "json:{\"backing\": {\"driver\": \"null-co\"}, \"driver\": \"IMGFMT\", \"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/PID-base.img\"}}", "device": "top", "filter-node-name": "filter_node", "job-id": "commit", "speed": 1, "top": "json:{\"backing\": {\"backing\": {\"driver\": \"null-co\"}, \"driver\": \"IMGFMT\", \"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/PID-base.img\"}}, \"driver\": \"IMGFMT\", \"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/PID-mid.img\"}}"}} +{"return": {}} +{"execute": "job-pause", "arguments": {"id": "commit"}} +{"return": {}} diff --git a/tests/qemu-iotests/228 b/tests/qemu-iotests/228 new file mode 100755 index 0000000000..9a50afd205 --- /dev/null +++ b/tests/qemu-iotests/228 @@ -0,0 +1,239 @@ +#!/usr/bin/env python +# +# Test for when a backing file is considered overridden (thus, a +# json:{} filename is generated for the overlay) and when it is not +# +# Copyright (C) 2018 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# Creator/Owner: Max Reitz <mreitz@redhat.com> + +import iotests +from iotests import log, qemu_img, filter_testfiles, filter_imgfmt, \ + filter_qmp_testfiles, filter_qmp_imgfmt + +# Need backing file and change-backing-file support +iotests.verify_image_format(supported_fmts=['qcow2', 'qed']) +iotests.verify_platform(['linux']) + + +def log_node_info(node): + log('') + + log('bs->filename: ' + node['image']['filename'], + filters=[filter_testfiles, filter_imgfmt]) + log('bs->backing_file: ' + node['backing_file'], + filters=[filter_testfiles, filter_imgfmt]) + + if 'backing-image' in node['image']: + log('bs->backing->bs->filename: ' + + node['image']['backing-image']['filename'], + filters=[filter_testfiles, filter_imgfmt]) + else: + log('bs->backing: (none)') + + log('') + + +with iotests.FilePath('base.img') as base_img_path, \ + iotests.FilePath('top.img') as top_img_path, \ + iotests.VM() as vm: + + assert qemu_img('create', '-f', iotests.imgfmt, base_img_path, '64M') == 0 + # Choose a funny way to describe the backing filename + assert qemu_img('create', '-f', iotests.imgfmt, '-b', + 'file:' + base_img_path, top_img_path) == 0 + + vm.launch() + + log('--- Implicit backing file ---') + log('') + + vm.qmp_log('blockdev-add', + node_name='node0', + driver=iotests.imgfmt, + file={ + 'driver': 'file', + 'filename': top_img_path + }, + filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) + + # Filename should be plain, and the backing filename should not + # contain the "file:" prefix + log_node_info(vm.node_info('node0')) + + vm.qmp_log('blockdev-del', node_name='node0') + + log('') + log('--- change-backing-file ---') + log('') + + vm.qmp_log('blockdev-add', + node_name='node0', + driver=iotests.imgfmt, + file={ + 'driver': 'file', + 'filename': top_img_path + }, + filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) + + # Changing the backing file to a qemu-reported filename should + # result in qemu accepting the corresponding BDS as the implicit + # backing BDS (and thus not generate a json:{} filename). + # So, first, query the backing filename. + + backing_filename = \ + vm.node_info('node0')['image']['backing-image']['filename'] + + # Next, change the backing file to something different + + vm.qmp_log('change-backing-file', + image_node_name='node0', + device='node0', + backing_file='null-co://', + filters=[filter_qmp_testfiles]) + + # Now, verify that we get a json:{} filename + # (Image header says "null-co://", actual backing file still is + # base_img_path) + + log_node_info(vm.node_info('node0')) + + # Change it back + # (To get header and backing file in sync) + + vm.qmp_log('change-backing-file', + image_node_name='node0', + device='node0', + backing_file=backing_filename, + filters=[filter_qmp_testfiles]) + + # And verify that we get our original results + + log_node_info(vm.node_info('node0')) + + # Finally, try a "file:" prefix. While this is actually what we + # originally had in the image header, qemu will not reopen the + # backing file here, so it cannot verify that this filename + # "resolves" to the actual backing BDS's filename and will thus + # consider both to be different. + # (This may be fixed in the future.) + + vm.qmp_log('change-backing-file', + image_node_name='node0', + device='node0', + backing_file=('file:' + backing_filename), + filters=[filter_qmp_testfiles]) + + # So now we should get a json:{} filename + + log_node_info(vm.node_info('node0')) + + # Remove and re-attach so we can see that (as in our first try), + # opening the image anew helps qemu resolve the header backing + # filename. + + vm.qmp_log('blockdev-del', node_name='node0') + + vm.qmp_log('blockdev-add', + node_name='node0', + driver=iotests.imgfmt, + file={ + 'driver': 'file', + 'filename': top_img_path + }, + filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) + + log_node_info(vm.node_info('node0')) + + vm.qmp_log('blockdev-del', node_name='node0') + + log('') + log('--- Override backing file ---') + log('') + + # For this test, we need the plain filename in the image header + # (because qemu cannot "canonicalize"/"resolve" the backing + # filename unless the backing file is opened implicitly with the + # overlay) + assert qemu_img('create', '-f', iotests.imgfmt, '-b', base_img_path, + top_img_path) == 0 + + # You can only reliably override backing options by using a node + # reference (or by specifying file.filename, but, well...) + vm.qmp_log('blockdev-add', node_name='null', driver='null-co') + + vm.qmp_log('blockdev-add', + node_name='node0', + driver=iotests.imgfmt, + file={ + 'driver': 'file', + 'filename': top_img_path + }, + backing='null', + filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) + + # Should get a json:{} filename (and bs->backing_file is + # null-co://, because that field actually has not much to do + # with the header backing filename (except that it is changed by + # change-backing-file)) + + log_node_info(vm.node_info('node0')) + + # Detach the backing file by reopening the whole thing + + vm.qmp_log('blockdev-del', node_name='node0') + vm.qmp_log('blockdev-del', node_name='null') + + vm.qmp_log('blockdev-add', + node_name='node0', + driver=iotests.imgfmt, + file={ + 'driver': 'file', + 'filename': top_img_path + }, + backing=None, + filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) + + # Should get a json:{} filename (because we overrode the backing + # file to not be there) + + log_node_info(vm.node_info('node0')) + + # Open the original backing file + + vm.qmp_log('blockdev-add', + node_name='original-backing', + driver=iotests.imgfmt, + file={ + 'driver': 'file', + 'filename': base_img_path + }, + filters=[filter_qmp_testfiles, filter_qmp_imgfmt]) + + # Attach the original backing file to its overlay + + vm.qmp_log('blockdev-snapshot', + node='original-backing', + overlay='node0') + + # This should give us the original plain result + + log_node_info(vm.node_info('node0')) + + vm.qmp_log('blockdev-del', node_name='node0') + vm.qmp_log('blockdev-del', node_name='original-backing') + + vm.shutdown() diff --git a/tests/qemu-iotests/228.out b/tests/qemu-iotests/228.out new file mode 100644 index 0000000000..4217df24fe --- /dev/null +++ b/tests/qemu-iotests/228.out @@ -0,0 +1,84 @@ +--- Implicit backing file --- + +{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top.img"}, "node-name": "node0"}} +{"return": {}} + +bs->filename: TEST_DIR/PID-top.img +bs->backing_file: TEST_DIR/PID-base.img +bs->backing->bs->filename: TEST_DIR/PID-base.img + +{"execute": "blockdev-del", "arguments": {"node-name": "node0"}} +{"return": {}} + +--- change-backing-file --- + +{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top.img"}, "node-name": "node0"}} +{"return": {}} +{"execute": "change-backing-file", "arguments": {"backing-file": "null-co://", "device": "node0", "image-node-name": "node0"}} +{"return": {}} + +bs->filename: json:{"backing": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-base.img"}}, "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top.img"}} +bs->backing_file: null-co:// +bs->backing->bs->filename: TEST_DIR/PID-base.img + +{"execute": "change-backing-file", "arguments": {"backing-file": "TEST_DIR/PID-base.img", "device": "node0", "image-node-name": "node0"}} +{"return": {}} + +bs->filename: TEST_DIR/PID-top.img +bs->backing_file: TEST_DIR/PID-base.img +bs->backing->bs->filename: TEST_DIR/PID-base.img + +{"execute": "change-backing-file", "arguments": {"backing-file": "file:TEST_DIR/PID-base.img", "device": "node0", "image-node-name": "node0"}} +{"return": {}} + +bs->filename: json:{"backing": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-base.img"}}, "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top.img"}} +bs->backing_file: file:TEST_DIR/PID-base.img +bs->backing->bs->filename: TEST_DIR/PID-base.img + +{"execute": "blockdev-del", "arguments": {"node-name": "node0"}} +{"return": {}} +{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top.img"}, "node-name": "node0"}} +{"return": {}} + +bs->filename: TEST_DIR/PID-top.img +bs->backing_file: TEST_DIR/PID-base.img +bs->backing->bs->filename: TEST_DIR/PID-base.img + +{"execute": "blockdev-del", "arguments": {"node-name": "node0"}} +{"return": {}} + +--- Override backing file --- + +{"execute": "blockdev-add", "arguments": {"driver": "null-co", "node-name": "null"}} +{"return": {}} +{"execute": "blockdev-add", "arguments": {"backing": "null", "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top.img"}, "node-name": "node0"}} +{"return": {}} + +bs->filename: json:{"backing": {"driver": "null-co"}, "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top.img"}} +bs->backing_file: null-co:// +bs->backing->bs->filename: null-co:// + +{"execute": "blockdev-del", "arguments": {"node-name": "node0"}} +{"return": {}} +{"execute": "blockdev-del", "arguments": {"node-name": "null"}} +{"return": {}} +{"execute": "blockdev-add", "arguments": {"backing": null, "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top.img"}, "node-name": "node0"}} +{"return": {}} + +bs->filename: json:{"backing": null, "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-top.img"}} +bs->backing_file: TEST_DIR/PID-base.img +bs->backing: (none) + +{"execute": "blockdev-add", "arguments": {"driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/PID-base.img"}, "node-name": "original-backing"}} +{"return": {}} +{"execute": "blockdev-snapshot", "arguments": {"node": "original-backing", "overlay": "node0"}} +{"return": {}} + +bs->filename: TEST_DIR/PID-top.img +bs->backing_file: TEST_DIR/PID-base.img +bs->backing->bs->filename: TEST_DIR/PID-base.img + +{"execute": "blockdev-del", "arguments": {"node-name": "node0"}} +{"return": {}} +{"execute": "blockdev-del", "arguments": {"node-name": "original-backing"}} +{"return": {}} diff --git a/tests/qemu-iotests/232 b/tests/qemu-iotests/232 index 0708b8b155..e48bc8f5db 100755 --- a/tests/qemu-iotests/232 +++ b/tests/qemu-iotests/232 @@ -29,7 +29,6 @@ status=1 # failure is the default! _cleanup() { _cleanup_test_img - rm -f $TEST_IMG.snap } trap "_cleanup; exit \$status" 0 1 2 3 15 @@ -70,6 +69,10 @@ size=128M _make_test_img $size +if [ -n "$TEST_IMG_FILE" ]; then + TEST_IMG=$TEST_IMG_FILE +fi + echo echo "=== -drive with read-write image: read-only/auto-read-only combinations ===" echo diff --git a/tests/qemu-iotests/237 b/tests/qemu-iotests/237 index 251771d7fb..06897f8c87 100755 --- a/tests/qemu-iotests/237 +++ b/tests/qemu-iotests/237 @@ -27,7 +27,8 @@ from iotests import imgfmt iotests.verify_image_format(supported_fmts=['vmdk']) def blockdev_create(vm, options): - result = vm.qmp_log('blockdev-create', job_id='job0', options=options) + result = vm.qmp_log('blockdev-create', job_id='job0', options=options, + filters=[iotests.filter_qmp_testfiles]) if 'return' in result: assert result['return'] == {} @@ -54,7 +55,7 @@ with iotests.FilePath('t.vmdk') as disk_path, \ 'size': 0 }) vm.qmp_log('blockdev-add', driver='file', filename=disk_path, - node_name='imgfile') + node_name='imgfile', filters=[iotests.filter_qmp_testfiles]) blockdev_create(vm, { 'driver': imgfmt, 'file': 'imgfile', @@ -223,7 +224,7 @@ with iotests.FilePath('t.vmdk') as disk_path, \ iotests.log("= %s %d =" % (subfmt, size)) iotests.log("") - num_extents = math.ceil(size / 2.0**31) + num_extents = int(math.ceil(size / 2.0**31)) extents = [ "ext%d" % (i) for i in range(1, num_extents + 1) ] vm.launch() diff --git a/tests/qemu-iotests/237.out b/tests/qemu-iotests/237.out index 241c864369..2aaa68f672 100644 --- a/tests/qemu-iotests/237.out +++ b/tests/qemu-iotests/237.out @@ -1,13 +1,13 @@ === Successful image creation (defaults) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "node_name": "imgfile"}} +{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "node-name": "imgfile"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "file": "imgfile", "size": 5368709120}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vmdk", "file": "imgfile", "size": 5368709120}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -29,12 +29,12 @@ Format specific information: === Successful image creation (inline blockdev-add, explicit defaults) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "ide", "driver": "vmdk", "extents": [], "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk"}, "hwversion": "4", "size": 67108864, "subformat": "monolithicSparse", "zeroed-grain": false}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": "ide", "driver": "vmdk", "extents": [], "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk"}, "hwversion": "4", "size": 67108864, "subformat": "monolithicSparse", "zeroed-grain": false}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -56,12 +56,12 @@ Format specific information: === Successful image creation (with non-default options) === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "size": 0}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk", "size": 0}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "buslogic", "driver": "vmdk", "extents": [], "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk"}, "size": 33554432, "subformat": "monolithicSparse", "zeroed-grain": true}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": "buslogic", "driver": "vmdk", "extents": [], "file": {"driver": "file", "filename": "TEST_DIR/PID-t.vmdk"}, "size": 33554432, "subformat": "monolithicSparse", "zeroed-grain": true}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -83,7 +83,7 @@ Format specific information: === Invalid BlockdevRef === -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "file": "this doesn't exist", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vmdk", "file": "this doesn't exist", "size": 33554432}}} {"return": {}} Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exist {"execute": "job-dismiss", "arguments": {"id": "job0"}} @@ -93,38 +93,38 @@ Job failed: Cannot find device=this doesn't exist nor node_name=this doesn't exi == Valid adapter types == -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "ide", "driver": "vmdk", "file": "node0", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": "ide", "driver": "vmdk", "file": "node0", "size": 33554432}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "buslogic", "driver": "vmdk", "file": "node0", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": "buslogic", "driver": "vmdk", "file": "node0", "size": 33554432}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "lsilogic", "driver": "vmdk", "file": "node0", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": "lsilogic", "driver": "vmdk", "file": "node0", "size": 33554432}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "legacyESX", "driver": "vmdk", "file": "node0", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": "legacyESX", "driver": "vmdk", "file": "node0", "size": 33554432}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} == Invalid adapter types == -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "foo", "driver": "vmdk", "file": "node0", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": "foo", "driver": "vmdk", "file": "node0", "size": 33554432}}} {"error": {"class": "GenericError", "desc": "Invalid parameter 'foo'"}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "IDE", "driver": "vmdk", "file": "node0", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": "IDE", "driver": "vmdk", "file": "node0", "size": 33554432}}} {"error": {"class": "GenericError", "desc": "Invalid parameter 'IDE'"}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": "legacyesx", "driver": "vmdk", "file": "node0", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": "legacyesx", "driver": "vmdk", "file": "node0", "size": 33554432}}} {"error": {"class": "GenericError", "desc": "Invalid parameter 'legacyesx'"}} -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"adapter-type": 1, "driver": "vmdk", "file": "node0", "size": 33554432}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"adapter-type": 1, "driver": "vmdk", "file": "node0", "size": 33554432}}} {"error": {"class": "GenericError", "desc": "Invalid parameter type for 'options.adapter-type', expected: string"}} === Other subformats === @@ -137,7 +137,7 @@ Formatting 'TEST_DIR/PID-t.vmdk.3', fmt=vmdk size=0 compat6=off hwversion=undefi == Missing extent == -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "file": "node0", "size": 33554432, "subformat": "monolithicFlat"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vmdk", "file": "node0", "size": 33554432, "subformat": "monolithicFlat"}}} {"return": {}} Job failed: Extent [0] not specified {"execute": "job-dismiss", "arguments": {"id": "job0"}} @@ -145,14 +145,14 @@ Job failed: Extent [0] not specified == Correct extent == -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 33554432, "subformat": "monolithicFlat"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 33554432, "subformat": "monolithicFlat"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} == Extra extent == -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "monolithicFlat"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 512, "subformat": "monolithicFlat"}}} {"return": {}} Job failed: List of extents contains unused extents {"execute": "job-dismiss", "arguments": {"id": "job0"}} @@ -162,7 +162,7 @@ Job failed: List of extents contains unused extents = twoGbMaxExtentFlat 512 = -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentFlat"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentFlat"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -182,7 +182,7 @@ Format specific information: = twoGbMaxExtentSparse 512 = -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentSparse"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 512, "subformat": "twoGbMaxExtentSparse"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -204,7 +204,7 @@ Format specific information: = twoGbMaxExtentFlat 1073741824 = -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentFlat"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentFlat"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -224,7 +224,7 @@ Format specific information: = twoGbMaxExtentSparse 1073741824 = -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentSparse"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 1073741824, "subformat": "twoGbMaxExtentSparse"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -246,7 +246,7 @@ Format specific information: = twoGbMaxExtentFlat 2147483648 = -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentFlat"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentFlat"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -266,7 +266,7 @@ Format specific information: = twoGbMaxExtentSparse 2147483648 = -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentSparse"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vmdk", "extents": ["ext1"], "file": "node0", "size": 2147483648, "subformat": "twoGbMaxExtentSparse"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -288,7 +288,7 @@ Format specific information: = twoGbMaxExtentFlat 5368709120 = -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 5368709120, "subformat": "twoGbMaxExtentFlat"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 5368709120, "subformat": "twoGbMaxExtentFlat"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} @@ -316,7 +316,7 @@ Format specific information: = twoGbMaxExtentSparse 5368709120 = -{"execute": "blockdev-create", "arguments": {"job_id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 5368709120, "subformat": "twoGbMaxExtentSparse"}}} +{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vmdk", "extents": ["ext1", "ext2", "ext3"], "file": "node0", "size": 5368709120, "subformat": "twoGbMaxExtentSparse"}}} {"return": {}} {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}} diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index e15e7a7c8e..09a27f02d0 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -145,6 +145,7 @@ else TEST_IMG="nbd:127.0.0.1:10810" elif [ "$IMGPROTO" = "ssh" ]; then TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT + REMOTE_TEST_DIR="ssh://127.0.0.1$TEST_DIR" TEST_IMG="ssh://127.0.0.1$TEST_IMG_FILE" elif [ "$IMGPROTO" = "nfs" ]; then TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index fc4c416fa3..b5ca63cf72 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -224,9 +224,11 @@ 221 rw auto quick 222 rw auto quick 223 rw auto quick +224 rw auto quick 225 rw auto quick 226 auto quick 227 auto quick +228 rw auto quick 229 auto quick 231 auto quick 232 auto quick diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index b461f53abf..4910fb2005 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -76,14 +76,16 @@ def qemu_img(*args): sys.stderr.write('qemu-img received signal %i: %s\n' % (-exitcode, ' '.join(qemu_img_args + list(args)))) return exitcode -def ordered_qmp(qmsg): +def ordered_qmp(qmsg, conv_keys=True): # Dictionaries are not ordered prior to 3.6, therefore: if isinstance(qmsg, list): return [ordered_qmp(atom) for atom in qmsg] if isinstance(qmsg, dict): od = OrderedDict() for k, v in sorted(qmsg.items()): - od[k] = ordered_qmp(v) + if conv_keys: + k = k.replace('_', '-') + od[k] = ordered_qmp(v, conv_keys=False) return od return qmsg @@ -236,6 +238,12 @@ def image_size(img): r = qemu_img_pipe('info', '--output=json', '-f', imgfmt, img) return json.loads(r)['virtual-size'] +def is_str(val): + if sys.version_info.major >= 3: + return isinstance(val, str) + else: + return isinstance(val, str) or isinstance(val, unicode) + test_dir_re = re.compile(r"%s" % test_dir) def filter_test_dir(msg): return test_dir_re.sub("TEST_DIR", msg) @@ -283,7 +291,7 @@ def filter_testfiles(msg): def filter_qmp_testfiles(qmsg): def _filter(key, value): - if key == 'filename' or key == 'backing-file': + if is_str(value): return filter_testfiles(value) return value return filter_qmp(qmsg, _filter) @@ -304,6 +312,16 @@ def filter_img_info(output, filename): lines.append(line) return '\n'.join(lines) +def filter_imgfmt(msg): + return msg.replace(imgfmt, 'IMGFMT') + +def filter_qmp_imgfmt(qmsg): + def _filter(key, value): + if is_str(value): + return filter_imgfmt(value) + return value + return filter_qmp(qmsg, _filter) + def log(msg, filters=[], indent=None): '''Logs either a string message or a JSON serializable message (like QMP). If indent is provided, JSON serializable messages are pretty-printed.''' @@ -514,7 +532,9 @@ class VM(qtest.QEMUQtestMachine): log(result, filters, indent=indent) return result + # Returns None on success, and an error string on failure def run_job(self, job, auto_finalize=True, auto_dismiss=False): + error = None while True: for ev in self.get_qmp_events_filtered(wait=True): if ev['event'] == 'JOB_STATUS_CHANGE': @@ -523,16 +543,24 @@ class VM(qtest.QEMUQtestMachine): result = self.qmp('query-jobs') for j in result['return']: if j['id'] == job: + error = j['error'] log('Job failed: %s' % (j['error'])) elif status == 'pending' and not auto_finalize: self.qmp_log('job-finalize', id=job) elif status == 'concluded' and not auto_dismiss: self.qmp_log('job-dismiss', id=job) elif status == 'null': - return + return error else: iotests.log(ev) + def node_info(self, node_name): + nodes = self.qmp('query-named-block-nodes') + for x in nodes['return']: + if x['node-name'] == node_name: + return x + return None + index_re = re.compile(r'([^\[]+)\[([^\]]+)\]') diff --git a/tests/test-bdrv-drain.c b/tests/test-bdrv-drain.c index 821be405f0..eda90750eb 100644 --- a/tests/test-bdrv-drain.c +++ b/tests/test-bdrv-drain.c @@ -1501,6 +1501,36 @@ static void test_append_to_drained(void) blk_unref(blk); } +static void test_set_aio_context(void) +{ + BlockDriverState *bs; + IOThread *a = iothread_new(); + IOThread *b = iothread_new(); + AioContext *ctx_a = iothread_get_aio_context(a); + AioContext *ctx_b = iothread_get_aio_context(b); + + bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR, + &error_abort); + + bdrv_drained_begin(bs); + bdrv_set_aio_context(bs, ctx_a); + + aio_context_acquire(ctx_a); + bdrv_drained_end(bs); + + bdrv_drained_begin(bs); + bdrv_set_aio_context(bs, ctx_b); + aio_context_release(ctx_a); + aio_context_acquire(ctx_b); + bdrv_set_aio_context(bs, qemu_get_aio_context()); + aio_context_release(ctx_b); + bdrv_drained_end(bs); + + bdrv_unref(bs); + iothread_join(a); + iothread_join(b); +} + int main(int argc, char **argv) { int ret; @@ -1582,6 +1612,8 @@ int main(int argc, char **argv) g_test_add_func("/bdrv-drain/attach/drain", test_append_to_drained); + g_test_add_func("/bdrv-drain/set_aio_context", test_set_aio_context); + ret = g_test_run(); qemu_event_destroy(&done_event); return ret; diff --git a/tests/test-bdrv-graph-mod.c b/tests/test-bdrv-graph-mod.c new file mode 100644 index 0000000000..458dfa6661 --- /dev/null +++ b/tests/test-bdrv-graph-mod.c @@ -0,0 +1,198 @@ +/* + * Block node graph modifications tests + * + * Copyright (c) 2019 Virtuozzo International GmbH. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "block/block_int.h" +#include "sysemu/block-backend.h" + +static BlockDriver bdrv_pass_through = { + .format_name = "pass-through", + .bdrv_child_perm = bdrv_filter_default_perms, +}; + +static void no_perm_default_perms(BlockDriverState *bs, BdrvChild *c, + const BdrvChildRole *role, + BlockReopenQueue *reopen_queue, + uint64_t perm, uint64_t shared, + uint64_t *nperm, uint64_t *nshared) +{ + *nperm = 0; + *nshared = BLK_PERM_ALL; +} + +static BlockDriver bdrv_no_perm = { + .format_name = "no-perm", + .bdrv_child_perm = no_perm_default_perms, +}; + +static BlockDriverState *no_perm_node(const char *name) +{ + return bdrv_new_open_driver(&bdrv_no_perm, name, BDRV_O_RDWR, &error_abort); +} + +static BlockDriverState *pass_through_node(const char *name) +{ + return bdrv_new_open_driver(&bdrv_pass_through, name, + BDRV_O_RDWR, &error_abort); +} + +/* + * test_update_perm_tree + * + * When checking node for a possibility to update permissions, it's subtree + * should be correctly checked too. New permissions for each node should be + * calculated and checked in context of permissions of other nodes. If we + * check new permissions of the node only in context of old permissions of + * its neighbors, we can finish up with wrong permission graph. + * + * This test firstly create the following graph: + * +--------+ + * | root | + * +--------+ + * | + * | perm: write, read + * | shared: except write + * v + * +-------------------+ +----------------+ + * | passtrough filter |---------->| null-co node | + * +-------------------+ +----------------+ + * + * + * and then, tries to append filter under node. Expected behavior: fail. + * Otherwise we'll get the following picture, with two BdrvChild'ren, having + * write permission to one node, without actually sharing it. + * + * +--------+ + * | root | + * +--------+ + * | + * | perm: write, read + * | shared: except write + * v + * +-------------------+ + * | passtrough filter | + * +-------------------+ + * | | + * perm: write, read | | perm: write, read + * shared: except write | | shared: except write + * v v + * +----------------+ + * | null co node | + * +----------------+ + */ +static void test_update_perm_tree(void) +{ + Error *local_err = NULL; + + BlockBackend *root = blk_new(BLK_PERM_WRITE | BLK_PERM_CONSISTENT_READ, + BLK_PERM_ALL & ~BLK_PERM_WRITE); + BlockDriverState *bs = no_perm_node("node"); + BlockDriverState *filter = pass_through_node("filter"); + + blk_insert_bs(root, bs, &error_abort); + + bdrv_attach_child(filter, bs, "child", &child_file, &error_abort); + + bdrv_append(filter, bs, &local_err); + + g_assert_nonnull(local_err); + + bdrv_unref(bs); + blk_unref(root); +} + +/* + * test_should_update_child + * + * Test that bdrv_replace_node, and concretely should_update_child + * do the right thing, i.e. not creating loops on the graph. + * + * The test does the following: + * 1. initial graph: + * + * +------+ +--------+ + * | root | | filter | + * +------+ +--------+ + * | | + * root| target| + * v v + * +------+ +--------+ + * | node |<---------| target | + * +------+ backing +--------+ + * + * 2. Append @filter above @node. If should_update_child works correctly, + * it understands, that backing child of @target should not be updated, + * as it will create a loop on node graph. Resulting picture should + * be the left one, not the right: + * + * +------+ +------+ + * | root | | root | + * +------+ +------+ + * | | + * root| root| + * v v + * +--------+ target +--------+ target + * | filter |--------------+ | filter |--------------+ + * +--------+ | +--------+ | + * | | | ^ v + * backing| | backing| | +--------+ + * v v | +-----------| target | + * +------+ +--------+ v backing +--------+ + * | node |<---------| target | +------+ + * +------+ backing +--------+ | node | + * +------+ + * + * (good picture) (bad picture) + * + */ +static void test_should_update_child(void) +{ + BlockBackend *root = blk_new(0, BLK_PERM_ALL); + BlockDriverState *bs = no_perm_node("node"); + BlockDriverState *filter = no_perm_node("filter"); + BlockDriverState *target = no_perm_node("target"); + + blk_insert_bs(root, bs, &error_abort); + + bdrv_set_backing_hd(target, bs, &error_abort); + + g_assert(target->backing->bs == bs); + bdrv_attach_child(filter, target, "target", &child_file, &error_abort); + bdrv_append(filter, bs, &error_abort); + g_assert(target->backing->bs == bs); + + bdrv_unref(bs); + blk_unref(root); +} + +int main(int argc, char *argv[]) +{ + bdrv_init(); + qemu_init_main_loop(&error_abort); + + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/bdrv-graph-mod/update-perm-tree", test_update_perm_tree); + g_test_add_func("/bdrv-graph-mod/should-update-child", + test_should_update_child); + + return g_test_run(); +} |