Block layer patches:

- qemu-img: fix info --backing-chain --image-opts
 - Error out on image creation with conflicting size options
 - Fix external snapshot with VM state
 - hmp: Allow using qdev ID for qemu-io command
 - Misc code cleanup
 - Many iotests improvements
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJd+7H/AAoJEH8JsnLIjy/WwIoP/igzSCfiH7yOzWexk7J7DUh7
 SplXRiBQSQAZ8KD2umUk80UO6/W19rHAl3bLLu50D5uzQ5PNz1wSW2S81JZsj0nQ
 ErUEr5yxLGAI/zHIw/LrjUSEygbqcZ21R7foNmIy3lInEXf6gGwPQEnZnZgGkH0x
 v5jwv1HpUpEyetnHunX2cK3JpSNEJCYsV+X1nzDwhjYFuGQq0nlhgUZ8BDt6+fEr
 b/S3TuHmj/FXMH+5wrSr0LiCKaIyAwPdREvC+61aklMNFuA8YwF33tOaJLoWeQCD
 qhxFA8jVd8b3dQ0NZXXbliXST5d6AzjpeqbNzsyKze1duVfcfF1RYsC6McojpQ7f
 9qFIXPC9IHe3sNkUZpTtvONLnmCeHTc9lwVIyVp9B5KXcmcLedvYM04WqhZ+/eeJ
 BfgCvXOyF9sL2GaVPFD+98E2DOYG4dI4rmzqn98kQj+RAXDFvvJ+zxuDUC9omE6T
 pVvxczGPXmnxP2ITRNljJyLVCN1YgE2g9S0GAXNM2i4uOXvhFToEwrJLFytVeVsw
 UwtYkE0F8KJyqjje5N3HiXclBVa++PK3+jjNFA+3B6XZ9wcZZRS2ZXmzsyNOJ7qG
 AeIPtrqBCz+QKsHtmS9CwYpvLrPafobHA3WS2z0dsevcWBHYBQBEM2EgXRFC3N3a
 mymYGxMOsG6+8onwqwjJ
 =laVP
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging

Block layer patches:

- qemu-img: fix info --backing-chain --image-opts
- Error out on image creation with conflicting size options
- Fix external snapshot with VM state
- hmp: Allow using qdev ID for qemu-io command
- Misc code cleanup
- Many iotests improvements

# gpg: Signature made Thu 19 Dec 2019 17:23:11 GMT
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream: (30 commits)
  iotests: Test external snapshot with VM state
  hmp: Allow using qdev ID for qemu-io command
  block: Activate recursively even for already active nodes
  iotests: 211: Remove duplication with VM.blockdev_create()
  iotests: 207: Remove duplication with VM.blockdev_create()
  iotests: 266: Convert to VM.blockdev_create()
  iotests: 237: Convert to VM.blockdev_create()
  iotests: 213: Convert to VM.blockdev_create()
  iotests: 212: Convert to VM.blockdev_create()
  iotests: 210: Convert to VM.blockdev_create()
  iotests: 206: Convert to VM.blockdev_create()
  iotests: 255: Drop blockdev_create()
  iotests: Create VM.blockdev_create()
  qcow2: Move error check of local_err near its assignment
  iotests: Fix IMGOPTSSYNTAX for nbd
  iotests/273: Filter format-specific information
  iotests: Add more "_require_drivers" checks to the shell-based tests
  MAINTAINERS: fix qcow2-bitmap.c under Dirty Bitmaps header
  qcow2: Use offset_into_cluster()
  iotests: Support job-complete in run_job()
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-12-20 18:25:32 +00:00
commit 1010af540b
32 changed files with 700 additions and 505 deletions

View file

@ -1872,12 +1872,12 @@ M: John Snow <jsnow@redhat.com>
R: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
L: qemu-block@nongnu.org
S: Supported
F: util/hbitmap.c
F: block/dirty-bitmap.c
F: include/qemu/hbitmap.h
F: include/block/dirty-bitmap.h
F: qcow2-bitmap.c
F: block/dirty-bitmap.c
F: block/qcow2-bitmap.c
F: migration/block-dirty-bitmap.c
F: util/hbitmap.c
F: tests/test-hbitmap.c
F: docs/interop/bitmaps.rst
T: git https://github.com/jnsnow/qemu.git bitmaps

60
block.c
View file

