diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-07-24 16:58:16 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-07-24 16:58:16 +0100 |
commit | 50104f5ac537eecc890c65e99362df47bac3f9d9 (patch) | |
tree | f80ef7933fc3f4e43ccb11f24d7b98a93656e89a | |
parent | ce1d20aac8533357650774c2c240e30de87dc122 (diff) | |
parent | 2c93c5cb43fd992038711f84ea34c9373273cda6 (diff) |
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches for 2.10.0-rc0
# gpg: Signature made Mon 24 Jul 2017 15:16:42 BST
# gpg: using RSA key 0x7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6
* remotes/kevin/tags/for-upstream:
qemu-iotests: Avoid unnecessary sleeps
block: Skip implicit nodes in query-block/blockstats
qcow2: Fix sector calculation in qcow2_measure()
dirty-bitmap: Report BlockDirtyInfo.count in bytes, as documented
iotests: Remove a few tests from 'quick' group
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | block.c | 13 | ||||
-rw-r--r-- | block/commit.c | 3 | ||||
-rw-r--r-- | block/dirty-bitmap.c | 2 | ||||
-rw-r--r-- | block/mirror.c | 3 | ||||
-rw-r--r-- | block/qapi.c | 33 | ||||
-rw-r--r-- | block/qcow2.c | 4 | ||||
-rw-r--r-- | include/block/block.h | 1 | ||||
-rw-r--r-- | include/block/block_int.h | 1 | ||||
-rw-r--r-- | qapi/block-core.json | 6 | ||||
-rwxr-xr-x | tests/qemu-iotests/030 | 7 | ||||
-rwxr-xr-x | tests/qemu-iotests/040 | 30 | ||||
-rw-r--r-- | tests/qemu-iotests/040.out | 4 | ||||
-rwxr-xr-x | tests/qemu-iotests/041 | 50 | ||||
-rw-r--r-- | tests/qemu-iotests/041.out | 4 | ||||
-rwxr-xr-x | tests/qemu-iotests/055 | 15 | ||||
-rw-r--r-- | tests/qemu-iotests/group | 4 | ||||
-rw-r--r-- | tests/qemu-iotests/iotests.py | 27 |
17 files changed, 157 insertions, 50 deletions
@@ -3973,19 +3973,6 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, return retval; } -int bdrv_get_backing_file_depth(BlockDriverState *bs) -{ - if (!bs->drv) { - return 0; - } - - if (!bs->backing) { - return 0; - } - - return 1 + bdrv_get_backing_file_depth(bs->backing->bs); -} - void bdrv_init(void) { module_call_init(MODULE_INIT_BLOCK); diff --git a/block/commit.c b/block/commit.c index 5cc910f567..c7857c3321 100644 --- a/block/commit.c +++ b/block/commit.c @@ -346,6 +346,9 @@ void commit_start(const char *job_id, BlockDriverState *bs, if (commit_top_bs == NULL) { goto fail; } + if (!filter_node_name) { + commit_top_bs->implicit = true; + } commit_top_bs->total_sectors = top->total_sectors; bdrv_set_aio_context(commit_top_bs, bdrv_get_aio_context(top)); diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c index 543bddb9b5..30462d4f9a 100644 --- a/block/dirty-bitmap.c +++ b/block/dirty-bitmap.c @@ -461,7 +461,7 @@ BlockDirtyInfoList *bdrv_query_dirty_bitmaps(BlockDriverState *bs) QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { BlockDirtyInfo *info = g_new0(BlockDirtyInfo, 1); BlockDirtyInfoList *entry = g_new0(BlockDirtyInfoList, 1); - info->count = bdrv_get_dirty_count(bm); + info->count = bdrv_get_dirty_count(bm) << BDRV_SECTOR_BITS; info->granularity = bdrv_dirty_bitmap_granularity(bm); info->has_name = !!bm->name; info->name = g_strdup(bm->name); diff --git a/block/mirror.c b/block/mirror.c index 8583b764a0..c9a6a3ca86 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -1168,6 +1168,9 @@ static void mirror_start_job(const char *job_id, BlockDriverState *bs, if (mirror_top_bs == NULL) { return; } + if (!filter_node_name) { + mirror_top_bs->implicit = true; + } mirror_top_bs->total_sectors = bs->total_sectors; bdrv_set_aio_context(mirror_top_bs, bdrv_get_aio_context(bs)); diff --git a/block/qapi.c b/block/qapi.c index 95b2e2daa5..d2b18ee9df 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -64,7 +64,6 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk, info->backing_file = g_strdup(bs->backing_file); } - info->backing_file_depth = bdrv_get_backing_file_depth(bs); info->detect_zeroes = bs->detect_zeroes; if (blk && blk_get_public(blk)->throttle_state) { @@ -125,6 +124,7 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk, bs0 = bs; p_image_info = &info->image; + info->backing_file_depth = 0; while (1) { Error *local_err = NULL; bdrv_query_image_info(bs0, p_image_info, &local_err); @@ -133,13 +133,21 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk, qapi_free_BlockDeviceInfo(info); return NULL; } + if (bs0->drv && bs0->backing) { + info->backing_file_depth++; bs0 = bs0->backing->bs; (*p_image_info)->has_backing_image = true; p_image_info = &((*p_image_info)->backing_image); } else { break; } + + /* Skip automatically inserted nodes that the user isn't aware of for + * query-block (blk != NULL), but not for query-named-block-nodes */ + while (blk && bs0 && bs0->drv && bs0->implicit) { + bs0 = backing_bs(bs0); + } } return info; @@ -324,6 +332,11 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info, BlockDriverState *bs = blk_bs(blk); char *qdev; + /* Skip automatically inserted nodes that the user isn't aware of */ + while (bs && bs->drv && bs->implicit) { + bs = backing_bs(bs); + } + info->device = g_strdup(blk_name(blk)); info->type = g_strdup("unknown"); info->locked = blk_dev_is_medium_locked(blk); @@ -434,8 +447,8 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk) } } -static BlockStats *bdrv_query_bds_stats(const BlockDriverState *bs, - bool query_backing) +static BlockStats *bdrv_query_bds_stats(BlockDriverState *bs, + bool blk_level) { BlockStats *s = NULL; @@ -446,6 +459,14 @@ static BlockStats *bdrv_query_bds_stats(const BlockDriverState *bs, return s; } + /* Skip automatically inserted nodes that the user isn't aware of in + * a BlockBackend-level command. Stay at the exact node for a node-level + * command. */ + while (blk_level && bs->drv && bs->implicit) { + bs = backing_bs(bs); + assert(bs); + } + if (bdrv_get_node_name(bs)[0]) { s->has_node_name = true; s->node_name = g_strdup(bdrv_get_node_name(bs)); @@ -455,12 +476,12 @@ static BlockStats *bdrv_query_bds_stats(const BlockDriverState *bs, if (bs->file) { s->has_parent = true; - s->parent = bdrv_query_bds_stats(bs->file->bs, query_backing); + s->parent = bdrv_query_bds_stats(bs->file->bs, blk_level); } - if (query_backing && bs->backing) { + if (blk_level && bs->backing) { s->has_backing = true; - s->backing = bdrv_query_bds_stats(bs->backing->bs, query_backing); + s->backing = bdrv_query_bds_stats(bs->backing->bs, blk_level); } return s; diff --git a/block/qcow2.c b/block/qcow2.c index d5790af1e0..90efa4477b 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -3669,8 +3669,8 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs, for (sector_num = 0; sector_num < ssize / BDRV_SECTOR_SIZE; sector_num += pnum) { - int nb_sectors = MAX(ssize / BDRV_SECTOR_SIZE - sector_num, - INT_MAX); + int nb_sectors = MIN(ssize / BDRV_SECTOR_SIZE - sector_num, + BDRV_REQUEST_MAX_SECTORS); BlockDriverState *file; int64_t ret; diff --git a/include/block/block.h b/include/block/block.h index b3e2674845..34770bb33a 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -300,7 +300,6 @@ int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset, int bytes, BdrvRequestFlags flags); BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs, const char *backing_file); -int bdrv_get_backing_file_depth(BlockDriverState *bs); void bdrv_refresh_filename(BlockDriverState *bs); int bdrv_truncate(BdrvChild *child, int64_t offset, PreallocMode prealloc, Error **errp); diff --git a/include/block/block_int.h b/include/block/block_int.h index 5c6b761d81..d4f4ea7584 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -549,6 +549,7 @@ struct BlockDriverState { bool sg; /* if true, the device is a /dev/sg* */ bool probed; /* if true, format was probed rather than specified */ bool force_share; /* if true, always allow all shared permissions */ + bool implicit; /* if true, this filter node was automatically inserted */ BlockDriver *drv; /* NULL means no media */ void *opaque; diff --git a/qapi/block-core.json b/qapi/block-core.json index 6866ae8a38..833c602150 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -520,7 +520,8 @@ # # Get a list of BlockInfo for all virtual block devices. # -# Returns: a list of @BlockInfo describing each virtual block device +# Returns: a list of @BlockInfo describing each virtual block device. Filter +# nodes that were created implicitly are skipped over. # # Since: 0.14.0 # @@ -780,7 +781,8 @@ # information, but not "backing". # If false or omitted, the behavior is as before - query all the # device backends, recursively including their "parent" and -# "backing". (Since 2.3) +# "backing". Filter nodes that were created implicitly are +# skipped over in this mode. (Since 2.3) # # Returns: A list of @BlockStats for each virtual block devices. # diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030 index feee86115d..d745cb4cde 100755 --- a/tests/qemu-iotests/030 +++ b/tests/qemu-iotests/030 @@ -89,18 +89,19 @@ class TestSingleDrive(iotests.QMPTestCase): result = self.vm.qmp('block-job-pause', device='drive0') self.assert_qmp(result, 'return', {}) - time.sleep(1) + self.vm.resume_drive('drive0') + self.pause_job('drive0') + result = self.vm.qmp('query-block-jobs') offset = self.dictpath(result, 'return[0]/offset') - time.sleep(1) + time.sleep(0.5) result = self.vm.qmp('query-block-jobs') self.assert_qmp(result, 'return[0]/offset', offset) result = self.vm.qmp('block-job-resume', device='drive0') self.assert_qmp(result, 'return', {}) - self.vm.resume_drive('drive0') self.wait_until_completed() self.assert_no_active_block_jobs() diff --git a/tests/qemu-iotests/040 b/tests/qemu-iotests/040 index 9d381d9b72..95b7510571 100755 --- a/tests/qemu-iotests/040 +++ b/tests/qemu-iotests/040 @@ -81,7 +81,7 @@ class TestSingleDrive(ImageCommitTestCase): qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img) qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', backing_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img) - self.vm = iotests.VM().add_drive(test_img, interface="none") + self.vm = iotests.VM().add_drive(test_img, "node-name=top,backing.node-name=mid,backing.backing.node-name=base", interface="none") self.vm.add_device("virtio-scsi-pci") self.vm.add_device("scsi-hd,id=scsi0,drive=drive0") self.vm.launch() @@ -163,6 +163,34 @@ class TestSingleDrive(ImageCommitTestCase): self.assert_no_active_block_jobs() + # Tests that the insertion of the commit_top filter node doesn't make a + # difference to query-blockstat + def test_implicit_node(self): + if self.image_len == 0: + return + + self.assert_no_active_block_jobs() + result = self.vm.qmp('block-commit', device='drive0', top=mid_img, + base=backing_img, speed=(self.image_len / 4)) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('query-block') + self.assert_qmp(result, 'return[0]/inserted/file', test_img) + self.assert_qmp(result, 'return[0]/inserted/drv', iotests.imgfmt) + self.assert_qmp(result, 'return[0]/inserted/backing_file', mid_img) + self.assert_qmp(result, 'return[0]/inserted/backing_file_depth', 2) + self.assert_qmp(result, 'return[0]/inserted/image/filename', test_img) + self.assert_qmp(result, 'return[0]/inserted/image/backing-image/filename', mid_img) + self.assert_qmp(result, 'return[0]/inserted/image/backing-image/backing-image/filename', backing_img) + + result = self.vm.qmp('query-blockstats') + self.assert_qmp(result, 'return[0]/node-name', 'top') + self.assert_qmp(result, 'return[0]/backing/node-name', 'mid') + self.assert_qmp(result, 'return[0]/backing/backing/node-name', 'base') + + self.cancel_and_wait() + self.assert_no_active_block_jobs() + class TestRelativePaths(ImageCommitTestCase): image_len = 1 * 1024 * 1024 test_len = 1 * 1024 * 256 diff --git a/tests/qemu-iotests/040.out b/tests/qemu-iotests/040.out index 6d9bee1a4b..e20a75ce4f 100644 --- a/tests/qemu-iotests/040.out +++ b/tests/qemu-iotests/040.out @@ -1,5 +1,5 @@ -........................... +............................. ---------------------------------------------------------------------- -Ran 27 tests +Ran 29 tests OK diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041 index 2f54986434..4cda540735 100755 --- a/tests/qemu-iotests/041 +++ b/tests/qemu-iotests/041 @@ -42,7 +42,7 @@ class TestSingleDrive(iotests.QMPTestCase): def setUp(self): iotests.create_image(backing_img, self.image_len) qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) - self.vm = iotests.VM().add_drive(test_img) + self.vm = iotests.VM().add_drive(test_img, "node-name=top,backing.node-name=base") if iotests.qemu_default_machine == 'pc': self.vm.add_drive(None, 'media=cdrom', 'ide') self.vm.launch() @@ -103,14 +103,12 @@ class TestSingleDrive(iotests.QMPTestCase): target=self.qmp_target) self.assert_qmp(result, 'return', {}) - result = self.vm.qmp('block-job-pause', device='drive0') - self.assert_qmp(result, 'return', {}) + self.pause_job('drive0') - time.sleep(1) result = self.vm.qmp('query-block-jobs') offset = self.dictpath(result, 'return[0]/offset') - time.sleep(1) + time.sleep(0.5) result = self.vm.qmp('query-block-jobs') self.assert_qmp(result, 'return[0]/offset', offset) @@ -169,6 +167,42 @@ class TestSingleDrive(iotests.QMPTestCase): self.assertTrue(iotests.compare_images(test_img, target_img), 'target image does not match source after mirroring') + # Tests that the insertion of the mirror_top filter node doesn't make a + # difference to query-block + def test_implicit_node(self): + self.assert_no_active_block_jobs() + + result = self.vm.qmp(self.qmp_cmd, device='drive0', sync='full', + target=self.qmp_target) + self.assert_qmp(result, 'return', {}) + + result = self.vm.qmp('query-block') + self.assert_qmp(result, 'return[0]/inserted/file', test_img) + self.assert_qmp(result, 'return[0]/inserted/drv', iotests.imgfmt) + self.assert_qmp(result, 'return[0]/inserted/backing_file', backing_img) + self.assert_qmp(result, 'return[0]/inserted/backing_file_depth', 1) + self.assert_qmp(result, 'return[0]/inserted/image/filename', test_img) + self.assert_qmp(result, 'return[0]/inserted/image/backing-image/filename', backing_img) + + result = self.vm.qmp('query-blockstats') + self.assert_qmp(result, 'return[0]/node-name', 'top') + self.assert_qmp(result, 'return[0]/backing/node-name', 'base') + + self.cancel_and_wait(force=True) + result = self.vm.qmp('query-block') + self.assert_qmp(result, 'return[0]/inserted/file', test_img) + self.assert_qmp(result, 'return[0]/inserted/drv', iotests.imgfmt) + self.assert_qmp(result, 'return[0]/inserted/backing_file', backing_img) + self.assert_qmp(result, 'return[0]/inserted/backing_file_depth', 1) + self.assert_qmp(result, 'return[0]/inserted/image/filename', test_img) + self.assert_qmp(result, 'return[0]/inserted/image/backing-image/filename', backing_img) + + result = self.vm.qmp('query-blockstats') + self.assert_qmp(result, 'return[0]/node-name', 'top') + self.assert_qmp(result, 'return[0]/backing/node-name', 'base') + + self.vm.shutdown() + def test_medium_not_found(self): if iotests.qemu_default_machine != 'pc': return @@ -860,14 +894,12 @@ class TestRepairQuorum(iotests.QMPTestCase): target=quorum_repair_img, format=iotests.imgfmt) self.assert_qmp(result, 'return', {}) - result = self.vm.qmp('block-job-pause', device='job0') - self.assert_qmp(result, 'return', {}) + self.pause_job('job0') - time.sleep(1) result = self.vm.qmp('query-block-jobs') offset = self.dictpath(result, 'return[0]/offset') - time.sleep(1) + time.sleep(0.5) result = self.vm.qmp('query-block-jobs') self.assert_qmp(result, 'return[0]/offset', offset) diff --git a/tests/qemu-iotests/041.out b/tests/qemu-iotests/041.out index e30fd3b05b..c28b392b87 100644 --- a/tests/qemu-iotests/041.out +++ b/tests/qemu-iotests/041.out @@ -1,5 +1,5 @@ -............................................................................... +..................................................................................... ---------------------------------------------------------------------- -Ran 79 tests +Ran 85 tests OK diff --git a/tests/qemu-iotests/055 b/tests/qemu-iotests/055 index ba4da65c77..e1206caf9b 100755 --- a/tests/qemu-iotests/055 +++ b/tests/qemu-iotests/055 @@ -89,11 +89,12 @@ class TestSingleDrive(iotests.QMPTestCase): self.assert_qmp(result, 'return', {}) self.vm.resume_drive('drive0') - time.sleep(1) + self.pause_job('drive0') + result = self.vm.qmp('query-block-jobs') offset = self.dictpath(result, 'return[0]/offset') - time.sleep(1) + time.sleep(0.5) result = self.vm.qmp('query-block-jobs') self.assert_qmp(result, 'return[0]/offset', offset) @@ -302,11 +303,12 @@ class TestSingleTransaction(iotests.QMPTestCase): self.assert_qmp(result, 'return', {}) self.vm.resume_drive('drive0') - time.sleep(1) + self.pause_job('drive0') + result = self.vm.qmp('query-block-jobs') offset = self.dictpath(result, 'return[0]/offset') - time.sleep(1) + time.sleep(0.5) result = self.vm.qmp('query-block-jobs') self.assert_qmp(result, 'return[0]/offset', offset) @@ -529,11 +531,12 @@ class TestDriveCompression(iotests.QMPTestCase): self.assert_qmp(result, 'return', {}) self.vm.resume_drive('drive0') - time.sleep(1) + self.pause_job('drive0') + result = self.vm.qmp('query-block-jobs') offset = self.dictpath(result, 'return[0]/offset') - time.sleep(1) + time.sleep(0.5) result = self.vm.qmp('query-block-jobs') self.assert_qmp(result, 'return[0]/offset', offset) diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 0961f8cc4e..287f0ea27d 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -175,7 +175,7 @@ 175 auto quick 176 rw auto backing 177 rw auto quick -178 auto quick +178 auto 179 rw auto quick 181 rw auto migration 182 rw auto quick @@ -183,4 +183,4 @@ 185 rw auto 186 rw auto 188 rw auto quick -189 rw auto quick +189 rw auto diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py index abcf3c10e2..22439c43d3 100644 --- a/tests/qemu-iotests/iotests.py +++ b/tests/qemu-iotests/iotests.py @@ -27,6 +27,7 @@ sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'scripts')) import qtest import struct import json +import signal # This will not work if arguments contain spaces but is necessary if we @@ -137,6 +138,20 @@ def log(msg, filters=[]): msg = flt(msg) print msg +class Timeout: + def __init__(self, seconds, errmsg = "Timeout"): + self.seconds = seconds + self.errmsg = errmsg + def __enter__(self): + signal.signal(signal.SIGALRM, self.timeout) + signal.setitimer(signal.ITIMER_REAL, self.seconds) + return self + def __exit__(self, type, value, traceback): + signal.setitimer(signal.ITIMER_REAL, 0) + return False + def timeout(self, signum, frame): + raise Exception(self.errmsg) + class VM(qtest.QEMUQtestMachine): '''A QEMU VM''' @@ -346,6 +361,18 @@ class QMPTestCase(unittest.TestCase): event = self.wait_until_completed(drive=drive) self.assert_qmp(event, 'data/type', 'mirror') + def pause_job(self, job_id='job0'): + result = self.vm.qmp('block-job-pause', device=job_id) + self.assert_qmp(result, 'return', {}) + + with Timeout(1, "Timeout waiting for job to pause"): + while True: + result = self.vm.qmp('query-block-jobs') + for job in result['return']: + if job['device'] == job_id and job['paused'] == True and job['busy'] == False: + return job + + def notrun(reason): '''Skip this test suite''' # Each test in qemu-iotests has a number ("seq") |