diff options
Diffstat (limited to 'tests/qemu-iotests/245')
| -rwxr-xr-x | tests/qemu-iotests/245 | 140 |
1 files changed, 124 insertions, 16 deletions
diff --git a/tests/qemu-iotests/245 b/tests/qemu-iotests/245 index fc5297e268..0295129cbb 100755 --- a/tests/qemu-iotests/245 +++ b/tests/qemu-iotests/245 @@ -79,7 +79,7 @@ class TestBlockdevReopen(iotests.QMPTestCase): for line in log.split("\n"): if line.startswith("Pattern verification failed"): raise Exception("%s (command #%d)" % (line, found)) - if re.match("read .*/.* bytes at offset", line): + if re.match("(read|wrote) .*/.* bytes at offset", line): found += 1 self.assertEqual(found, self.total_io_cmds, "Expected output of %d qemu-io commands, found %d" % @@ -146,8 +146,8 @@ class TestBlockdevReopen(iotests.QMPTestCase): self.reopen(opts, {'driver': 'raw'}, "Cannot change the option 'driver'") self.reopen(opts, {'driver': ''}, "Invalid parameter ''") self.reopen(opts, {'driver': None}, "Invalid parameter type for 'driver', expected: string") - self.reopen(opts, {'file': 'not-found'}, "Cannot change the option 'file'") - self.reopen(opts, {'file': ''}, "Cannot change the option 'file'") + self.reopen(opts, {'file': 'not-found'}, "Cannot find device='' nor node-name='not-found'") + self.reopen(opts, {'file': ''}, "Cannot find device='' nor node-name=''") self.reopen(opts, {'file': None}, "Invalid parameter type for 'file', expected: BlockdevRef") self.reopen(opts, {'file.node-name': 'newname'}, "Cannot change the option 'node-name'") self.reopen(opts, {'file.driver': 'host_device'}, "Cannot change the option 'driver'") @@ -443,7 +443,7 @@ class TestBlockdevReopen(iotests.QMPTestCase): # Illegal operation: hd2 is a child of hd1 self.reopen(opts[2], {'backing': 'hd1'}, - "Making 'hd1' a backing file of 'hd2' would create a cycle") + "Making 'hd1' a backing child of 'hd2' would create a cycle") # hd2 <- hd0, hd2 <- hd1 self.reopen(opts[0], {'backing': 'hd2'}) @@ -454,8 +454,9 @@ class TestBlockdevReopen(iotests.QMPTestCase): # More illegal operations self.reopen(opts[2], {'backing': 'hd1'}, - "Making 'hd1' a backing file of 'hd2' would create a cycle") - self.reopen(opts[2], {'file': 'hd0-file'}, "Cannot change the option 'file'") + "Making 'hd1' a backing child of 'hd2' would create a cycle") + self.reopen(opts[2], {'file': 'hd0-file'}, + "Permission conflict on node 'hd0-file': permissions 'write, resize' are both required by node 'hd0' (uses node 'hd0-file' as 'file' child) and unshared by node 'hd2' (uses node 'hd0-file' as 'file' child).") result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'hd2') self.assert_qmp(result, 'error/class', 'GenericError') @@ -497,18 +498,18 @@ class TestBlockdevReopen(iotests.QMPTestCase): # Illegal: hd2 is backed by hd1 self.reopen(opts[1], {'backing': 'hd2'}, - "Making 'hd2' a backing file of 'hd1' would create a cycle") + "Making 'hd2' a backing child of 'hd1' would create a cycle") # hd1 <- hd0 <- hd2 self.reopen(opts[2], {'backing': 'hd0'}) # Illegal: hd2 is backed by hd0, which is backed by hd1 self.reopen(opts[1], {'backing': 'hd2'}, - "Making 'hd2' a backing file of 'hd1' would create a cycle") + "Making 'hd2' a backing child of 'hd1' would create a cycle") # Illegal: hd1 cannot point to itself self.reopen(opts[1], {'backing': 'hd1'}, - "Making 'hd1' a backing file of 'hd1' would create a cycle") + "Making 'hd1' a backing child of 'hd1' would create a cycle") # Remove all backing files self.reopen(opts[0]) @@ -530,12 +531,119 @@ class TestBlockdevReopen(iotests.QMPTestCase): # Illegal: hd0 is a child of the blkverify node self.reopen(opts[0], {'backing': 'bv'}, - "Making 'bv' a backing file of 'hd0' would create a cycle") + "Making 'bv' a backing child of 'hd0' would create a cycle") # Delete the blkverify node result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'bv') self.assert_qmp(result, 'return', {}) + # Replace the protocol layer ('file' parameter) of a disk image + def test_replace_file(self): + # Create two small raw images and add them to a running VM + qemu_img('create', '-f', 'raw', hd_path[0], '10k') + qemu_img('create', '-f', 'raw', hd_path[1], '10k') + + hd0_opts = {'driver': 'file', 'node-name': 'hd0-file', 'filename': hd_path[0] } + hd1_opts = {'driver': 'file', 'node-name': 'hd1-file', 'filename': hd_path[1] } + + result = self.vm.qmp('blockdev-add', conv_keys = False, **hd0_opts) + self.assert_qmp(result, 'return', {}) + result = self.vm.qmp('blockdev-add', conv_keys = False, **hd1_opts) + self.assert_qmp(result, 'return', {}) + + # Add a raw format layer that uses hd0-file as its protocol layer + opts = {'driver': 'raw', 'node-name': 'hd', 'file': 'hd0-file'} + + result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) + self.assert_qmp(result, 'return', {}) + + # Fill the image with data + self.run_qemu_io("hd", "read -P 0 0 10k") + self.run_qemu_io("hd", "write -P 0xa0 0 10k") + + # Replace hd0-file with hd1-file and fill it with (different) data + self.reopen(opts, {'file': 'hd1-file'}) + self.run_qemu_io("hd", "read -P 0 0 10k") + self.run_qemu_io("hd", "write -P 0xa1 0 10k") + + # Use hd0-file again and check that it contains the expected data + self.reopen(opts, {'file': 'hd0-file'}) + self.run_qemu_io("hd", "read -P 0xa0 0 10k") + + # And finally do the same with hd1-file + self.reopen(opts, {'file': 'hd1-file'}) + self.run_qemu_io("hd", "read -P 0xa1 0 10k") + + # Insert (and remove) a throttle filter + def test_insert_throttle_filter(self): + # Add an image to the VM + hd0_opts = hd_opts(0) + result = self.vm.qmp('blockdev-add', conv_keys = False, **hd0_opts) + self.assert_qmp(result, 'return', {}) + + # Create a throttle-group object + opts = { 'qom-type': 'throttle-group', 'id': 'group0', + 'limits': { 'iops-total': 1000 } } + result = self.vm.qmp('object-add', conv_keys = False, **opts) + self.assert_qmp(result, 'return', {}) + + # Add a throttle filter with the group that we just created. + # The filter is not used by anyone yet + opts = { 'driver': 'throttle', 'node-name': 'throttle0', + 'throttle-group': 'group0', 'file': 'hd0-file' } + result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) + self.assert_qmp(result, 'return', {}) + + # Insert the throttle filter between hd0 and hd0-file + self.reopen(hd0_opts, {'file': 'throttle0'}) + + # Remove the throttle filter from hd0 + self.reopen(hd0_opts, {'file': 'hd0-file'}) + + # Insert (and remove) a compress filter + def test_insert_compress_filter(self): + # Add an image to the VM: hd (raw) -> hd0 (qcow2) -> hd0-file (file) + opts = {'driver': 'raw', 'node-name': 'hd', 'file': hd_opts(0)} + result = self.vm.qmp('blockdev-add', conv_keys = False, **opts) + self.assert_qmp(result, 'return', {}) + + # Add a 'compress' filter + filter_opts = {'driver': 'compress', + 'node-name': 'compress0', + 'file': 'hd0'} + result = self.vm.qmp('blockdev-add', conv_keys = False, **filter_opts) + self.assert_qmp(result, 'return', {}) + + # Unmap the beginning of the image (we cannot write compressed + # data to an allocated cluster) + self.run_qemu_io("hd", "write -z -u 0 128k") + + # Write data to the first cluster + self.run_qemu_io("hd", "write -P 0xa0 0 64k") + + # Insert the filter then write to the second cluster + # hd -> compress0 -> hd0 -> hd0-file + self.reopen(opts, {'file': 'compress0'}) + self.run_qemu_io("hd", "write -P 0xa1 64k 64k") + + # Remove the filter then write to the third cluster + # hd -> hd0 -> hd0-file + self.reopen(opts, {'file': 'hd0'}) + self.run_qemu_io("hd", "write -P 0xa2 128k 64k") + + # Verify the data that we just wrote + self.run_qemu_io("hd", "read -P 0xa0 0 64k") + self.run_qemu_io("hd", "read -P 0xa1 64k 64k") + self.run_qemu_io("hd", "read -P 0xa2 128k 64k") + + self.vm.shutdown() + + # Check the first byte of the first three L2 entries and verify that + # the second one is compressed (0x40) while the others are not (0x80) + iotests.qemu_io_log('-f', 'raw', '-c', 'read -P 0x80 0x40000 1', + '-c', 'read -P 0x40 0x40008 1', + '-c', 'read -P 0x80 0x40010 1', hd_path[0]) + # Misc reopen tests with different block drivers @iotests.skip_if_unsupported(['quorum', 'throttle']) def test_misc_drivers(self): @@ -563,7 +671,7 @@ class TestBlockdevReopen(iotests.QMPTestCase): # You can't make quorum0 a backing file of hd0: # hd0 is already a child of quorum0. self.reopen(hd_opts(0), {'backing': 'quorum0'}, - "Making 'quorum0' a backing file of 'hd0' would create a cycle") + "Making 'quorum0' a backing child of 'hd0' would create a cycle") # Delete quorum0 result = self.vm.qmp('blockdev-del', conv_keys = True, node_name = 'quorum0') @@ -878,7 +986,7 @@ class TestBlockdevReopen(iotests.QMPTestCase): # We can't remove hd1 while the stream job is ongoing opts['backing'] = None - self.reopen(opts, {}, "Cannot change 'backing' link from 'hd0' to 'hd1'") + self.reopen(opts, {}, "Cannot change frozen 'backing' link from 'hd0' to 'hd1'") self.vm.run_job('stream0', auto_finalize = False, auto_dismiss = True) @@ -910,7 +1018,7 @@ class TestBlockdevReopen(iotests.QMPTestCase): # We can't remove hd2 while the stream job is ongoing opts['backing']['backing'] = None self.reopen(opts['backing'], {'read-only': False}, - "Cannot change 'backing' link from 'hd1' to 'hd2'") + "Cannot change frozen 'backing' link from 'hd1' to 'hd2'") # We can detach hd1 from hd0 because it doesn't affect the stream job opts['backing'] = None @@ -933,11 +1041,11 @@ class TestBlockdevReopen(iotests.QMPTestCase): # We can't remove hd2 while the commit job is ongoing opts['backing']['backing'] = None - self.reopen(opts, {}, "Cannot change 'backing' link from 'hd1' to 'hd2'") + self.reopen(opts, {}, "Cannot change frozen 'backing' link from 'hd1' to 'hd2'") # We can't remove hd1 while the commit job is ongoing opts['backing'] = None - self.reopen(opts, {}, "Cannot change 'backing' link from 'hd0' to 'hd1'") + self.reopen(opts, {}, "Cannot change frozen 'backing' link from 'hd0' to 'hd1'") event = self.vm.event_wait(name='BLOCK_JOB_READY') self.assert_qmp(event, 'data/device', 'commit0') @@ -969,7 +1077,7 @@ class TestBlockdevReopen(iotests.QMPTestCase): # We can't remove hd1 while the commit job is ongoing opts['backing'] = None - self.reopen(opts, {}, "Cannot change backing link if 'hd0' has an implicit backing file") + self.reopen(opts, {}, "Cannot replace implicit backing child of hd0") # hd2 <- hd0 self.vm.run_job('commit0', auto_finalize = False, auto_dismiss = True) |