@ -5335,10 +5335,6 @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs,
return;
}
if (!(bs->open_flags & BDRV_O_INACTIVE)) {
return;
}
QLIST_FOREACH(child, &bs->children, next) {
bdrv_co_invalidate_cache(child->bs, &local_err);
if (local_err) {
@ -5360,34 +5356,36 @@ static void coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs,
* just keep the extended permissions for the next time that an activation
* of the image is tried.
*/
bs->open_flags &= ~BDRV_O_INACTIVE;
bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, NULL, &local_err);
if (ret < 0) {
bs->open_flags |= BDRV_O_INACTIVE;
error_propagate(errp, local_err);
return;
}
bdrv_set_perm(bs, perm, shared_perm);
if (bs->drv->bdrv_co_invalidate_cache) {
bs->drv->bdrv_co_invalidate_cache(bs, &local_err);
if (local_err) {
if (bs->open_flags & BDRV_O_INACTIVE) {
bs->open_flags &= ~BDRV_O_INACTIVE;
bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, NULL, &local_err);
if (ret < 0) {
bs->open_flags |= BDRV_O_INACTIVE;
error_propagate(errp, local_err);
return;
}
}
bdrv_set_perm(bs, perm, shared_perm);
FOR_EACH_DIRTY_BITMAP(bs, bm) {
bdrv_dirty_bitmap_skip_store(bm, false);
}
if (bs->drv->bdrv_co_invalidate_cache) {
bs->drv->bdrv_co_invalidate_cache(bs, &local_err);
if (local_err) {
bs->open_flags |= BDRV_O_INACTIVE;
error_propagate(errp, local_err);
return;
}
}
ret = refresh_total_sectors(bs, bs->total_sectors);
if (ret < 0) {
bs->open_flags |= BDRV_O_INACTIVE;
error_setg_errno(errp, -ret, "Could not refresh total sector count");
return;
FOR_EACH_DIRTY_BITMAP(bs, bm) {
bdrv_dirty_bitmap_skip_store(bm, false);
}
ret = refresh_total_sectors(bs, bs->total_sectors);
if (ret < 0) {
bs->open_flags |= BDRV_O_INACTIVE;
error_setg_errno(errp, -ret, "Could not refresh total sector count");
return;
}
}
QLIST_FOREACH(parent, &bs->parents, next_parent) {
@ -5751,12 +5749,11 @@ void bdrv_img_create(const char *filename, const char *fmt,
return;
}
/* Create parameter list */
create_opts = qemu_opts_append(create_opts, drv->create_opts);
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
/* Create parameter list with default values */
opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size, &error_abort);
/* Parse -o options */
if (options) {
@ -5766,6 +5763,13 @@ void bdrv_img_create(const char *filename, const char *fmt,
}
}
if (!qemu_opt_get(opts, BLOCK_OPT_SIZE)) {
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size, &error_abort);
} else if (img_size != UINT64_C(-1)) {
error_setg(errp, "The image size must be specified only once");
goto out;
}
if (base_filename) {
qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, base_filename, &local_err);
if (local_err) {

View file

@ -367,7 +367,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
return -EINVAL;
}
if (bitmaps_ext.bitmap_directory_offset & (s->cluster_size - 1)) {
if (offset_into_cluster(s, bitmaps_ext.bitmap_directory_offset)) {
error_setg(errp, "bitmaps_ext: "
"invalid bitmap directory offset");
return -EINVAL;
@ -1705,14 +1705,14 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
if (!(bdrv_get_flags(bs) & BDRV_O_INACTIVE)) {
/* It's case 1, 2 or 3.2. Or 3.1 which is BUG in management layer. */
bool header_updated = qcow2_load_dirty_bitmaps(bs, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
}
update_header = update_header && !header_updated;
}
if (local_err != NULL) {
error_propagate(errp, local_err);
ret = -EINVAL;
goto fail;
}
if (update_header) {
ret = qcow2_update_header(bs);
@ -1722,7 +1722,8 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
}
}
bs->supported_zero_flags = header.version >= 3 ? BDRV_REQ_MAY_UNMAP : 0;
bs->supported_zero_flags = header.version >= 3 ?
BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK : 0;
/* Repair image if dirty */
if (!(flags & (BDRV_O_CHECK | BDRV_O_INACTIVE)) && !bs->read_only &&
@ -1958,9 +1959,8 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
{
BDRVQcow2State *s = bs->opaque;
uint64_t cluster_offset;
int index_in_cluster, ret;
unsigned int bytes;
int status = 0;
int ret, status = 0;
qemu_co_mutex_lock(&s->lock);
@ -1981,8 +1981,7 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs,
if ((ret == QCOW2_CLUSTER_NORMAL || ret == QCOW2_CLUSTER_ZERO_ALLOC) &&
!s->crypto) {
index_in_cluster = offset & (s->cluster_size - 1);
*map = cluster_offset | index_in_cluster;
*map = cluster_offset | offset_into_cluster(s, offset);
*file = s->data_file->bs;
status |= BDRV_BLOCK_OFFSET_VALID;
}

View file

@ -261,7 +261,8 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
return;
}
if (speed < 0) {
error_setg(errp, QERR_INVALID_PARAMETER, "speed");
error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "speed",
"a non-negative value");
return;
}

View file

@ -1875,9 +1875,11 @@ ETEXI
{
.name = "qemu-io",
.args_type = "device:B,command:s",
.params = "[device] \"[command]\"",
.help = "run a qemu-io command on a block device",
.args_type = "qdev:-d,device:B,command:s",
.params = "[-d] [device] \"[command]\"",
.help = "run a qemu-io command on a block device\n\t\t\t"
"-d: [device] is a device ID rather than a "
"drive ID or node name",
.cmd = hmp_qemu_io,
},

View file

@ -2467,23 +2467,31 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
{
BlockBackend *blk;
BlockBackend *local_blk = NULL;
bool qdev = qdict_get_try_bool(qdict, "qdev", false);
const char* device = qdict_get_str(qdict, "device");
const char* command = qdict_get_str(qdict, "command");
Error *err = NULL;
int ret;
blk = blk_by_name(device);
if (!blk) {
BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err);
if (bs) {
blk = local_blk = blk_new(bdrv_get_aio_context(bs),
0, BLK_PERM_ALL);
ret = blk_insert_bs(blk, bs, &err);
if (ret < 0) {
if (qdev) {
blk = blk_by_qdev_id(device, &err);
if (!blk) {
goto fail;
}
} else {
blk = blk_by_name(device);
if (!blk) {
BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err);
if (bs) {
blk = local_blk = blk_new(bdrv_get_aio_context(bs),
0, BLK_PERM_ALL);
ret = blk_insert_bs(blk, bs, &err);
if (ret < 0) {
goto fail;
}
} else {
goto fail;
}
} else {
goto fail;
}
}

View file

@ -2963,9 +2963,13 @@
#
# Driver specific block device options for the NVMe backend.
#
# @device: controller address of the NVMe device.
# @device: PCI controller address of the NVMe device in
# format hhhh:bb:ss.f (host:bus:slot.function)
# @namespace: namespace number of the device, starting from 1.
#
# Note that the PCI @device must have been unbound from any host
# kernel driver before instructing QEMU to add the blockdev.
#
# Since: 2.12
##
{ 'struct': 'BlockdevOptionsNVMe',

View file

@ -2680,7 +2680,10 @@ static ImageInfoList *collect_image_info_list(bool image_opts,
blk_unref(blk);
/* Clear parameters that only apply to the topmost image */
filename = fmt = NULL;
image_opts = false;
if (chain) {
if (info->has_full_backing_filename) {
filename = info->full_backing_filename;

View file

@ -943,7 +943,7 @@ class TestSetSpeed(iotests.QMPTestCase):
self.assert_no_active_block_jobs()
result = self.vm.qmp('block-stream', device='drive0', speed=-1)
self.assert_qmp(result, 'error/desc', "Invalid parameter 'speed'")
self.assert_qmp(result, 'error/desc', "Parameter 'speed' expects a non-negative value")
self.assert_no_active_block_jobs()
@ -952,7 +952,7 @@ class TestSetSpeed(iotests.QMPTestCase):
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('block-job-set-speed', device='drive0', speed=-1)
self.assert_qmp(result, 'error/desc', "Invalid parameter 'speed'")
self.assert_qmp(result, 'error/desc', "Parameter 'speed' expects a non-negative value")
self.cancel_and_wait(resume=True)

View file

@ -78,6 +78,11 @@ for s in $sizes; do
test_qemu_img create -f $IMGFMT -o size=$s "$TEST_IMG"
done
echo "== 4. Specify size twice (-o and traditional parameter) =="
echo
test_qemu_img create -f $IMGFMT -o size=10M "$TEST_IMG" 20M
echo "== Check correct interpretation of suffixes for cluster size =="
echo
sizes="1024 1024b 1k 1K 1M "

View file

@ -121,6 +121,11 @@ qemu-img: TEST_DIR/t.qcow2: Parameter 'size' expects a non-negative number below
Optional suffix k, M, G, T, P or E means kilo-, mega-, giga-, tera-, peta-
and exabytes, respectively.
== 4. Specify size twice (-o and traditional parameter) ==
qemu-img create -f qcow2 -o size=10M TEST_DIR/t.qcow2 20M
qemu-img: TEST_DIR/t.qcow2: The image size must be specified only once
== Check correct interpretation of suffixes for cluster size ==
qemu-img create -f qcow2 -o cluster_size=1024 TEST_DIR/t.qcow2 64M

View file

@ -41,6 +41,7 @@ _supported_proto file
# A compat=0.10 image is created in this test which does not support anything
# other than refcount_bits=16
_unsupported_imgopts 'refcount_bits=\([^1]\|.\([^6]\|$\)\)'
_require_drivers nbd
do_run_qemu()
{

View file

@ -25,16 +25,6 @@ from iotests import imgfmt
iotests.verify_image_format(supported_fmts=['qcow2'])
def blockdev_create(vm, options):
result = vm.qmp_log('blockdev-create',
filters=[iotests.filter_qmp_testfiles],
job_id='job0', options=options)
if 'return' in result:
assert result['return'] == {}
vm.run_job('job0')
iotests.log("")
with iotests.FilePath('t.qcow2') as disk_path, \
iotests.FilePath('t.qcow2.base') as backing_path, \
iotests.VM() as vm:
@ -50,18 +40,18 @@ with iotests.FilePath('t.qcow2') as disk_path, \
size = 128 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.qmp_log('blockdev-add',
filters=[iotests.filter_qmp_testfiles],
driver='file', filename=disk_path,
node_name='imgfile')
blockdev_create(vm, { 'driver': imgfmt,
'file': 'imgfile',
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'imgfile',
'size': size })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -76,23 +66,23 @@ with iotests.FilePath('t.qcow2') as disk_path, \
size = 64 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0,
'preallocation': 'off',
'nocow': False })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0,
'preallocation': 'off',
'nocow': False })
blockdev_create(vm, { 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'version': 'v3',
'cluster-size': 65536,
'preallocation': 'off',
'lazy-refcounts': False,
'refcount-bits': 16 })
vm.blockdev_create({ 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'version': 'v3',
'cluster-size': 65536,
'preallocation': 'off',
'lazy-refcounts': False,
'refcount-bits': 16 })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -107,23 +97,23 @@ with iotests.FilePath('t.qcow2') as disk_path, \
size = 32 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0,
'preallocation': 'falloc',
'nocow': True })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0,
'preallocation': 'falloc',
'nocow': True })
blockdev_create(vm, { 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'version': 'v3',
'cluster-size': 2097152,
'preallocation': 'metadata',
'lazy-refcounts': True,
'refcount-bits': 1 })
vm.blockdev_create({ 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'version': 'v3',
'cluster-size': 2097152,
'preallocation': 'metadata',
'lazy-refcounts': True,
'refcount-bits': 1 })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -135,20 +125,20 @@ with iotests.FilePath('t.qcow2') as disk_path, \
iotests.log("")
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0 })
blockdev_create(vm, { 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'backing-file': backing_path,
'backing-fmt': 'qcow2',
'version': 'v2',
'cluster-size': 512 })
vm.blockdev_create({ 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'backing-file': backing_path,
'backing-fmt': 'qcow2',
'version': 'v2',
'cluster-size': 512 })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -160,22 +150,22 @@ with iotests.FilePath('t.qcow2') as disk_path, \
iotests.log("")
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'encrypt': {
'format': 'luks',
'key-secret': 'keysec0',
'cipher-alg': 'twofish-128',
'cipher-mode': 'ctr',
'ivgen-alg': 'plain64',
'ivgen-hash-alg': 'md5',
'hash-alg': 'sha1',
'iter-time': 10,
}})
vm.blockdev_create({ 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'encrypt': {
'format': 'luks',
'key-secret': 'keysec0',
'cipher-alg': 'twofish-128',
'cipher-mode': 'ctr',
'ivgen-alg': 'plain64',
'ivgen-hash-alg': 'md5',
'hash-alg': 'sha1',
'iter-time': 10,
}})
vm.shutdown()
iotests.img_info_log(disk_path)
@ -187,9 +177,9 @@ with iotests.FilePath('t.qcow2') as disk_path, \
iotests.log("")
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': "this doesn't exist",
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': "this doesn't exist",
'size': size })
vm.shutdown()
#
@ -211,9 +201,9 @@ with iotests.FilePath('t.qcow2') as disk_path, \
vm.launch()
for size in [ 1234, 18446744073709551104, 9223372036854775808,
9223372036854775296 ]:
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': size })
vm.shutdown()
#
@ -222,20 +212,20 @@ with iotests.FilePath('t.qcow2') as disk_path, \
iotests.log("=== Invalid version ===")
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'version': 'v1' })
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'version': 'v2',
'lazy-refcounts': True })
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'version': 'v2',
'refcount-bits': 8 })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'version': 'v1' })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'version': 'v2',
'lazy-refcounts': True })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'version': 'v2',
'refcount-bits': 8 })
vm.shutdown()
#
@ -244,15 +234,15 @@ with iotests.FilePath('t.qcow2') as disk_path, \
iotests.log("=== Invalid backing file options ===")
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'backing-file': '/dev/null',
'preallocation': 'full' })
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'backing-fmt': imgfmt })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'backing-file': '/dev/null',
'preallocation': 'full' })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'backing-fmt': imgfmt })
vm.shutdown()
#
@ -262,14 +252,14 @@ with iotests.FilePath('t.qcow2') as disk_path, \
vm.launch()
for csize in [ 1234, 128, 4194304, 0 ]:
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'cluster-size': csize })
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 281474976710656,
'cluster-size': 512 })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'cluster-size': csize })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 281474976710656,
'cluster-size': 512 })
vm.shutdown()
#
@ -279,8 +269,8 @@ with iotests.FilePath('t.qcow2') as disk_path, \
vm.launch()
for refcount_bits in [ 128, 0, 7 ]:
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'refcount-bits': refcount_bits })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'refcount-bits': refcount_bits })
vm.shutdown()

