mirror of https://gitee.com/openkylin/qemu.git
Block layer patches for 2.10.0-rc0
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJZdgFKAAoJEH8JsnLIjy/WT8wQAIbx1EX+gfSQ5rOE1QXvO1PY rQBYjhbzI8VJ/g8l/cII5i3bmd1kgtbY49o4PWOrdZBBDjAofr7Z7gBvKQJscEcX +uzhhoCJjypiyLh8+eppaLEdWnriFV2YE4FshGFQMB1Jtc8Wdbg6wNn2am5UEk/i DALSGyZiVnxe5CdwZN5PeJEWESr302zvGzN5rzh4EQ1WJ5rMLbsyMIodvPEv2YNR rvHwcDyB6oWAbMuxKE6m8blvOOa7JqkKvIlkk1Nuz0Mfk4edWyZgFq8HAEp4y6cA UQI9nu7CouOjUyXkB3BaRQk4o0pmu/jidj6i09xiixSKdTLd4jzxhTSKJ2TiWL5l tiRLjRCK8a16raTywlM3LZ50ujbbQpHpV88IueKlBHRt/iU0zrYiOrB50XTSNr0j He77WAWmXGl2NifeOJ4nk6aucWayp1spJZoAozGtM+OpUfyvb5qr0TRDmovSdKX3 hKbKYwouOohxA3zZbmOW6IUiGgvrIWMejSJ3WjLGQyaVvwprtRRzhpKHBBGOhbEX eej/DssXZCRiYb0L+evXKRSleL+HZqdP35vZhDR7oMwd/4QPZ1URFLvI8Vh0daqb cjvMz63V+LDRPn//IAAyUephk51UN6xucz9lbvmq6hXXypKE8tH5+IwoTAWZ0xmo cHPZwQseF7TDiNpfndHa =OzLv -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
50104f5ac5
13
block.c
13
block.c
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
33
block/qapi.c
33
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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
#
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
...........................
|
||||
.............................
|
||||
----------------------------------------------------------------------
|
||||
Ran 27 tests
|
||||
Ran 29 tests
|
||||
|
||||
OK
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
...............................................................................
|
||||
.....................................................................................
|
||||
----------------------------------------------------------------------
|
||||
Ran 79 tests
|
||||
Ran 85 tests
|
||||
|
||||
OK
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
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 @@ def complete_and_wait(self, drive='drive0', wait_ready=True):
|
|||
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")
|
||||
|
|
Loading…
Reference in New Issue