View file

@ -35,13 +35,7 @@ def filter_hash(qmsg):
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_qmp_testfiles, filter_hash])
if 'return' in result:
assert result['return'] == {}
vm.run_job('job0')
iotests.log("")
vm.blockdev_create(options, filters=[iotests.filter_qmp_testfiles, filter_hash])
with iotests.FilePath('t.img') as disk_path, \
iotests.VM() as vm:

View file

@ -26,15 +26,6 @@ from iotests import imgfmt
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,
filters=[iotests.filter_qmp_testfiles])
if 'return' in result:
assert result['return'] == {}
vm.run_job('job0')
iotests.log("")
with iotests.FilePath('t.luks') as disk_path, \
iotests.VM() as vm:
@ -49,18 +40,18 @@ with iotests.FilePath('t.luks') as disk_path, \
size = 128 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
node_name='imgfile', filters=[iotests.filter_qmp_testfiles])
blockdev_create(vm, { 'driver': imgfmt,
'file': 'imgfile',
'key-secret': 'keysec0',
'size': size,
'iter-time': 10 })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'imgfile',
'key-secret': 'keysec0',
'size': size,
'iter-time': 10 })
vm.shutdown()
# TODO Proper support for images to be used with imgopts and/or protocols
@ -79,22 +70,22 @@ with iotests.FilePath('t.luks') as disk_path, \
size = 64 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0 })
blockdev_create(vm, { 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'key-secret': 'keysec0',
'cipher-alg': 'twofish-128',
'cipher-mode': 'ctr',
'ivgen-alg': 'plain64',
'ivgen-hash-alg': 'md5',
'hash-alg': 'sha1',
'iter-time': 10 })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.blockdev_create({ 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'key-secret': 'keysec0',
'cipher-alg': 'twofish-128',
'cipher-mode': 'ctr',
'ivgen-alg': 'plain64',
'ivgen-hash-alg': 'md5',
'hash-alg': 'sha1',
'iter-time': 10 })
vm.shutdown()
# TODO Proper support for images to be used with imgopts and/or protocols
@ -113,9 +104,9 @@ with iotests.FilePath('t.luks') as disk_path, \
size = 64 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': "this doesn't exist",
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': "this doesn't exist",
'size': size })
vm.shutdown()
#
@ -126,11 +117,11 @@ with iotests.FilePath('t.luks') as disk_path, \
vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'key-secret': 'keysec0',
'size': 0,
'iter-time': 10 })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'key-secret': 'keysec0',
'size': 0,
'iter-time': 10 })
vm.shutdown()
# TODO Proper support for images to be used with imgopts and/or protocols
@ -157,10 +148,10 @@ with iotests.FilePath('t.luks') as disk_path, \
vm.launch()
for size in [ 18446744073709551104, 9223372036854775808, 9223372036854775296 ]:
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'key-secret': 'keysec0',
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'key-secret': 'keysec0',
'size': size })
vm.shutdown()
#

View file

@ -27,15 +27,9 @@ 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,
filters=[iotests.filter_qmp_testfiles])
if 'return' in result:
assert result['return'] == {}
error = vm.run_job('job0')
if error and 'Could not allocate bmap' in error:
iotests.notrun('Insufficient memory')
iotests.log("")
error = vm.blockdev_create(options)
if error and 'Could not allocate bmap' in error:
iotests.notrun('Insufficient memory')
with iotests.FilePath('t.vdi') as disk_path, \
iotests.VM() as vm:

View file

@ -26,15 +26,6 @@ from iotests import imgfmt
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,
filters=[iotests.filter_qmp_testfiles])
if 'return' in result:
assert result['return'] == {}
vm.run_job('job0')
iotests.log("")
with iotests.FilePath('t.parallels') as disk_path, \
iotests.VM() as vm:
@ -47,16 +38,16 @@ with iotests.FilePath('t.parallels') as disk_path, \
size = 128 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
node_name='imgfile', filters=[iotests.filter_qmp_testfiles])
blockdev_create(vm, { 'driver': imgfmt,
'file': 'imgfile',
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'imgfile',
'size': size })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -71,16 +62,16 @@ with iotests.FilePath('t.parallels') as disk_path, \
size = 64 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0 })
blockdev_create(vm, { 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'cluster-size': 1048576 })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.blockdev_create({ 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'cluster-size': 1048576 })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -95,16 +86,16 @@ with iotests.FilePath('t.parallels') as disk_path, \
size = 32 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0 })
blockdev_create(vm, { 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'cluster-size': 65536 })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.blockdev_create({ 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'cluster-size': 65536 })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -116,9 +107,9 @@ with iotests.FilePath('t.parallels') as disk_path, \
iotests.log("")
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': "this doesn't exist",
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': "this doesn't exist",
'size': size })
vm.shutdown()
#
@ -129,9 +120,9 @@ with iotests.FilePath('t.parallels') as disk_path, \
vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 0 })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 0 })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -143,9 +134,9 @@ with iotests.FilePath('t.parallels') as disk_path, \
iotests.log("")
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 4503599627369984})
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 4503599627369984})
vm.shutdown()
iotests.img_info_log(disk_path)
@ -171,9 +162,9 @@ with iotests.FilePath('t.parallels') as disk_path, \
vm.launch()
for size in [ 1234, 18446744073709551104, 9223372036854775808,
9223372036854775296, 4503599627370497 ]:
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': size })
vm.shutdown()
#
@ -185,12 +176,12 @@ with iotests.FilePath('t.parallels') as disk_path, \
vm.launch()
for csize in [ 1234, 128, 4294967296, 9223372036854775808,
18446744073709551104, 0 ]:
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'cluster-size': csize })
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 281474976710656,
'cluster-size': 512 })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'cluster-size': csize })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 281474976710656,
'cluster-size': 512 })
vm.shutdown()

View file

@ -26,15 +26,6 @@ from iotests import imgfmt
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,
filters=[iotests.filter_qmp_testfiles])
if 'return' in result:
assert result['return'] == {}
vm.run_job('job0')
iotests.log("")
with iotests.FilePath('t.vhdx') as disk_path, \
iotests.VM() as vm:
@ -47,16 +38,16 @@ with iotests.FilePath('t.vhdx') as disk_path, \
size = 128 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
node_name='imgfile', filters=[iotests.filter_qmp_testfiles])
blockdev_create(vm, { 'driver': imgfmt,
'file': 'imgfile',
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'imgfile',
'size': size })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -71,19 +62,19 @@ with iotests.FilePath('t.vhdx') as disk_path, \
size = 64 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0 })
blockdev_create(vm, { 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'log-size': 1048576,
'block-size': 8388608,
'subformat': 'dynamic',
'block-state-zero': True })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.blockdev_create({ 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'log-size': 1048576,
'block-size': 8388608,
'subformat': 'dynamic',
'block-state-zero': True })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -98,19 +89,19 @@ with iotests.FilePath('t.vhdx') as disk_path, \
size = 32 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0 })
blockdev_create(vm, { 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'log-size': 8388608,
'block-size': 268435456,
'subformat': 'fixed',
'block-state-zero': False })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.blockdev_create({ 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'log-size': 8388608,
'block-size': 268435456,
'subformat': 'fixed',
'block-state-zero': False })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -122,9 +113,9 @@ with iotests.FilePath('t.vhdx') as disk_path, \
iotests.log("")
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': "this doesn't exist",
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': "this doesn't exist",
'size': size })
vm.shutdown()
#
@ -135,9 +126,9 @@ with iotests.FilePath('t.vhdx') as disk_path, \
vm.add_blockdev('driver=file,filename=%s,node-name=node0' % (disk_path))
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 0 })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 0 })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -149,9 +140,9 @@ with iotests.FilePath('t.vhdx') as disk_path, \
iotests.log("")
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 70368744177664 })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 70368744177664 })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -176,9 +167,9 @@ with iotests.FilePath('t.vhdx') as disk_path, \
vm.launch()
for size in [ 18446744073709551104, 9223372036854775808,
9223372036854775296, 70368744177665 ]:
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': size })
vm.shutdown()
#
@ -189,10 +180,10 @@ with iotests.FilePath('t.vhdx') as disk_path, \
vm.launch()
for bsize in [ 1234567, 128, 3145728, 536870912, 0 ]:
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'block-size': bsize })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'block-size': bsize })
vm.shutdown()
#
@ -203,8 +194,8 @@ with iotests.FilePath('t.vhdx') as disk_path, \
vm.launch()
for lsize in [ 1234567, 128, 4294967296, 0 ]:
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'log-size': lsize })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 67108864,
'log-size': lsize })
vm.shutdown()

View file

@ -26,15 +26,6 @@ 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,
filters=[iotests.filter_qmp_testfiles])
if 'return' in result:
assert result['return'] == {}
vm.run_job('job0')
iotests.log("")
with iotests.FilePath('t.vmdk') as disk_path, \
iotests.FilePath('t.vmdk.1') as extent1_path, \
iotests.FilePath('t.vmdk.2') as extent2_path, \
@ -50,16 +41,16 @@ with iotests.FilePath('t.vmdk') as disk_path, \
size = 5 * 1024 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.qmp_log('blockdev-add', driver='file', filename=disk_path,
node_name='imgfile', filters=[iotests.filter_qmp_testfiles])
blockdev_create(vm, { 'driver': imgfmt,
'file': 'imgfile',
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'imgfile',
'size': size })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -74,21 +65,21 @@ with iotests.FilePath('t.vmdk') as disk_path, \
size = 64 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0 })
blockdev_create(vm, { 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'extents': [],
'subformat': 'monolithicSparse',
'adapter-type': 'ide',
'hwversion': '4',
'zeroed-grain': False })
vm.blockdev_create({ 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'extents': [],
'subformat': 'monolithicSparse',
'adapter-type': 'ide',
'hwversion': '4',
'zeroed-grain': False })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -103,20 +94,20 @@ with iotests.FilePath('t.vmdk') as disk_path, \
size = 32 * 1024 * 1024
vm.launch()
blockdev_create(vm, { 'driver': 'file',
'filename': disk_path,
'size': 0 })
vm.blockdev_create({ 'driver': 'file',
'filename': disk_path,
'size': 0 })
blockdev_create(vm, { 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'extents': [],
'subformat': 'monolithicSparse',
'adapter-type': 'buslogic',
'zeroed-grain': True })
vm.blockdev_create({ 'driver': imgfmt,
'file': {
'driver': 'file',
'filename': disk_path,
},
'size': size,
'extents': [],
'subformat': 'monolithicSparse',
'adapter-type': 'buslogic',
'zeroed-grain': True })
vm.shutdown()
iotests.img_info_log(disk_path)
@ -128,9 +119,9 @@ with iotests.FilePath('t.vmdk') as disk_path, \
iotests.log("")
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': "this doesn't exist",
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': "this doesn't exist",
'size': size })
vm.shutdown()
#
@ -148,10 +139,10 @@ with iotests.FilePath('t.vmdk') as disk_path, \
vm.launch()
for adapter_type in [ 'ide', 'buslogic', 'lsilogic', 'legacyESX' ]:
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': size,
'adapter-type': adapter_type })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': size,
'adapter-type': adapter_type })
vm.shutdown()
# Invalid
@ -160,10 +151,10 @@ with iotests.FilePath('t.vmdk') as disk_path, \
vm.launch()
for adapter_type in [ 'foo', 'IDE', 'legacyesx', 1 ]:
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': size,
'adapter-type': adapter_type })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': size,
'adapter-type': adapter_type })
vm.shutdown()
#
@ -185,10 +176,10 @@ with iotests.FilePath('t.vmdk') as disk_path, \
iotests.log("")
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': size,
'subformat': 'monolithicFlat' })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': size,
'subformat': 'monolithicFlat' })
vm.shutdown()
# Correct extent
@ -196,11 +187,11 @@ with iotests.FilePath('t.vmdk') as disk_path, \
iotests.log("")
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': size,
'subformat': 'monolithicFlat',
'extents': ['ext1'] })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': size,
'subformat': 'monolithicFlat',
'extents': ['ext1'] })
vm.shutdown()
# Extra extent
@ -208,11 +199,11 @@ with iotests.FilePath('t.vmdk') as disk_path, \
iotests.log("")
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': 512,
'subformat': 'monolithicFlat',
'extents': ['ext1', 'ext2', 'ext3'] })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': 512,
'subformat': 'monolithicFlat',
'extents': ['ext1', 'ext2', 'ext3'] })
vm.shutdown()
# Split formats
@ -228,11 +219,11 @@ with iotests.FilePath('t.vmdk') as disk_path, \
extents = [ "ext%d" % (i) for i in range(1, num_extents + 1) ]
vm.launch()
blockdev_create(vm, { 'driver': imgfmt,
'file': 'node0',
'size': size,
'subformat': subfmt,
'extents': extents })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'node0',
'size': size,
'subformat': subfmt,
'extents': extents })
vm.shutdown()
iotests.img_info_log(disk_path)

View file

@ -25,16 +25,6 @@ from iotests import imgfmt
iotests.verify_image_format(supported_fmts=['qcow2'])
def blockdev_create(vm, options):
result = vm.qmp_log('blockdev-create',
filters=[iotests.filter_qmp_testfiles],
job_id='job0', options=options)
if 'return' in result:
assert result['return'] == {}
vm.run_job('job0')
iotests.log("")
iotests.log('Finishing a commit job with background reads')
iotests.log('============================================')
iotests.log('')

View file

@ -22,15 +22,6 @@ import iotests
from iotests import imgfmt
def blockdev_create(vm, 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')
# Successful image creation (defaults)
def implicit_defaults(vm, file_path):
iotests.log("=== Successful image creation (defaults) ===")
@ -40,9 +31,9 @@ def implicit_defaults(vm, file_path):
# (Close to 64 MB)
size = 8 * 964 * 17 * 512
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': size })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'protocol-node',
'size': size })
# Successful image creation (explicit defaults)
@ -54,11 +45,11 @@ def explicit_defaults(vm, file_path):
# (Close to 128 MB)
size = 16 * 964 * 17 * 512
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': size,
'subformat': 'dynamic',
'force-size': False })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'protocol-node',
'size': size,
'subformat': 'dynamic',
'force-size': False })
# Successful image creation (non-default options)
@ -69,11 +60,11 @@ def non_defaults(vm, file_path):
# Not representable in CHS (fine with force-size=True)
size = 1048576
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': size,
'subformat': 'fixed',
'force-size': True })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'protocol-node',
'size': size,
'subformat': 'fixed',
'force-size': True })
# Size not representable in CHS with force-size=False
@ -84,10 +75,10 @@ def non_chs_size_without_force(vm, file_path):
# Not representable in CHS (will not work with force-size=False)
size = 1048576
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': size,
'force-size': False })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'protocol-node',
'size': size,
'force-size': False })
# Zero size
@ -95,9 +86,9 @@ def zero_size(vm, file_path):
iotests.log("=== Zero size===")
iotests.log("")
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': 0 })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'protocol-node',
'size': 0 })
# Maximum CHS size
@ -105,9 +96,9 @@ def maximum_chs_size(vm, file_path):
iotests.log("=== Maximum CHS size===")
iotests.log("")
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': 16 * 65535 * 255 * 512 })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'protocol-node',
'size': 16 * 65535 * 255 * 512 })
# Actual maximum size
@ -115,10 +106,10 @@ def maximum_size(vm, file_path):
iotests.log("=== Actual maximum size===")
iotests.log("")
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': 0xff000000 * 512,
'force-size': True })
vm.blockdev_create({ 'driver': imgfmt,
'file': 'protocol-node',
'size': 0xff000000 * 512,
'force-size': True })
def main():
@ -132,9 +123,9 @@ def main():
vm.launch()
iotests.log('--- Creating empty file ---')
blockdev_create(vm, { 'driver': 'file',
'filename': file_path,
'size': 0 })
vm.blockdev_create({ 'driver': 'file',
'filename': file_path,
'size': 0 })
vm.qmp_log('blockdev-add', driver='file', filename=file_path,
node_name='protocol-node',

View file

@ -3,6 +3,7 @@
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
@ -13,6 +14,7 @@
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
image: TEST_IMG
file format: IMGFMT
virtual size: 64 MiB (67125248 bytes)
@ -23,6 +25,7 @@ cluster_size: 2097152
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
@ -33,6 +36,7 @@ cluster_size: 2097152
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
image: TEST_IMG
file format: IMGFMT
virtual size: 128 MiB (134250496 bytes)
@ -43,6 +47,7 @@ cluster_size: 2097152
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
@ -53,6 +58,7 @@ cluster_size: 2097152
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
image: TEST_IMG
file format: IMGFMT
virtual size: 1 MiB (1048576 bytes)
@ -62,6 +68,7 @@ virtual size: 1 MiB (1048576 bytes)
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
@ -73,6 +80,7 @@ Job failed: The requested image size cannot be represented in CHS geometry
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
qemu-img: Could not open 'TEST_IMG': File too small for a VHD header
--- Creating empty file ---
@ -80,6 +88,7 @@ qemu-img: Could not open 'TEST_IMG': File too small for a VHD header
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
@ -90,6 +99,7 @@ qemu-img: Could not open 'TEST_IMG': File too small for a VHD header
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
image: TEST_IMG
file format: IMGFMT
virtual size: 0 B (0 bytes)
@ -100,6 +110,7 @@ cluster_size: 2097152
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
@ -110,6 +121,7 @@ cluster_size: 2097152
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
image: TEST_IMG
file format: IMGFMT
virtual size: 127 GiB (136899993600 bytes)
@ -120,6 +132,7 @@ cluster_size: 2097152
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
@ -130,6 +143,7 @@ cluster_size: 2097152
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
image: TEST_IMG
file format: IMGFMT
virtual size: 1.99 TiB (2190433320960 bytes)

View file

@ -40,6 +40,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
_require_drivers copy-on-read
# Internal snapshots are (currently) impossible with refcount_bits=1
_unsupported_imgopts 'refcount_bits=1[^0-9]'

View file

@ -48,7 +48,8 @@ do_run_qemu()
run_qemu()
{
do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_qmp |
_filter_generated_node_ids | _filter_imgfmt | _filter_actual_image_size
_filter_generated_node_ids | _filter_imgfmt |
_filter_actual_image_size | _filter_img_info
}
TEST_IMG="$TEST_IMG.base" _make_test_img 64M

View file

@ -38,15 +38,6 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev
"cluster-size": 65536,
"format": "IMGFMT",
"actual-size": SIZE,
"format-specific": {
"type": "IMGFMT",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"refcount-bits": 16,
"corrupt": false
}
},
"full-backing-filename": "TEST_DIR/t.IMGFMT.base",
"backing-filename": "TEST_DIR/t.IMGFMT.base",
"dirty-flag": false
@ -57,15 +48,6 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev
"cluster-size": 65536,
"format": "IMGFMT",
"actual-size": SIZE,
"format-specific": {
"type": "IMGFMT",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"refcount-bits": 16,
"corrupt": false
}
},
"full-backing-filename": "TEST_DIR/t.IMGFMT.mid",
"backing-filename": "TEST_DIR/t.IMGFMT.mid",
"dirty-flag": false
@ -136,15 +118,6 @@ Testing: -blockdev file,node-name=base,filename=TEST_DIR/t.IMGFMT.base -blockdev
"cluster-size": 65536,
"format": "IMGFMT",
"actual-size": SIZE,
"format-specific": {
"type": "IMGFMT",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"refcount-bits": 16,
"corrupt": false
}
},
"full-backing-filename": "TEST_DIR/t.IMGFMT.base",
"backing-filename": "TEST_DIR/t.IMGFMT.base",
"dirty-flag": false

57
tests/qemu-iotests/279 Executable file
View file

@ -0,0 +1,57 @@
#!/usr/bin/env bash
#
# Test qemu-img --backing-chain --image-opts
#
# Copyright (C) 2019 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/>.
#
seq=$(basename "$0")
echo "QA output created by $seq"
status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
rm -f "$TEST_IMG.mid"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
# Backing files are required...
_supported_fmt qcow qcow2 vmdk qed
_supported_proto file
_supported_os Linux
TEST_IMG="$TEST_IMG.base" _make_test_img 64M
TEST_IMG="$TEST_IMG.mid" _make_test_img -b "$TEST_IMG.base"
_make_test_img -b "$TEST_IMG.mid"
echo
echo '== qemu-img info --backing-chain =='
_img_info --backing-chain | _filter_img_info
echo
echo '== qemu-img info --backing-chain --image-opts =='
TEST_IMG="driver=qcow2,file.driver=file,file.filename=$TEST_IMG" _img_info --backing-chain --image-opts | _filter_img_info
# success, all done
echo "*** done"
rm -f $seq.full
status=0

View file

@ -0,0 +1,35 @@
QA output created by 279
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
Formatting 'TEST_DIR/t.IMGFMT.mid', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.mid
== qemu-img info --backing-chain ==
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64 MiB (67108864 bytes)
backing file: TEST_DIR/t.IMGFMT.mid
image: TEST_DIR/t.IMGFMT.mid
file format: IMGFMT
virtual size: 64 MiB (67108864 bytes)
backing file: TEST_DIR/t.IMGFMT.base
image: TEST_DIR/t.IMGFMT.base
file format: IMGFMT
virtual size: 64 MiB (67108864 bytes)
== qemu-img info --backing-chain --image-opts ==
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64 MiB (67108864 bytes)
backing file: TEST_DIR/t.IMGFMT.mid
image: TEST_DIR/t.IMGFMT.mid
file format: IMGFMT
virtual size: 64 MiB (67108864 bytes)
backing file: TEST_DIR/t.IMGFMT.base
image: TEST_DIR/t.IMGFMT.base
file format: IMGFMT
virtual size: 64 MiB (67108864 bytes)
*** done

83
tests/qemu-iotests/280 Executable file
View file

@ -0,0 +1,83 @@
#!/usr/bin/env python
#
# Copyright (C) 2019 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: Kevin Wolf <kwolf@redhat.com>
#
# Test migration to file for taking an external snapshot with VM state.
import iotests
import os
iotests.verify_image_format(supported_fmts=['qcow2'])
iotests.verify_protocol(supported=['file'])
iotests.verify_platform(['linux'])
with iotests.FilePath('base') as base_path , \
iotests.FilePath('top') as top_path, \
iotests.VM() as vm:
iotests.qemu_img_log('create', '-f', iotests.imgfmt, base_path, '64M')
iotests.log('=== Launch VM ===')
vm.add_object('iothread,id=iothread0')
vm.add_blockdev('file,filename=%s,node-name=base-file' % (base_path))
vm.add_blockdev('%s,file=base-file,node-name=base-fmt' % (iotests.imgfmt))
vm.add_device('virtio-blk,drive=base-fmt,iothread=iothread0,id=vda')
vm.launch()
vm.enable_migration_events('VM')
iotests.log('\n=== Migrate to file ===')
vm.qmp_log('migrate', uri='exec:cat > /dev/null')
with iotests.Timeout(3, 'Migration does not complete'):
vm.wait_migration()
iotests.log('\nVM is now stopped:')
iotests.log(vm.qmp('query-migrate')['return']['status'])
vm.qmp_log('query-status')
iotests.log('\n=== Create a snapshot of the disk image ===')
vm.blockdev_create({
'driver': 'file',
'filename': top_path,
'size': 0,
})
vm.qmp_log('blockdev-add', node_name='top-file',
driver='file', filename=top_path,
filters=[iotests.filter_qmp_testfiles])
vm.blockdev_create({
'driver': iotests.imgfmt,
'file': 'top-file',
'size': 1024 * 1024,
})
vm.qmp_log('blockdev-add', node_name='top-fmt',
driver=iotests.imgfmt, file='top-file')
vm.qmp_log('blockdev-snapshot', node='base-fmt', overlay='top-fmt')
iotests.log('\n=== Resume the VM and simulate a write request ===')
vm.qmp_log('cont')
iotests.log(vm.hmp_qemu_io('-d vda/virtio-backend', 'write 4k 4k'))
iotests.log('\n=== Commit it to the backing file ===')
result = vm.qmp_log('block-commit', job_id='job0', auto_dismiss=False,
device='top-fmt', top_node='top-fmt',
filters=[iotests.filter_qmp_testfiles])
if 'return' in result:
vm.run_job('job0')

View file

@ -0,0 +1,50 @@
Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16
=== Launch VM ===
Enabling migration QMP events on VM...
{"return": {}}
=== Migrate to file ===
{"execute": "migrate", "arguments": {"uri": "exec:cat > /dev/null"}}
{"return": {}}
{"data": {"status": "setup"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
{"data": {"status": "active"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
{"data": {"status": "completed"}, "event": "MIGRATION", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
VM is now stopped:
completed
{"execute": "query-status", "arguments": {}}
{"return": {"running": false, "singlestep": false, "status": "postmigrate"}}
=== Create a snapshot of the disk image ===
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-top", "size": 0}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-top", "node-name": "top-file"}}
{"return": {}}
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "qcow2", "file": "top-file", "size": 1048576}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "qcow2", "file": "top-file", "node-name": "top-fmt"}}
{"return": {}}
{"execute": "blockdev-snapshot", "arguments": {"node": "base-fmt", "overlay": "top-fmt"}}
{"return": {}}
=== Resume the VM and simulate a write request ===
{"execute": "cont", "arguments": {}}
{"return": {}}
{"return": ""}
=== Commit it to the backing file ===
{"execute": "block-commit", "arguments": {"auto-dismiss": false, "device": "top-fmt", "job-id": "job0", "top-node": "top-fmt"}}
{"return": {}}
{"execute": "job-complete", "arguments": {"id": "job0"}}
{"return": {}}
{"data": {"device": "job0", "len": 65536, "offset": 65536, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_READY", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
{"data": {"device": "job0", "len": 65536, "offset": 65536, "speed": 0, "type": "commit"}, "event": "BLOCK_JOB_COMPLETED", "timestamp": {"microseconds": "USECS", "seconds": "SECS"}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}

View file

@ -217,7 +217,8 @@ if [ "$IMGOPTSSYNTAX" = "true" ]; then
TEST_IMG="$DRIVER,file.filename=$TEST_DIR/t.$IMGFMT"
elif [ "$IMGPROTO" = "nbd" ]; then
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
TEST_IMG="$DRIVER,file.driver=nbd,file.type=unix,file.path=$SOCKDIR/nbd"
TEST_IMG="$DRIVER,file.driver=nbd,file.type=unix"
TEST_IMG="$TEST_IMG,file.path=$SOCK_DIR/nbd"
elif [ "$IMGPROTO" = "ssh" ]; then
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
TEST_IMG="$DRIVER,file.driver=ssh,file.host=127.0.0.1,file.path=$TEST_IMG_FILE"

View file

@ -286,3 +286,5 @@
272 rw
273 backing quick
277 rw quick
279 rw backing quick
280 rw migration quick

View file

@ -162,6 +162,11 @@ def qemu_io(*args):
sys.stderr.write('qemu-io received signal %i: %s\n' % (-exitcode, ' '.join(args)))
return subp.communicate()[0]
def qemu_io_log(*args):
result = qemu_io(*args)
log(result, filters=[filter_testfiles, filter_qemu_io])
return result
def qemu_io_silent(*args):
'''Run qemu-io and return the exit code, suppressing stdout'''
args = qemu_io_args + list(args)
@ -604,7 +609,7 @@ def run_job(self, job, auto_finalize=True, auto_dismiss=False,
]
error = None
while True:
ev = filter_qmp_event(self.events_wait(events))
ev = filter_qmp_event(self.events_wait(events, timeout=wait))
if ev['event'] != 'JOB_STATUS_CHANGE':
if use_log:
log(ev)
@ -617,6 +622,8 @@ def run_job(self, job, auto_finalize=True, auto_dismiss=False,
error = j['error']
if use_log:
log('Job failed: %s' % (j['error']))
elif status == 'ready':
self.qmp_log('job-complete', id=job)
elif status == 'pending' and not auto_finalize:
if pre_finalize:
pre_finalize()
@ -636,6 +643,22 @@ def run_job(self, job, auto_finalize=True, auto_dismiss=False,
elif status == 'null':
return error
# Returns None on success, and an error string on failure
def blockdev_create(self, options, job_id='job0', filters=None):
if filters is None:
filters = [filter_qmp_testfiles]
result = self.qmp_log('blockdev-create', filters=filters,
job_id=job_id, options=options)
if 'return' in result:
assert result['return'] == {}
job_result = self.run_job(job_id)
else:
job_result = result['error']
log("")
return job_result
def enable_migration_events(self, name):
log('Enabling migration QMP events on %s...' % name)
log(self.qmp('migrate-set-capabilities', capabilities=[