aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block.c26
-rw-r--r--block/blkdebug.c8
-rwxr-xr-xblock/blkreplay.c3
-rw-r--r--block/blkverify.c3
-rw-r--r--block/block-backend.c7
-rw-r--r--block/commit.c5
-rw-r--r--block/crypto.c5
-rw-r--r--block/file-posix.c21
-rw-r--r--block/file-win32.c7
-rw-r--r--block/gluster.c7
-rw-r--r--block/io.c16
-rw-r--r--block/iscsi.c6
-rw-r--r--block/mirror.c2
-rw-r--r--block/nfs.c12
-rw-r--r--block/parallels.c13
-rw-r--r--block/qcow.c6
-rw-r--r--block/qcow2-refcount.c5
-rw-r--r--block/qcow2.c31
-rw-r--r--block/qed.c8
-rw-r--r--block/raw-format.c6
-rw-r--r--block/rbd.c3
-rw-r--r--block/sheepdog.c14
-rw-r--r--block/vdi.c4
-rw-r--r--block/vhdx-log.c2
-rw-r--r--block/vhdx.c25
-rw-r--r--block/vmdk.c13
-rw-r--r--block/vpc.c13
-rw-r--r--blockdev.c21
-rw-r--r--include/block/block.h2
-rw-r--r--include/block/block_int.h8
-rw-r--r--include/sysemu/block-backend.h4
-rw-r--r--migration/savevm.c8
-rw-r--r--qemu-img-cmds.hx8
-rw-r--r--qemu-img.c313
-rw-r--r--qemu-img.texi7
-rw-r--r--qemu-io-cmds.c5
-rw-r--r--qemu-options.hx4
-rwxr-xr-xtests/qemu-iotests/0262
-rw-r--r--tests/qemu-iotests/026.out2
-rw-r--r--tests/qemu-iotests/026.out.nocache2
-rw-r--r--tests/qemu-iotests/028.out2
-rwxr-xr-xtests/qemu-iotests/0514
-rw-r--r--tests/qemu-iotests/051.out109
-rw-r--r--tests/qemu-iotests/051.pc.out135
-rwxr-xr-xtests/qemu-iotests/06612
-rw-r--r--tests/qemu-iotests/066.out12
-rwxr-xr-xtests/qemu-iotests/0684
-rw-r--r--tests/qemu-iotests/068.out6
-rwxr-xr-xtests/qemu-iotests/1096
-rw-r--r--tests/qemu-iotests/109.out20
-rw-r--r--tests/qemu-iotests/122.out4
-rw-r--r--tests/qemu-iotests/130.out4
-rwxr-xr-xtests/qemu-iotests/1422
-rw-r--r--tests/qemu-iotests/142.out10
-rwxr-xr-xtests/qemu-iotests/1453
-rw-r--r--tests/qemu-iotests/145.out2
-rwxr-xr-xtests/qemu-iotests/181119
-rw-r--r--tests/qemu-iotests/181.out38
-rw-r--r--tests/qemu-iotests/common11
-rw-r--r--tests/qemu-iotests/common.config24
-rw-r--r--tests/qemu-iotests/common.filter13
-rw-r--r--tests/qemu-iotests/common.qemu4
-rw-r--r--tests/qemu-iotests/common.rc4
-rw-r--r--tests/qemu-iotests/group1
-rw-r--r--util/qemu-progress.c3
-rw-r--r--vl.c2
66 files changed, 669 insertions, 542 deletions
diff --git a/block.c b/block.c
index 5db266be21..6c6bb3ec7a 100644
--- a/block.c
+++ b/block.c
@@ -1204,7 +1204,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockBackend *file,
filename = qdict_get_try_str(options, "filename");
}
- if (drv->bdrv_needs_filename && !filename) {
+ if (drv->bdrv_needs_filename && (!filename || !filename[0])) {
error_setg(errp, "The '%s' block driver requires a file name",
drv->format_name);
ret = -EINVAL;
@@ -3307,26 +3307,30 @@ exit:
/**
* Truncate file to 'offset' bytes (needed only for file protocols)
*/
-int bdrv_truncate(BdrvChild *child, int64_t offset)
+int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp)
{
BlockDriverState *bs = child->bs;
BlockDriver *drv = bs->drv;
int ret;
- /* FIXME: Some format block drivers use this function instead of implicitly
- * growing their file by writing beyond its end.
- * See bdrv_aligned_pwritev() for an explanation why we currently
- * cannot assert this permission in that case. */
- // assert(child->perm & BLK_PERM_RESIZE);
+ assert(child->perm & BLK_PERM_RESIZE);
- if (!drv)
+ if (!drv) {
+ error_setg(errp, "No medium inserted");
return -ENOMEDIUM;
- if (!drv->bdrv_truncate)
+ }
+ if (!drv->bdrv_truncate) {
+ error_setg(errp, "Image format driver does not support resize");
return -ENOTSUP;
- if (bs->read_only)
+ }
+ if (bs->read_only) {
+ error_setg(errp, "Image is read-only");
return -EACCES;
+ }
+
+ assert(!(bs->open_flags & BDRV_O_INACTIVE));
- ret = drv->bdrv_truncate(bs, offset);
+ ret = drv->bdrv_truncate(bs, offset, errp);
if (ret == 0) {
ret = refresh_total_sectors(bs, offset >> BDRV_SECTOR_BITS);
bdrv_dirty_bitmap_truncate(bs);
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 67e8024e36..d2a7561c4c 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -389,14 +389,12 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
} else if (align) {
error_setg(errp, "Invalid alignment");
ret = -EINVAL;
- goto fail_unref;
+ goto out;
}
ret = 0;
goto out;
-fail_unref:
- bdrv_unref_child(bs, bs->file);
out:
if (ret < 0) {
g_free(s->config_file);
@@ -661,9 +659,9 @@ static int64_t blkdebug_getlength(BlockDriverState *bs)
return bdrv_getlength(bs->file->bs);
}
-static int blkdebug_truncate(BlockDriverState *bs, int64_t offset)
+static int blkdebug_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
{
- return bdrv_truncate(bs->file, offset);
+ return bdrv_truncate(bs->file, offset, errp);
}
static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options)
diff --git a/block/blkreplay.c b/block/blkreplay.c
index e1102119fb..6aa5fd4156 100755
--- a/block/blkreplay.c
+++ b/block/blkreplay.c
@@ -37,9 +37,6 @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags,
ret = 0;
fail:
- if (ret < 0) {
- bdrv_unref_child(bs, bs->file);
- }
return ret;
}
diff --git a/block/blkverify.c b/block/blkverify.c
index 9a1e21c6ad..af23281669 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -142,9 +142,6 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
ret = 0;
fail:
- if (ret < 0) {
- bdrv_unref_child(bs, bs->file);
- }
qemu_opts_del(opts);
return ret;
}
diff --git a/block/block-backend.c b/block/block-backend.c
index 7405024e08..f5bf13eec9 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -420,7 +420,7 @@ void monitor_remove_blk(BlockBackend *blk)
* Return @blk's name, a non-null string.
* Returns an empty string iff @blk is not referenced by the monitor.
*/
-const char *blk_name(BlockBackend *blk)
+const char *blk_name(const BlockBackend *blk)
{
return blk->name ?: "";
}
@@ -1746,13 +1746,14 @@ int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
BDRV_REQ_WRITE_COMPRESSED);
}
-int blk_truncate(BlockBackend *blk, int64_t offset)
+int blk_truncate(BlockBackend *blk, int64_t offset, Error **errp)
{
if (!blk_is_available(blk)) {
+ error_setg(errp, "No medium inserted");
return -ENOMEDIUM;
}
- return bdrv_truncate(blk->root, offset);
+ return bdrv_truncate(blk->root, offset, errp);
}
static void blk_pdiscard_entry(void *opaque)
diff --git a/block/commit.c b/block/commit.c
index 91d2c344f6..76a0d98c6f 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -151,7 +151,7 @@ static void coroutine_fn commit_run(void *opaque)
}
if (base_len < s->common.len) {
- ret = blk_truncate(s->base, s->common.len);
+ ret = blk_truncate(s->base, s->common.len, NULL);
if (ret) {
goto out;
}
@@ -511,8 +511,9 @@ int bdrv_commit(BlockDriverState *bs)
* grow the backing file image if possible. If not possible,
* we must return an error */
if (length > backing_length) {
- ret = blk_truncate(backing, length);
+ ret = blk_truncate(backing, length, &local_err);
if (ret < 0) {
+ error_report_err(local_err);
goto ro_cleanup;
}
}
diff --git a/block/crypto.c b/block/crypto.c
index 34549b28a5..6828180840 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -381,7 +381,8 @@ static int block_crypto_create_generic(QCryptoBlockFormat format,
return ret;
}
-static int block_crypto_truncate(BlockDriverState *bs, int64_t offset)
+static int block_crypto_truncate(BlockDriverState *bs, int64_t offset,
+ Error **errp)
{
BlockCrypto *crypto = bs->opaque;
size_t payload_offset =
@@ -389,7 +390,7 @@ static int block_crypto_truncate(BlockDriverState *bs, int64_t offset)
offset += payload_offset;
- return bdrv_truncate(bs->file, offset);
+ return bdrv_truncate(bs->file, offset, errp);
}
static void block_crypto_close(BlockDriverState *bs)
diff --git a/block/file-posix.c b/block/file-posix.c
index 0c4896876e..1941fb6749 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -25,8 +25,6 @@
#include "qapi/error.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
-#include "qemu/timer.h"
-#include "qemu/log.h"
#include "block/block_int.h"
#include "qemu/module.h"
#include "trace.h"
@@ -1409,24 +1407,31 @@ static void raw_close(BlockDriverState *bs)
}
}
-static int raw_truncate(BlockDriverState *bs, int64_t offset)
+static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
{
BDRVRawState *s = bs->opaque;
struct stat st;
+ int ret;
if (fstat(s->fd, &st)) {
- return -errno;
+ ret = -errno;
+ error_setg_errno(errp, -ret, "Failed to fstat() the file");
+ return ret;
}
if (S_ISREG(st.st_mode)) {
if (ftruncate(s->fd, offset) < 0) {
- return -errno;
+ ret = -errno;
+ error_setg_errno(errp, -ret, "Failed to resize the file");
+ return ret;
}
} else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
- if (offset > raw_getlength(bs)) {
- return -EINVAL;
- }
+ if (offset > raw_getlength(bs)) {
+ error_setg(errp, "Cannot grow device files");
+ return -EINVAL;
+ }
} else {
+ error_setg(errp, "Resizing this file is not supported");
return -ENOTSUP;
}
diff --git a/block/file-win32.c b/block/file-win32.c
index 800fabdd72..7872e00a21 100644
--- a/block/file-win32.c
+++ b/block/file-win32.c
@@ -24,7 +24,6 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
-#include "qemu/timer.h"
#include "block/block_int.h"
#include "qemu/module.h"
#include "block/raw-aio.h"
@@ -461,7 +460,7 @@ static void raw_close(BlockDriverState *bs)
}
}
-static int raw_truncate(BlockDriverState *bs, int64_t offset)
+static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
{
BDRVRawState *s = bs->opaque;
LONG low, high;
@@ -476,11 +475,11 @@ static int raw_truncate(BlockDriverState *bs, int64_t offset)
*/
dwPtrLow = SetFilePointer(s->hfile, low, &high, FILE_BEGIN);
if (dwPtrLow == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) {
- fprintf(stderr, "SetFilePointer error: %lu\n", GetLastError());
+ error_setg_win32(errp, GetLastError(), "SetFilePointer error");
return -EIO;
}
if (SetEndOfFile(s->hfile) == 0) {
- fprintf(stderr, "SetEndOfFile error: %lu\n", GetLastError());
+ error_setg_win32(errp, GetLastError(), "SetEndOfFile error");
return -EIO;
}
return 0;
diff --git a/block/gluster.c b/block/gluster.c
index cf29b5f9a4..1d4e2f7c52 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -1092,14 +1092,17 @@ static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
return acb.ret;
}
-static int qemu_gluster_truncate(BlockDriverState *bs, int64_t offset)
+static int qemu_gluster_truncate(BlockDriverState *bs, int64_t offset,
+ Error **errp)
{
int ret;
BDRVGlusterState *s = bs->opaque;
ret = glfs_ftruncate(s->fd, offset);
if (ret < 0) {
- return -errno;
+ ret = -errno;
+ error_setg_errno(errp, -ret, "Failed to truncate file");
+ return ret;
}
return 0;
diff --git a/block/io.c b/block/io.c
index a7142e00e8..40bd94f323 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1362,16 +1362,8 @@ static int coroutine_fn bdrv_aligned_pwritev(BdrvChild *child,
assert(!waited || !req->serialising);
assert(req->overlap_offset <= offset);
assert(offset + bytes <= req->overlap_offset + req->overlap_bytes);
- /* FIXME: Block migration uses the BlockBackend of the guest device at a
- * point when it has not yet taken write permissions. This will be
- * fixed by a future patch, but for now we have to bypass this
- * assertion for block migration to work. */
- // assert(child->perm & BLK_PERM_WRITE);
- /* FIXME: Because of the above, we also cannot guarantee that all format
- * BDS take the BLK_PERM_RESIZE permission on their file BDS, since
- * they are not obligated to do so if they do not have any parent
- * that has taken the permission to write to them. */
- // assert(end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE);
+ assert(child->perm & BLK_PERM_WRITE);
+ assert(end_sector <= bs->total_sectors || child->perm & BLK_PERM_RESIZE);
ret = notifier_with_return_list_notify(&bs->before_write_notifiers, req);
@@ -1452,7 +1444,7 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvChild *child,
int ret = 0;
head_padding_bytes = offset & (align - 1);
- tail_padding_bytes = align - ((offset + bytes) & (align - 1));
+ tail_padding_bytes = (align - (offset + bytes)) & (align - 1);
assert(flags & BDRV_REQ_ZERO_WRITE);
@@ -2308,7 +2300,7 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
bdrv_inc_in_flight(bs);
- if (!bs || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs) ||
+ if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs) ||
bdrv_is_sg(bs)) {
goto early_exit;
}
diff --git a/block/iscsi.c b/block/iscsi.c
index 42fb0b019c..5daa201181 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -2059,22 +2059,24 @@ static void iscsi_reopen_commit(BDRVReopenState *reopen_state)
}
}
-static int iscsi_truncate(BlockDriverState *bs, int64_t offset)
+static int iscsi_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
{
IscsiLun *iscsilun = bs->opaque;
Error *local_err = NULL;
if (iscsilun->type != TYPE_DISK) {
+ error_setg(errp, "Cannot resize non-disk iSCSI devices");
return -ENOTSUP;
}
iscsi_readcapacity_sync(iscsilun, &local_err);
if (local_err != NULL) {
- error_free(local_err);
+ error_propagate(errp, local_err);
return -EIO;
}
if (offset > iscsi_getlength(bs)) {
+ error_setg(errp, "Cannot grow iSCSI devices");
return -EINVAL;
}
diff --git a/block/mirror.c b/block/mirror.c
index 9f5eb692fd..e86f8f8ad7 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -724,7 +724,7 @@ static void coroutine_fn mirror_run(void *opaque)
}
if (s->bdev_length > base_length) {
- ret = blk_truncate(s->target, s->bdev_length);
+ ret = blk_truncate(s->target, s->bdev_length, NULL);
if (ret < 0) {
goto immediate_exit;
}
diff --git a/block/nfs.c b/block/nfs.c
index 6541dec1fc..76572ae546 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -764,10 +764,18 @@ static int64_t nfs_get_allocated_file_size(BlockDriverState *bs)
return (task.ret < 0 ? task.ret : st.st_blocks * 512);
}
-static int nfs_file_truncate(BlockDriverState *bs, int64_t offset)
+static int nfs_file_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
{
NFSClient *client = bs->opaque;
- return nfs_ftruncate(client->context, client->fh, offset);
+ int ret;
+
+ ret = nfs_ftruncate(client->context, client->fh, offset);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to truncate file");
+ return ret;
+ }
+
+ return 0;
}
/* Note that this will not re-establish a connection with the NFS server
diff --git a/block/parallels.c b/block/parallels.c
index 90acf79687..8be46a7d48 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -223,7 +223,8 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
space << BDRV_SECTOR_BITS, 0);
} else {
ret = bdrv_truncate(bs->file,
- (s->data_end + space) << BDRV_SECTOR_BITS);
+ (s->data_end + space) << BDRV_SECTOR_BITS,
+ NULL);
}
if (ret < 0) {
return ret;
@@ -456,8 +457,10 @@ static int parallels_check(BlockDriverState *bs, BdrvCheckResult *res,
size - res->image_end_offset);
res->leaks += count;
if (fix & BDRV_FIX_LEAKS) {
- ret = bdrv_truncate(bs->file, res->image_end_offset);
+ Error *local_err = NULL;
+ ret = bdrv_truncate(bs->file, res->image_end_offset, &local_err);
if (ret < 0) {
+ error_report_err(local_err);
res->check_errors++;
return ret;
}
@@ -504,7 +507,7 @@ static int parallels_create(const char *filename, QemuOpts *opts, Error **errp)
blk_set_allow_write_beyond_eof(file, true);
- ret = blk_truncate(file, 0);
+ ret = blk_truncate(file, 0, errp);
if (ret < 0) {
goto exit;
}
@@ -696,7 +699,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
}
if (!(flags & BDRV_O_RESIZE) || !bdrv_has_zero_init(bs->file->bs) ||
- bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs)) != 0) {
+ bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs), NULL) != 0) {
s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE;
}
@@ -739,7 +742,7 @@ static void parallels_close(BlockDriverState *bs)
}
if (bs->open_flags & BDRV_O_RDWR) {
- bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS);
+ bdrv_truncate(bs->file, s->data_end << BDRV_SECTOR_BITS, NULL);
}
g_free(s->bat_dirty_bmap);
diff --git a/block/qcow.c b/block/qcow.c
index 9d6ac83959..5d147b962e 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -473,7 +473,7 @@ static uint64_t get_cluster_offset(BlockDriverState *bs,
/* round to cluster size */
cluster_offset = (cluster_offset + s->cluster_size - 1) &
~(s->cluster_size - 1);
- bdrv_truncate(bs->file, cluster_offset + s->cluster_size);
+ bdrv_truncate(bs->file, cluster_offset + s->cluster_size, NULL);
/* if encrypted, we must initialize the cluster
content which won't be written */
if (bs->encrypted &&
@@ -833,7 +833,7 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp)
blk_set_allow_write_beyond_eof(qcow_blk, true);
- ret = blk_truncate(qcow_blk, 0);
+ ret = blk_truncate(qcow_blk, 0, errp);
if (ret < 0) {
goto exit;
}
@@ -916,7 +916,7 @@ static int qcow_make_empty(BlockDriverState *bs)
if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, s->l1_table,
l1_length) < 0)
return -1;
- ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length);
+ ret = bdrv_truncate(bs->file, s->l1_table_offset + l1_length, NULL);
if (ret < 0)
return ret;
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 9e96f64c8b..4efca7ebdb 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1728,14 +1728,17 @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
if (fix & BDRV_FIX_ERRORS) {
int64_t new_nb_clusters;
+ Error *local_err = NULL;
if (offset > INT64_MAX - s->cluster_size) {
ret = -EINVAL;
goto resize_fail;
}
- ret = bdrv_truncate(bs->file, offset + s->cluster_size);
+ ret = bdrv_truncate(bs->file, offset + s->cluster_size,
+ &local_err);
if (ret < 0) {
+ error_report_err(local_err);
goto resize_fail;
}
size = bdrv_getlength(bs->file->bs);
diff --git a/block/qcow2.c b/block/qcow2.c
index 6a92d2ef3f..5c1573c999 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2294,9 +2294,9 @@ static int qcow2_create2(const char *filename, int64_t total_size,
}
/* Okay, now that we have a valid image, let's give it the right size */
- ret = blk_truncate(blk, total_size);
+ ret = blk_truncate(blk, total_size, errp);
if (ret < 0) {
- error_setg_errno(errp, -ret, "Could not resize image");
+ error_prepend(errp, "Could not resize image: ");
goto out;
}
@@ -2515,7 +2515,12 @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,
if (!QEMU_IS_ALIGNED(offset | count, s->cluster_size)) {
assert(count < s->cluster_size);
- return -ENOTSUP;
+ /* Ignore partial clusters, except for the special case of the
+ * complete partial cluster at the end of an unaligned file */
+ if (!QEMU_IS_ALIGNED(offset, s->cluster_size) ||
+ offset + count != bs->total_sectors * BDRV_SECTOR_SIZE) {
+ return -ENOTSUP;
+ }
}
qemu_co_mutex_lock(&s->lock);
@@ -2525,32 +2530,33 @@ static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,
return ret;
}
-static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
+static int qcow2_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
{
BDRVQcow2State *s = bs->opaque;
int64_t new_l1_size;
int ret;
if (offset & 511) {
- error_report("The new size must be a multiple of 512");
+ error_setg(errp, "The new size must be a multiple of 512");
return -EINVAL;
}
/* cannot proceed if image has snapshots */
if (s->nb_snapshots) {
- error_report("Can't resize an image which has snapshots");
+ error_setg(errp, "Can't resize an image which has snapshots");
return -ENOTSUP;
}
/* shrinking is currently not supported */
if (offset < bs->total_sectors * 512) {
- error_report("qcow2 doesn't support shrinking images yet");
+ error_setg(errp, "qcow2 doesn't support shrinking images yet");
return -ENOTSUP;
}
new_l1_size = size_to_l1(s, offset);
ret = qcow2_grow_l1_table(bs, new_l1_size, true);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to grow the L1 table");
return ret;
}
@@ -2559,6 +2565,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, size),
&offset, sizeof(uint64_t));
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to update the image size");
return ret;
}
@@ -2584,7 +2591,7 @@ qcow2_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
/* align end of file to a sector boundary to ease reading with
sector based I/Os */
cluster_offset = bdrv_getlength(bs->file->bs);
- return bdrv_truncate(bs->file, cluster_offset);
+ return bdrv_truncate(bs->file, cluster_offset, NULL);
}
buf = qemu_blockalign(bs, s->cluster_size);
@@ -2674,6 +2681,7 @@ fail:
static int make_completely_empty(BlockDriverState *bs)
{
BDRVQcow2State *s = bs->opaque;
+ Error *local_err = NULL;
int ret, l1_clusters;
int64_t offset;
uint64_t *new_reftable = NULL;
@@ -2798,8 +2806,10 @@ static int make_completely_empty(BlockDriverState *bs)
goto fail;
}
- ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size);
+ ret = bdrv_truncate(bs->file, (3 + l1_clusters) * s->cluster_size,
+ &local_err);
if (ret < 0) {
+ error_report_err(local_err);
goto fail;
}
@@ -3273,9 +3283,10 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
return ret;
}
- ret = blk_truncate(blk, new_size);
+ ret = blk_truncate(blk, new_size, &local_err);
blk_unref(blk);
if (ret < 0) {
+ error_report_err(local_err);
return ret;
}
}
diff --git a/block/qed.c b/block/qed.c
index 5ec7fd83f2..fd76817cbb 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -635,7 +635,7 @@ static int qed_create(const char *filename, uint32_t cluster_size,
blk_set_allow_write_beyond_eof(blk, true);
/* File must start empty and grow, check truncate is supported */
- ret = blk_truncate(blk, 0);
+ ret = blk_truncate(blk, 0, errp);
if (ret < 0) {
goto out;
}
@@ -1518,7 +1518,7 @@ static int coroutine_fn bdrv_qed_co_pwrite_zeroes(BlockDriverState *bs,
return cb.ret;
}
-static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset)
+static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
{
BDRVQEDState *s = bs->opaque;
uint64_t old_image_size;
@@ -1526,11 +1526,12 @@ static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset)
if (!qed_is_image_size_valid(offset, s->header.cluster_size,
s->header.table_size)) {
+ error_setg(errp, "Invalid image size specified");
return -EINVAL;
}
- /* Shrinking is currently not supported */
if ((uint64_t)offset < s->header.image_size) {
+ error_setg(errp, "Shrinking images is currently not supported");
return -ENOTSUP;
}
@@ -1539,6 +1540,7 @@ static int bdrv_qed_truncate(BlockDriverState *bs, int64_t offset)
ret = qed_write_header_sync(s);
if (ret < 0) {
s->header.image_size = old_image_size;
+ error_setg_errno(errp, -ret, "Failed to update the image size");
}
return ret;
}
diff --git a/block/raw-format.c b/block/raw-format.c
index 86fbc657eb..36e65036f0 100644
--- a/block/raw-format.c
+++ b/block/raw-format.c
@@ -327,21 +327,23 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
}
}
-static int raw_truncate(BlockDriverState *bs, int64_t offset)
+static int raw_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
{
BDRVRawState *s = bs->opaque;
if (s->has_size) {
+ error_setg(errp, "Cannot resize fixed-size raw disks");
return -ENOTSUP;
}
if (INT64_MAX - offset < s->offset) {
+ error_setg(errp, "Disk size too large for the chosen offset");
return -EINVAL;
}
s->size = offset;
offset += s->offset;
- return bdrv_truncate(bs->file, offset);
+ return bdrv_truncate(bs->file, offset, errp);
}
static int raw_media_changed(BlockDriverState *bs)
diff --git a/block/rbd.c b/block/rbd.c
index 6471f4fd2b..fbf30591d1 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -916,13 +916,14 @@ static int64_t qemu_rbd_getlength(BlockDriverState *bs)
return info.size;
}
-static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset)
+static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
{
BDRVRBDState *s = bs->opaque;
int r;
r = rbd_resize(s->image, offset);
if (r < 0) {
+ error_setg_errno(errp, -r, "Failed to resize file");
return r;
}
diff --git a/block/sheepdog.c b/block/sheepdog.c
index b2a5998188..fe8fd923d5 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -2159,9 +2159,8 @@ static int64_t sd_getlength(BlockDriverState *bs)
return s->inode.vdi_size;
}
-static int sd_truncate(BlockDriverState *bs, int64_t offset)
+static int sd_truncate(BlockDriverState *bs, int64_t offset, Error **errp)
{
- Error *local_err = NULL;
BDRVSheepdogState *s = bs->opaque;
int ret, fd;
unsigned int datalen;
@@ -2169,16 +2168,15 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
max_vdi_size = (UINT64_C(1) << s->inode.block_size_shift) * MAX_DATA_OBJS;
if (offset < s->inode.vdi_size) {
- error_report("shrinking is not supported");
+ error_setg(errp, "shrinking is not supported");
return -EINVAL;
} else if (offset > max_vdi_size) {
- error_report("too big image size");
+ error_setg(errp, "too big image size");
return -EINVAL;
}
- fd = connect_to_sdog(s, &local_err);
+ fd = connect_to_sdog(s, errp);
if (fd < 0) {
- error_report_err(local_err);
return fd;
}
@@ -2191,7 +2189,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
close(fd);
if (ret < 0) {
- error_report("failed to update an inode.");
+ error_setg_errno(errp, -ret, "failed to update an inode");
}
return ret;
@@ -2456,7 +2454,7 @@ static coroutine_fn int sd_co_writev(BlockDriverState *bs, int64_t sector_num,
BDRVSheepdogState *s = bs->opaque;
if (offset > s->inode.vdi_size) {
- ret = sd_truncate(bs, offset);
+ ret = sd_truncate(bs, offset, NULL);
if (ret < 0) {
return ret;
}
diff --git a/block/vdi.c b/block/vdi.c
index 9b4f70e977..d12d9cdc79 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -832,9 +832,9 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp)
}
if (image_type == VDI_TYPE_STATIC) {
- ret = blk_truncate(blk, offset + blocks * block_size);
+ ret = blk_truncate(blk, offset + blocks * block_size, errp);
if (ret < 0) {
- error_setg(errp, "Failed to statically allocate %s", filename);
+ error_prepend(errp, "Failed to statically allocate %s", filename);
goto exit;
}
}
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
index 67a91c0de5..3f4c2aa095 100644
--- a/block/vhdx-log.c
+++ b/block/vhdx-log.c
@@ -548,7 +548,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
if (new_file_size % (1024*1024)) {
/* round up to nearest 1MB boundary */
new_file_size = ((new_file_size >> 20) + 1) << 20;
- bdrv_truncate(bs->file, new_file_size);
+ bdrv_truncate(bs->file, new_file_size, NULL);
}
}
qemu_vfree(desc_entries);
diff --git a/block/vhdx.c b/block/vhdx.c
index 052a753159..e8fe3fb5e9 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -1171,7 +1171,7 @@ static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
/* per the spec, the address for a block is in units of 1MB */
*new_offset = ROUND_UP(*new_offset, 1024 * 1024);
- return bdrv_truncate(bs->file, *new_offset + s->block_size);
+ return bdrv_truncate(bs->file, *new_offset + s->block_size, NULL);
}
/*
@@ -1586,7 +1586,7 @@ exit:
static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
uint64_t image_size, VHDXImageType type,
bool use_zero_blocks, uint64_t file_offset,
- uint32_t length)
+ uint32_t length, Error **errp)
{
int ret = 0;
uint64_t data_file_offset;
@@ -1607,16 +1607,17 @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
if (type == VHDX_TYPE_DYNAMIC) {
/* All zeroes, so we can just extend the file - the end of the BAT
* is the furthest thing we have written yet */
- ret = blk_truncate(blk, data_file_offset);
+ ret = blk_truncate(blk, data_file_offset, errp);
if (ret < 0) {
goto exit;
}
} else if (type == VHDX_TYPE_FIXED) {
- ret = blk_truncate(blk, data_file_offset + image_size);
+ ret = blk_truncate(blk, data_file_offset + image_size, errp);
if (ret < 0) {
goto exit;
}
} else {
+ error_setg(errp, "Unsupported image type");
ret = -ENOTSUP;
goto exit;
}
@@ -1627,6 +1628,7 @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
/* for a fixed file, the default BAT entry is not zero */
s->bat = g_try_malloc0(length);
if (length && s->bat == NULL) {
+ error_setg(errp, "Failed to allocate memory for the BAT");
ret = -ENOMEM;
goto exit;
}
@@ -1646,6 +1648,7 @@ static int vhdx_create_bat(BlockBackend *blk, BDRVVHDXState *s,
}
ret = blk_pwrite(blk, file_offset, s->bat, length, 0);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to write the BAT");
goto exit;
}
}
@@ -1671,7 +1674,8 @@ static int vhdx_create_new_region_table(BlockBackend *blk,
uint32_t log_size,
bool use_zero_blocks,
VHDXImageType type,
- uint64_t *metadata_offset)
+ uint64_t *metadata_offset,
+ Error **errp)
{
int ret = 0;
uint32_t offset = 0;
@@ -1740,7 +1744,7 @@ static int vhdx_create_new_region_table(BlockBackend *blk,
/* The region table gives us the data we need to create the BAT,
* so do that now */
ret = vhdx_create_bat(blk, s, image_size, type, use_zero_blocks,
- bat_file_offset, bat_length);
+ bat_file_offset, bat_length, errp);
if (ret < 0) {
goto exit;
}
@@ -1749,12 +1753,14 @@ static int vhdx_create_new_region_table(BlockBackend *blk,
ret = blk_pwrite(blk, VHDX_REGION_TABLE_OFFSET, buffer,
VHDX_HEADER_BLOCK_SIZE, 0);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to write first region table");
goto exit;
}
ret = blk_pwrite(blk, VHDX_REGION_TABLE2_OFFSET, buffer,
VHDX_HEADER_BLOCK_SIZE, 0);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to write second region table");
goto exit;
}
@@ -1825,6 +1831,7 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
ret = -ENOTSUP;
goto exit;
} else {
+ error_setg(errp, "Invalid subformat '%s'", type);
ret = -EINVAL;
goto exit;
}
@@ -1879,12 +1886,14 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET, &signature, sizeof(signature),
0);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to write file signature");
goto delete_and_exit;
}
if (creator) {
ret = blk_pwrite(blk, VHDX_FILE_ID_OFFSET + sizeof(signature),
creator, creator_items * sizeof(gunichar2), 0);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to write creator field");
goto delete_and_exit;
}
}
@@ -1893,13 +1902,14 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
/* Creates (B),(C) */
ret = vhdx_create_new_headers(blk, image_size, log_size);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to write image headers");
goto delete_and_exit;
}
/* Creates (D),(E),(G) explicitly. (F) created as by-product */
ret = vhdx_create_new_region_table(blk, image_size, block_size, 512,
log_size, use_zero_blocks, image_type,
- &metadata_offset);
+ &metadata_offset, errp);
if (ret < 0) {
goto delete_and_exit;
}
@@ -1908,6 +1918,7 @@ static int vhdx_create(const char *filename, QemuOpts *opts, Error **errp)
ret = vhdx_create_new_metadata(blk, image_size, block_size, 512,
metadata_offset, image_type);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Failed to initialize metadata");
goto delete_and_exit;
}
diff --git a/block/vmdk.c b/block/vmdk.c
index a9bd22bf93..c61b9cc8e0 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1714,10 +1714,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
blk_set_allow_write_beyond_eof(blk, true);
if (flat) {
- ret = blk_truncate(blk, filesize);
- if (ret < 0) {
- error_setg_errno(errp, -ret, "Could not truncate file");
- }
+ ret = blk_truncate(blk, filesize, errp);
goto exit;
}
magic = cpu_to_be32(VMDK4_MAGIC);
@@ -1780,9 +1777,8 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
goto exit;
}
- ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9);
+ ret = blk_truncate(blk, le64_to_cpu(header.grain_offset) << 9, errp);
if (ret < 0) {
- error_setg_errno(errp, -ret, "Could not truncate file");
goto exit;
}
@@ -2090,10 +2086,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
/* bdrv_pwrite write padding zeros to align to sector, we don't need that
* for description file */
if (desc_offset == 0) {
- ret = blk_truncate(new_blk, desc_len);
- if (ret < 0) {
- error_setg_errno(errp, -ret, "Could not truncate file");
- }
+ ret = blk_truncate(new_blk, desc_len, errp);
}
exit:
if (new_blk) {
diff --git a/block/vpc.c b/block/vpc.c
index f591d4be38..ecfee77149 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -851,20 +851,21 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
}
static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
- int64_t total_size)
+ int64_t total_size, Error **errp)
{
int ret;
/* Add footer to total size */
total_size += HEADER_SIZE;
- ret = blk_truncate(blk, total_size);
+ ret = blk_truncate(blk, total_size, errp);
if (ret < 0) {
return ret;
}
ret = blk_pwrite(blk, total_size - HEADER_SIZE, buf, HEADER_SIZE, 0);
if (ret < 0) {
+ error_setg_errno(errp, -ret, "Unable to write VHD header");
return ret;
}
@@ -996,11 +997,11 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
if (disk_type == VHD_DYNAMIC) {
ret = create_dynamic_disk(blk, buf, total_sectors);
+ if (ret < 0) {
+ error_setg(errp, "Unable to create or write VHD header");
+ }
} else {
- ret = create_fixed_disk(blk, buf, total_size);
- }
- if (ret < 0) {
- error_setg(errp, "Unable to create or write VHD header");
+ ret = create_fixed_disk(blk, buf, total_size, errp);
}
out:
diff --git a/blockdev.c b/blockdev.c
index 64282065d8..4d8cdedd54 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2930,26 +2930,7 @@ void qmp_block_resize(bool has_device, const char *device,
/* complete all in-flight operations before resizing the device */
bdrv_drain_all();
- ret = blk_truncate(blk, size);
- switch (ret) {
- case 0:
- break;
- case -ENOMEDIUM:
- error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
- break;
- case -ENOTSUP:
- error_setg(errp, QERR_UNSUPPORTED);
- break;
- case -EACCES:
- error_setg(errp, "Device '%s' is read only", device);
- break;
- case -EBUSY:
- error_setg(errp, QERR_DEVICE_IN_USE, device);
- break;
- default:
- error_setg_errno(errp, -ret, "Could not resize");
- break;
- }
+ ret = blk_truncate(blk, size, errp);
out:
blk_unref(blk);
diff --git a/include/block/block.h b/include/block/block.h
index 144df0ddfb..862eb56fc7 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -294,7 +294,7 @@ 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);
+int bdrv_truncate(BdrvChild *child, int64_t offset, Error **errp);
int64_t bdrv_nb_sectors(BlockDriverState *bs);
int64_t bdrv_getlength(BlockDriverState *bs);
int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 4f8cd29ae4..87739405d5 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -196,7 +196,7 @@ struct BlockDriver {
int coroutine_fn (*bdrv_co_flush_to_os)(BlockDriverState *bs);
const char *protocol_name;
- int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset);
+ int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset, Error **errp);
int64_t (*bdrv_getlength)(BlockDriverState *bs);
bool has_variable_length;
@@ -252,7 +252,7 @@ struct BlockDriver {
* Returns 0 for completed check, -errno for internal errors.
* The check results are stored in result.
*/
- int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result,
+ int (*bdrv_check)(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix);
int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts,
@@ -454,13 +454,13 @@ struct BdrvChildRole {
/* Returns a name that is supposedly more useful for human users than the
* node name for identifying the node in question (in particular, a BB
* name), or NULL if the parent can't provide a better name. */
- const char* (*get_name)(BdrvChild *child);
+ const char *(*get_name)(BdrvChild *child);
/* Returns a malloced string that describes the parent of the child for a
* human reader. This could be a node-name, BlockBackend name, qdev ID or
* QOM path of the device owning the BlockBackend, job type and ID etc. The
* caller is responsible for freeing the memory. */
- char* (*get_parent_desc)(BdrvChild *child);
+ char *(*get_parent_desc)(BdrvChild *child);
/*
* If this pair of functions is implemented, the parent doesn't issue new
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 7462228ac1..840ad6134c 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -99,7 +99,7 @@ int blk_get_refcnt(BlockBackend *blk);
void blk_ref(BlockBackend *blk);
void blk_unref(BlockBackend *blk);
void blk_remove_all_bs(void);
-const char *blk_name(BlockBackend *blk);
+const char *blk_name(const BlockBackend *blk);
BlockBackend *blk_by_name(const char *name);
BlockBackend *blk_next(BlockBackend *blk);
bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp);
@@ -225,7 +225,7 @@ int coroutine_fn blk_co_pwrite_zeroes(BlockBackend *blk, int64_t offset,
int count, BdrvRequestFlags flags);
int blk_pwrite_compressed(BlockBackend *blk, int64_t offset, const void *buf,
int count);
-int blk_truncate(BlockBackend *blk, int64_t offset);
+int blk_truncate(BlockBackend *blk, int64_t offset, Error **errp);
int blk_pdiscard(BlockBackend *blk, int64_t offset, int count);
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
int64_t pos, int size);
diff --git a/migration/savevm.c b/migration/savevm.c
index 03ae1bdeb4..a00c1ab0af 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -1622,6 +1622,14 @@ static void loadvm_postcopy_handle_run_bh(void *opaque)
error_report_err(local_err);
}
+ /* If we get an error here, just don't restart the VM yet. */
+ blk_resume_after_migration(&local_err);
+ if (local_err) {
+ error_free(local_err);
+ local_err = NULL;
+ autostart = false;
+ }
+
trace_loadvm_postcopy_handle_run_cpu_sync();
cpu_synchronize_all_post_init();
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 8ac78222af..bf4ce59019 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -22,9 +22,9 @@ STEXI
ETEXI
DEF("create", img_create,
- "create [-q] [--object objectdef] [-f fmt] [-o options] filename [size]")
+ "create [-q] [--object objectdef] [-f fmt] [-b backing_file] [-F backing_fmt] [-o options] filename [size]")
STEXI
-@item create [--object @var{objectdef}] [-q] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}]
+@item create [--object @var{objectdef}] [-q] [-f @var{fmt}] [-b @var{backing_file}] [-F @var{backing_fmt}] [-o @var{options}] @var{filename} [@var{size}]
ETEXI
DEF("commit", img_commit,
@@ -40,9 +40,9 @@ STEXI
ETEXI
DEF("convert", img_convert,
- "convert [--object objectdef] [--image-opts] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename")
+ "convert [--object objectdef] [--image-opts] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename")
STEXI
-@item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename}
+@item convert [--object @var{objectdef}] [--image-opts] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename}
ETEXI
DEF("dd", img_dd,
diff --git a/qemu-img.c b/qemu-img.c
index bbe15741f1..c7196362df 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1522,7 +1522,7 @@ typedef struct ImgConvertState {
int min_sparse;
size_t cluster_sectors;
size_t buf_sectors;
- int num_coroutines;
+ long num_coroutines;
int running_coroutines;
Coroutine *co[MAX_COROUTINES];
int64_t wait_sector_num[MAX_COROUTINES];
@@ -1554,9 +1554,15 @@ static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num)
if (s->sector_next_status <= sector_num) {
BlockDriverState *file;
- ret = bdrv_get_block_status(blk_bs(s->src[src_cur]),
- sector_num - src_cur_offset,
- n, &n, &file);
+ if (s->target_has_backing) {
+ ret = bdrv_get_block_status(blk_bs(s->src[src_cur]),
+ sector_num - src_cur_offset,
+ n, &n, &file);
+ } else {
+ ret = bdrv_get_block_status_above(blk_bs(s->src[src_cur]), NULL,
+ sector_num - src_cur_offset,
+ n, &n, &file);
+ }
if (ret < 0) {
return ret;
}
@@ -1565,26 +1571,8 @@ static int convert_iteration_sectors(ImgConvertState *s, int64_t sector_num)
s->status = BLK_ZERO;
} else if (ret & BDRV_BLOCK_DATA) {
s->status = BLK_DATA;
- } else if (!s->target_has_backing) {
- /* Without a target backing file we must copy over the contents of
- * the backing file as well. */
- /* Check block status of the backing file chain to avoid
- * needlessly reading zeroes and limiting the iteration to the
- * buffer size */
- ret = bdrv_get_block_status_above(blk_bs(s->src[src_cur]), NULL,
- sector_num - src_cur_offset,
- n, &n, &file);
- if (ret < 0) {
- return ret;
- }
-
- if (ret & BDRV_BLOCK_ZERO) {
- s->status = BLK_ZERO;
- } else {
- s->status = BLK_DATA;
- }
} else {
- s->status = BLK_BACKING_FILE;
+ s->status = s->target_has_backing ? BLK_BACKING_FILE : BLK_DATA;
}
s->sector_next_status = sector_num + n;
@@ -1661,6 +1649,8 @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num,
while (nb_sectors > 0) {
int n = nb_sectors;
+ BdrvRequestFlags flags = s->compressed ? BDRV_REQ_WRITE_COMPRESSED : 0;
+
switch (status) {
case BLK_BACKING_FILE:
/* If we have a backing file, leave clusters unallocated that are
@@ -1670,43 +1660,24 @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num,
break;
case BLK_DATA:
- /* We must always write compressed clusters as a whole, so don't
- * try to find zeroed parts in the buffer. We can only save the
- * write if the buffer is completely zeroed and we're allowed to
- * keep the target sparse. */
- if (s->compressed) {
- if (s->has_zero_init && s->min_sparse &&
- buffer_is_zero(buf, n * BDRV_SECTOR_SIZE))
- {
- assert(!s->target_has_backing);
- break;
- }
-
- iov.iov_base = buf;
- iov.iov_len = n << BDRV_SECTOR_BITS;
- qemu_iovec_init_external(&qiov, &iov, 1);
-
- ret = blk_co_pwritev(s->target, sector_num << BDRV_SECTOR_BITS,
- n << BDRV_SECTOR_BITS, &qiov,
- BDRV_REQ_WRITE_COMPRESSED);
- if (ret < 0) {
- return ret;
- }
- break;
- }
-
- /* If there is real non-zero data or we're told to keep the target
- * fully allocated (-S 0), we must write it. Otherwise we can treat
- * it as zero sectors. */
+ /* If we're told to keep the target fully allocated (-S 0) or there
+ * is real non-zero data, we must write it. Otherwise we can treat
+ * it as zero sectors.
+ * Compressed clusters need to be written as a whole, so in that
+ * case we can only save the write if the buffer is completely
+ * zeroed. */
if (!s->min_sparse ||
- is_allocated_sectors_min(buf, n, &n, s->min_sparse))
+ (!s->compressed &&
+ is_allocated_sectors_min(buf, n, &n, s->min_sparse)) ||
+ (s->compressed &&
+ !buffer_is_zero(buf, n * BDRV_SECTOR_SIZE)))
{
iov.iov_base = buf;
iov.iov_len = n << BDRV_SECTOR_BITS;
qemu_iovec_init_external(&qiov, &iov, 1);
ret = blk_co_pwritev(s->target, sector_num << BDRV_SECTOR_BITS,
- n << BDRV_SECTOR_BITS, &qiov, 0);
+ n << BDRV_SECTOR_BITS, &qiov, flags);
if (ret < 0) {
return ret;
}
@@ -1716,6 +1687,7 @@ static int coroutine_fn convert_co_write(ImgConvertState *s, int64_t sector_num,
case BLK_ZERO:
if (s->has_zero_init) {
+ assert(!s->target_has_backing);
break;
}
ret = blk_co_pwrite_zeroes(s->target,
@@ -1916,39 +1888,29 @@ static int convert_do_copy(ImgConvertState *s)
static int img_convert(int argc, char **argv)
{
- int c, bs_n, bs_i, compress, cluster_sectors, skip_create;
- int64_t ret = 0;
- int progress = 0, flags, src_flags;
- bool writethrough, src_writethrough;
- const char *fmt, *out_fmt, *cache, *src_cache, *out_baseimg, *out_filename;
+ int c, bs_i, flags, src_flags = 0;
+ const char *fmt = NULL, *out_fmt = "raw", *cache = "unsafe",
+ *src_cache = BDRV_DEFAULT_CACHE, *out_baseimg = NULL,
+ *out_filename, *out_baseimg_param, *snapshot_name = NULL;
BlockDriver *drv, *proto_drv;
- BlockBackend **blk = NULL, *out_blk = NULL;
- BlockDriverState **bs = NULL, *out_bs = NULL;
- int64_t total_sectors;
- int64_t *bs_sectors = NULL;
- size_t bufsectors = IO_BUF_SIZE / BDRV_SECTOR_SIZE;
BlockDriverInfo bdi;
- QemuOpts *opts = NULL;
+ BlockDriverState *out_bs;
+ QemuOpts *opts = NULL, *sn_opts = NULL;
QemuOptsList *create_opts = NULL;
- const char *out_baseimg_param;
char *options = NULL;
- const char *snapshot_name = NULL;
- int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */
- bool quiet = false;
Error *local_err = NULL;
- QemuOpts *sn_opts = NULL;
- ImgConvertState state;
- bool image_opts = false;
- bool wr_in_order = true;
- long num_coroutines = 8;
+ bool writethrough, src_writethrough, quiet = false, image_opts = false,
+ skip_create = false, progress = false;
+ int64_t ret = -EINVAL;
+
+ ImgConvertState s = (ImgConvertState) {
+ /* Need at least 4k of zeros for sparse detection */
+ .min_sparse = 8,
+ .buf_sectors = IO_BUF_SIZE / BDRV_SECTOR_SIZE,
+ .wr_in_order = true,
+ .num_coroutines = 8,
+ };
- fmt = NULL;
- out_fmt = "raw";
- cache = "unsafe";
- src_cache = BDRV_DEFAULT_CACHE;
- out_baseimg = NULL;
- compress = 0;
- skip_create = 0;
for(;;) {
static const struct option long_options[] = {
{"help", no_argument, 0, 'h'},
@@ -1981,22 +1943,19 @@ static int img_convert(int argc, char **argv)
out_baseimg = optarg;
break;
case 'c':
- compress = 1;
+ s.compressed = true;
break;
case 'e':
error_report("option -e is deprecated, please use \'-o "
"encryption\' instead!");
- ret = -1;
goto fail_getopt;
case '6':
error_report("option -6 is deprecated, please use \'-o "
"compat6\' instead!");
- ret = -1;
goto fail_getopt;
case 'o':
if (!is_valid_option_list(optarg)) {
error_report("Invalid option list: %s", optarg);
- ret = -1;
goto fail_getopt;
}
if (!options) {
@@ -2017,7 +1976,6 @@ static int img_convert(int argc, char **argv)
if (!sn_opts) {
error_report("Failed in parsing snapshot param '%s'",
optarg);
- ret = -1;
goto fail_getopt;
}
} else {
@@ -2031,15 +1989,14 @@ static int img_convert(int argc, char **argv)
sval = cvtnum(optarg);
if (sval < 0) {
error_report("Invalid minimum zero buffer size for sparse output specified");
- ret = -1;
goto fail_getopt;
}
- min_sparse = sval / BDRV_SECTOR_SIZE;
+ s.min_sparse = sval / BDRV_SECTOR_SIZE;
break;
}
case 'p':
- progress = 1;
+ progress = true;
break;
case 't':
cache = optarg;
@@ -2051,27 +2008,28 @@ static int img_convert(int argc, char **argv)
quiet = true;
break;
case 'n':
- skip_create = 1;
+ skip_create = true;
break;
case 'm':
- if (qemu_strtol(optarg, NULL, 0, &num_coroutines) ||
- num_coroutines < 1 || num_coroutines > MAX_COROUTINES) {
+ if (qemu_strtol(optarg, NULL, 0, &s.num_coroutines) ||
+ s.num_coroutines < 1 || s.num_coroutines > MAX_COROUTINES) {
error_report("Invalid number of coroutines. Allowed number of"
" coroutines is between 1 and %d", MAX_COROUTINES);
- ret = -1;
goto fail_getopt;
}
break;
case 'W':
- wr_in_order = false;
+ s.wr_in_order = false;
break;
- case OPTION_OBJECT:
- opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!opts) {
+ case OPTION_OBJECT: {
+ QemuOpts *object_opts;
+ object_opts = qemu_opts_parse_noisily(&qemu_object_opts,
+ optarg, true);
+ if (!object_opts) {
goto fail_getopt;
}
break;
+ }
case OPTION_IMAGE_OPTS:
image_opts = true;
break;
@@ -2084,83 +2042,73 @@ static int img_convert(int argc, char **argv)
goto fail_getopt;
}
- if (!wr_in_order && compress) {
+ if (!s.wr_in_order && s.compressed) {
error_report("Out of order write and compress are mutually exclusive");
- ret = -1;
goto fail_getopt;
}
- /* Initialize before goto out */
- if (quiet) {
- progress = 0;
- }
- qemu_progress_init(progress, 1.0);
-
- bs_n = argc - optind - 1;
- out_filename = bs_n >= 1 ? argv[argc - 1] : NULL;
+ s.src_num = argc - optind - 1;
+ out_filename = s.src_num >= 1 ? argv[argc - 1] : NULL;
if (options && has_help_option(options)) {
ret = print_block_option_help(out_filename, out_fmt);
- goto out;
+ goto fail_getopt;
}
- if (bs_n < 1) {
- error_exit("Must specify image file name");
+ if (s.src_num < 1) {
+ error_report("Must specify image file name");
+ goto fail_getopt;
}
- if (bs_n > 1 && out_baseimg) {
- error_report("-B makes no sense when concatenating multiple input "
- "images");
- ret = -1;
- goto out;
- }
-
- src_flags = 0;
+ /* ret is still -EINVAL until here */
ret = bdrv_parse_cache_mode(src_cache, &src_flags, &src_writethrough);
if (ret < 0) {
error_report("Invalid source cache option: %s", src_cache);
- goto out;
+ goto fail_getopt;
}
+ /* Initialize before goto out */
+ if (quiet) {
+ progress = false;
+ }
+ qemu_progress_init(progress, 1.0);
qemu_progress_print(0, 100);
- blk = g_new0(BlockBackend *, bs_n);
- bs = g_new0(BlockDriverState *, bs_n);
- bs_sectors = g_new(int64_t, bs_n);
+ s.src = g_new0(BlockBackend *, s.src_num);
+ s.src_sectors = g_new(int64_t, s.src_num);
- total_sectors = 0;
- for (bs_i = 0; bs_i < bs_n; bs_i++) {
- blk[bs_i] = img_open(image_opts, argv[optind + bs_i],
- fmt, src_flags, src_writethrough, quiet);
- if (!blk[bs_i]) {
+ for (bs_i = 0; bs_i < s.src_num; bs_i++) {
+ s.src[bs_i] = img_open(image_opts, argv[optind + bs_i],
+ fmt, src_flags, src_writethrough, quiet);
+ if (!s.src[bs_i]) {
ret = -1;
goto out;
}
- bs[bs_i] = blk_bs(blk[bs_i]);
- bs_sectors[bs_i] = blk_nb_sectors(blk[bs_i]);
- if (bs_sectors[bs_i] < 0) {
+ s.src_sectors[bs_i] = blk_nb_sectors(s.src[bs_i]);
+ if (s.src_sectors[bs_i] < 0) {
error_report("Could not get size of %s: %s",
- argv[optind + bs_i], strerror(-bs_sectors[bs_i]));
+ argv[optind + bs_i], strerror(-s.src_sectors[bs_i]));
ret = -1;
goto out;
}
- total_sectors += bs_sectors[bs_i];
+ s.total_sectors += s.src_sectors[bs_i];
}
if (sn_opts) {
- bdrv_snapshot_load_tmp(bs[0],
+ bdrv_snapshot_load_tmp(blk_bs(s.src[0]),
qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID),
qemu_opt_get(sn_opts, SNAPSHOT_OPT_NAME),
&local_err);
} else if (snapshot_name != NULL) {
- if (bs_n > 1) {
+ if (s.src_num > 1) {
error_report("No support for concatenating multiple snapshot");
ret = -1;
goto out;
}
- bdrv_snapshot_load_tmp_by_id_or_name(bs[0], snapshot_name, &local_err);
+ bdrv_snapshot_load_tmp_by_id_or_name(blk_bs(s.src[0]), snapshot_name,
+ &local_err);
}
if (local_err) {
error_reportf_err(local_err, "Failed to load snapshot: ");
@@ -2211,7 +2159,7 @@ static int img_convert(int argc, char **argv)
}
}
- qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_sectors * 512,
+ qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s.total_sectors * 512,
&error_abort);
ret = add_old_style_options(out_fmt, opts, out_baseimg, NULL);
if (ret < 0) {
@@ -2224,9 +2172,17 @@ static int img_convert(int argc, char **argv)
if (out_baseimg_param) {
out_baseimg = out_baseimg_param;
}
+ s.target_has_backing = (bool) out_baseimg;
+
+ if (s.src_num > 1 && out_baseimg) {
+ error_report("Having a backing file for the target makes no sense when "
+ "concatenating multiple input images");
+ ret = -1;
+ goto out;
+ }
/* Check if compression is supported */
- if (compress) {
+ if (s.compressed) {
bool encryption =
qemu_opt_get_bool(opts, BLOCK_OPT_ENCRYPT, false);
const char *preallocation =
@@ -2265,7 +2221,7 @@ static int img_convert(int argc, char **argv)
}
}
- flags = min_sparse ? (BDRV_O_RDWR | BDRV_O_UNMAP) : BDRV_O_RDWR;
+ flags = s.min_sparse ? (BDRV_O_RDWR | BDRV_O_UNMAP) : BDRV_O_RDWR;
ret = bdrv_parse_cache_mode(cache, &flags, &writethrough);
if (ret < 0) {
error_report("Invalid cache option: %s", cache);
@@ -2277,64 +2233,48 @@ static int img_convert(int argc, char **argv)
* the bdrv_create() call which takes different params.
* Not critical right now, so fix can wait...
*/
- out_blk = img_open_file(out_filename, out_fmt, flags, writethrough, quiet);
- if (!out_blk) {
+ s.target = img_open_file(out_filename, out_fmt, flags, writethrough, quiet);
+ if (!s.target) {
ret = -1;
goto out;
}
- out_bs = blk_bs(out_blk);
+ out_bs = blk_bs(s.target);
/* increase bufsectors from the default 4096 (2M) if opt_transfer
* or discard_alignment of the out_bs is greater. Limit to 32768 (16MB)
* as maximum. */
- bufsectors = MIN(32768,
- MAX(bufsectors,
- MAX(out_bs->bl.opt_transfer >> BDRV_SECTOR_BITS,
- out_bs->bl.pdiscard_alignment >>
- BDRV_SECTOR_BITS)));
+ s.buf_sectors = MIN(32768,
+ MAX(s.buf_sectors,
+ MAX(out_bs->bl.opt_transfer >> BDRV_SECTOR_BITS,
+ out_bs->bl.pdiscard_alignment >>
+ BDRV_SECTOR_BITS)));
if (skip_create) {
- int64_t output_sectors = blk_nb_sectors(out_blk);
+ int64_t output_sectors = blk_nb_sectors(s.target);
if (output_sectors < 0) {
error_report("unable to get output image length: %s",
strerror(-output_sectors));
ret = -1;
goto out;
- } else if (output_sectors < total_sectors) {
+ } else if (output_sectors < s.total_sectors) {
error_report("output file is smaller than input file");
ret = -1;
goto out;
}
}
- cluster_sectors = 0;
ret = bdrv_get_info(out_bs, &bdi);
if (ret < 0) {
- if (compress) {
+ if (s.compressed) {
error_report("could not get block driver info");
goto out;
}
} else {
- compress = compress || bdi.needs_compressed_writes;
- cluster_sectors = bdi.cluster_size / BDRV_SECTOR_SIZE;
- }
-
- state = (ImgConvertState) {
- .src = blk,
- .src_sectors = bs_sectors,
- .src_num = bs_n,
- .total_sectors = total_sectors,
- .target = out_blk,
- .compressed = compress,
- .target_has_backing = (bool) out_baseimg,
- .min_sparse = min_sparse,
- .cluster_sectors = cluster_sectors,
- .buf_sectors = bufsectors,
- .wr_in_order = wr_in_order,
- .num_coroutines = num_coroutines,
- };
- ret = convert_do_copy(&state);
+ s.compressed = s.compressed || bdi.needs_compressed_writes;
+ s.cluster_sectors = bdi.cluster_size / BDRV_SECTOR_SIZE;
+ }
+ ret = convert_do_copy(&s);
out:
if (!ret) {
qemu_progress_print(100, 0);
@@ -2343,22 +2283,18 @@ out:
qemu_opts_del(opts);
qemu_opts_free(create_opts);
qemu_opts_del(sn_opts);
- blk_unref(out_blk);
- g_free(bs);
- if (blk) {
- for (bs_i = 0; bs_i < bs_n; bs_i++) {
- blk_unref(blk[bs_i]);
+ blk_unref(s.target);
+ if (s.src) {
+ for (bs_i = 0; bs_i < s.src_num; bs_i++) {
+ blk_unref(s.src[bs_i]);
}
- g_free(blk);
+ g_free(s.src);
}
- g_free(bs_sectors);
+ g_free(s.src_sectors);
fail_getopt:
g_free(options);
- if (ret) {
- return 1;
- }
- return 0;
+ return !!ret;
}
@@ -3500,20 +3436,11 @@ static int img_resize(int argc, char **argv)
goto out;
}
- ret = blk_truncate(blk, total_size);
- switch (ret) {
- case 0:
+ ret = blk_truncate(blk, total_size, &err);
+ if (!ret) {
qprintf(quiet, "Image resized.\n");
- break;
- case -ENOTSUP:
- error_report("This image does not support resize");
- break;
- case -EACCES:
- error_report("Image is read-only");
- break;
- default:
- error_report("Error resizing image: %s", strerror(-ret));
- break;
+ } else {
+ error_report_err(err);
}
out:
blk_unref(blk);
diff --git a/qemu-img.texi b/qemu-img.texi
index c81db3e81c..50a2364e80 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -84,7 +84,8 @@ with or without a command shows help and lists the supported formats
@item -p
display progress bar (compare, convert and rebase commands only).
If the @var{-p} option is not used for a command that supports it, the
-progress is reported when the process receives a @code{SIGUSR1} signal.
+progress is reported when the process receives a @code{SIGUSR1} or
+@code{SIGINFO} signal.
@item -q
Quiet mode - do not print any output (except errors). There's no progress bar
in case both @var{-q} and @var{-p} options are used.
@@ -224,7 +225,7 @@ If @code{-r} is specified, exit codes representing the image state refer to the
state after (the attempt at) repairing it. That is, a successful @code{-r all}
will yield the exit code 0, independently of the image state before.
-@item create [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}]
+@item create [-f @var{fmt}] [-b @var{backing_file}] [-F @var{backing_fmt}] [-o @var{options}] @var{filename} [@var{size}]
Create the new disk image @var{filename} of size @var{size} and format
@var{fmt}. Depending on the file format, you can add one or more @var{options}
@@ -302,7 +303,7 @@ Error on reading data
@end table
-@item convert [-c] [-p] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-m @var{num_coroutines}] [-W] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+@item convert [-c] [-p] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-m @var{num_coroutines}] [-W] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
Convert the disk image @var{filename} or a snapshot @var{snapshot_param}(@var{snapshot_id_or_name} is deprecated)
to disk image @var{output_filename} using format @var{output_fmt}. It can be optionally compressed (@code{-c}
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 312fc6d157..21af9e65b2 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -1567,6 +1567,7 @@ static const cmdinfo_t flush_cmd = {
static int truncate_f(BlockBackend *blk, int argc, char **argv)
{
+ Error *local_err = NULL;
int64_t offset;
int ret;
@@ -1576,9 +1577,9 @@ static int truncate_f(BlockBackend *blk, int argc, char **argv)
return 0;
}
- ret = blk_truncate(blk, offset);
+ ret = blk_truncate(blk, offset, &local_err);
if (ret < 0) {
- printf("truncate: %s\n", strerror(-ret));
+ error_report_err(local_err);
return 0;
}
diff --git a/qemu-options.hx b/qemu-options.hx
index 787b9c38da..f68829f3b0 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -803,8 +803,8 @@ STEXI
Force hard disk 0 physical geometry (1 <= @var{c} <= 16383, 1 <=
@var{h} <= 16, 1 <= @var{s} <= 63) and optionally force the BIOS
translation mode (@var{t}=none, lba or auto). Usually QEMU can guess
-all those parameters. This option is useful for old MS-DOS disk
-images.
+all those parameters. This option is deprecated, please use
+@code{-device ide-hd,cyls=c,heads=h,secs=s,...} instead.
ETEXI
DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
diff --git a/tests/qemu-iotests/026 b/tests/qemu-iotests/026
index f5a7f02b25..7fadfbace5 100755
--- a/tests/qemu-iotests/026
+++ b/tests/qemu-iotests/026
@@ -119,7 +119,7 @@ done
echo
-echo === Refcout table growth tests ===
+echo === Refcount table growth tests ===
echo
CLUSTER_SIZE=512
diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out
index 59b8f74cd4..86a50a2e13 100644
--- a/tests/qemu-iotests/026.out
+++ b/tests/qemu-iotests/026.out
@@ -462,7 +462,7 @@ Event: cluster_alloc; errno: 28; imm: off; once: off; write -b
write failed: No space left on device
No errors were found on the image.
-=== Refcout table growth tests ===
+=== Refcount table growth tests ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
diff --git a/tests/qemu-iotests/026.out.nocache b/tests/qemu-iotests/026.out.nocache
index b4aeebcc61..ea2e166a4e 100644
--- a/tests/qemu-iotests/026.out.nocache
+++ b/tests/qemu-iotests/026.out.nocache
@@ -470,7 +470,7 @@ Event: cluster_alloc; errno: 28; imm: off; once: off; write -b
write failed: No space left on device
No errors were found on the image.
-=== Refcout table growth tests ===
+=== Refcount table growth tests ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
diff --git a/tests/qemu-iotests/028.out b/tests/qemu-iotests/028.out
index acd2870bae..7d54aeb003 100644
--- a/tests/qemu-iotests/028.out
+++ b/tests/qemu-iotests/028.out
@@ -469,7 +469,7 @@ No errors were found on the image.
block-backup
Formatting 'TEST_DIR/t.IMGFMT.copy', fmt=IMGFMT size=4294968832 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block-info block-jinfo block-joinfo block-jobinfo block-jobs
+(qemu) info block-jobs
No active jobs
=== IO: pattern 195
read 512/512 bytes at offset 3221194240
diff --git a/tests/qemu-iotests/051 b/tests/qemu-iotests/051
index 630cb7a114..26c29deb51 100755
--- a/tests/qemu-iotests/051
+++ b/tests/qemu-iotests/051
@@ -60,7 +60,8 @@ function do_run_qemu()
function run_qemu()
{
- do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_generated_node_ids
+ do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu |
+ _filter_generated_node_ids | _filter_hmp
}
size=128M
@@ -231,6 +232,7 @@ echo === Leaving out required options ===
echo
run_qemu -drive driver=file
+run_qemu -drive driver=file,filename=
run_qemu -drive driver=nbd
run_qemu -drive driver=raw
run_qemu -drive file.driver=file
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index 7524c62025..4d3b1ff316 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -58,12 +58,12 @@ QEMU X.Y.Z monitor - type 'help' for more information
Testing: -drive file=TEST_DIR/t.qcow2,driver=qcow2,backing.file.filename=TEST_DIR/t.qcow2.orig,if=none,id=drive0 -nodefaults
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
+(qemu) info block
drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
Removable device: not locked, tray closed
Cache mode: writeback
Backing file: TEST_DIR/t.qcow2.orig (chain depth: 1)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,driver=raw,backing.file.filename=TEST_DIR/t.qcow2.orig
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=raw,backing.file.filename=TEST_DIR/t.qcow2.orig: Driver doesn't support backing files
@@ -79,11 +79,11 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.backing.driver=qcow2,file.backing.f
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=: Parameter 'lazy-refcounts' expects 'on' or 'off'
@@ -103,7 +103,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on: Lazy ref
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
=== No medium ===
@@ -117,93 +117,93 @@ QEMU X.Y.Z monitor - type 'help' for more information
Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
=== Cache modes ===
Testing: -drive driver=null-co,cache=none
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive driver=null-co,cache=directsync
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive driver=null-co,cache=writeback
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive driver=null-co,cache=writethrough
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive driver=null-co,cache=unsafe
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive driver=null-co,cache=invalid_value
QEMU_PROG: -drive driver=null-co,cache=invalid_value: invalid cache option
Testing: -drive file=TEST_DIR/t.qcow2,cache=writeback,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
+(qemu) info block
drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
Removable device: not locked, tray closed
Cache mode: writeback
Backing file: TEST_DIR/t.qcow2.base (chain depth: 1)
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block finfo block fiinfo block filinfo block file
+(qemu) info block file
file: TEST_DIR/t.qcow2 (file)
Cache mode: writeback
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backing
+(qemu) info block backing
backing: TEST_DIR/t.qcow2.base (qcow2, read-only)
Cache mode: writeback, ignore flushes
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backinginfo block backing-info block backing-finfo block backing-fiinfo block backing-filinfo block backing-file
+(qemu) info block backing-file
backing-file: TEST_DIR/t.qcow2.base (file, read-only)
Cache mode: writeback, ignore flushes
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,cache=writethrough,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
+(qemu) info block
drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
Removable device: not locked, tray closed
Cache mode: writethrough
Backing file: TEST_DIR/t.qcow2.base (chain depth: 1)
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block finfo block fiinfo block filinfo block file
+(qemu) info block file
file: TEST_DIR/t.qcow2 (file)
Cache mode: writeback
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backing
+(qemu) info block backing
backing: TEST_DIR/t.qcow2.base (qcow2, read-only)
Cache mode: writeback, ignore flushes
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backinginfo block backing-info block backing-finfo block backing-fiinfo block backing-filinfo block backing-file
+(qemu) info block backing-file
backing-file: TEST_DIR/t.qcow2.base (file, read-only)
Cache mode: writeback, ignore flushes
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,cache=unsafe,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
+(qemu) info block
drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
Removable device: not locked, tray closed
Cache mode: writeback, ignore flushes
Backing file: TEST_DIR/t.qcow2.base (chain depth: 1)
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block finfo block fiinfo block filinfo block file
+(qemu) info block file
file: TEST_DIR/t.qcow2 (file)
Cache mode: writeback, ignore flushes
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backing
+(qemu) info block backing
backing: TEST_DIR/t.qcow2.base (qcow2, read-only)
Cache mode: writeback, ignore flushes
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backinginfo block backing-info block backing-finfo block backing-fiinfo block backing-filinfo block backing-file
+(qemu) info block backing-file
backing-file: TEST_DIR/t.qcow2.base (file, read-only)
Cache mode: writeback, ignore flushes
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0: invalid cache option
@@ -213,7 +213,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filenam
Testing: -drive file=TEST_DIR/t.qcow2,file.driver=file
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
=== Leaving out required options ===
@@ -221,6 +221,9 @@ QEMU X.Y.Z monitor - type 'help' for more information
Testing: -drive driver=file
QEMU_PROG: -drive driver=file: The 'file' block driver requires a file name
+Testing: -drive driver=file,filename=
+QEMU_PROG: -drive driver=file,filename=: The 'file' block driver requires a file name
+
Testing: -drive driver=nbd
QEMU_PROG: -drive driver=nbd: NBD server address missing
@@ -307,15 +310,15 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,throttling.bps-total=-5: bps/iops/max va
Testing: -drive file=TEST_DIR/t.qcow2,bps=0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,bps=1
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,bps=1000000000000000
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,bps=1000000000000001
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,bps=1000000000000001: bps/iops/max values must be within [0, 1000000000000000]
@@ -337,11 +340,11 @@ QEMU_PROG: -drive file.filename=foo:bar: Could not open 'foo:bar': No such file
Testing: -hda file:TEST_DIR/t.qcow2
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=file:TEST_DIR/t.qcow2
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file.filename=file:TEST_DIR/t.qcow2
QEMU_PROG: -drive file.filename=file:TEST_DIR/t.qcow2: Could not open 'file:TEST_DIR/t.qcow2': No such file or directory
@@ -353,78 +356,78 @@ wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=drive0 -snapshot
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file.filename=TEST_DIR/t.qcow2,driver=qcow2,snapshot=on,if=none,id=drive0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file.filename=TEST_DIR/t.qcow2,driver=qcow2,if=none,id=drive0 -snapshot
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=file:TEST_DIR/t.qcow2,if=none,id=drive0 -snapshot
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=file:TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=drive0 -snapshot
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
read 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Testing: -drive file=TEST_DIR/t.qcow2,snapshot=off,if=none,id=drive0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
read 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x3qemu-io drive0 "write -P 0x33qemu-io drive0 "write -P 0x33 qemu-io drive0 "write -P 0x33 0qemu-io drive0 "write -P 0x33 0 qemu-io drive0 "write -P 0x33 0 4qemu-io drive0 "write -P 0x33 0 4kqemu-io drive0 "write -P 0x33 0 4k"
+(qemu) qemu-io drive0 "write -P 0x33 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) ccocomcommcommicommitcommit commit dcommit drcommit dricommit drivcommit drivecommit drive0
-(qemu) qququiquit
+(qemu) commit drive0
+(qemu) quit
read 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/051.pc.out b/tests/qemu-iotests/051.pc.out
index c6f4eef215..76d7205460 100644
--- a/tests/qemu-iotests/051.pc.out
+++ b/tests/qemu-iotests/051.pc.out
@@ -58,12 +58,12 @@ QEMU X.Y.Z monitor - type 'help' for more information
Testing: -drive file=TEST_DIR/t.qcow2,driver=qcow2,backing.file.filename=TEST_DIR/t.qcow2.orig,if=none,id=drive0 -nodefaults
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
+(qemu) info block
drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
Removable device: not locked, tray closed
Cache mode: writeback
Backing file: TEST_DIR/t.qcow2.orig (chain depth: 1)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,driver=raw,backing.file.filename=TEST_DIR/t.qcow2.orig
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,driver=raw,backing.file.filename=TEST_DIR/t.qcow2.orig: Driver doesn't support backing files
@@ -79,11 +79,11 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.backing.driver=qcow2,file.backing.f
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=: Parameter 'lazy-refcounts' expects 'on' or 'off'
@@ -103,23 +103,23 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on: Lazy ref
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
=== No medium ===
Testing: -drive if=floppy
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive if=ide,media=cdrom
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive if=scsi,media=cdrom
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -drive if=scsi,media=cdrom: warning: bus=0,unit=0 is deprecated with this machine type
-qququiquit
+quit
Testing: -drive if=ide
QEMU X.Y.Z monitor - type 'help' for more information
@@ -137,11 +137,11 @@ QEMU X.Y.Z monitor - type 'help' for more information
Testing: -drive if=none,id=disk -device ide-cd,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive if=none,id=disk -device ide-drive,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information
@@ -166,16 +166,16 @@ QEMU X.Y.Z monitor - type 'help' for more information
Testing: -drive file=TEST_DIR/t.qcow2,if=floppy,readonly=on
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,media=cdrom,readonly=on
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on: warning: bus=0,unit=0 is deprecated with this machine type
-qququiquit
+quit
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on
QEMU X.Y.Z monitor - type 'help' for more information
@@ -185,19 +185,19 @@ QEMU_PROG: Initialization of device ide-hd failed: Device initialization failed.
Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on: warning: bus=0,unit=0 is deprecated with this machine type
-qququiquit
+quit
Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-cd,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-drive,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information
@@ -211,97 +211,97 @@ QEMU_PROG: -device ide-hd,drive=disk: Device initialization failed.
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
=== Cache modes ===
Testing: -drive driver=null-co,cache=none
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive driver=null-co,cache=directsync
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive driver=null-co,cache=writeback
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive driver=null-co,cache=writethrough
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive driver=null-co,cache=unsafe
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive driver=null-co,cache=invalid_value
QEMU_PROG: -drive driver=null-co,cache=invalid_value: invalid cache option
Testing: -drive file=TEST_DIR/t.qcow2,cache=writeback,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
+(qemu) info block
drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
Removable device: not locked, tray closed
Cache mode: writeback
Backing file: TEST_DIR/t.qcow2.base (chain depth: 1)
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block finfo block fiinfo block filinfo block file
+(qemu) info block file
file: TEST_DIR/t.qcow2 (file)
Cache mode: writeback
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backing
+(qemu) info block backing
backing: TEST_DIR/t.qcow2.base (qcow2, read-only)
Cache mode: writeback, ignore flushes
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backinginfo block backing-info block backing-finfo block backing-fiinfo block backing-filinfo block backing-file
+(qemu) info block backing-file
backing-file: TEST_DIR/t.qcow2.base (file, read-only)
Cache mode: writeback, ignore flushes
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,cache=writethrough,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
+(qemu) info block
drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
Removable device: not locked, tray closed
Cache mode: writethrough
Backing file: TEST_DIR/t.qcow2.base (chain depth: 1)
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block finfo block fiinfo block filinfo block file
+(qemu) info block file
file: TEST_DIR/t.qcow2 (file)
Cache mode: writeback
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backing
+(qemu) info block backing
backing: TEST_DIR/t.qcow2.base (qcow2, read-only)
Cache mode: writeback, ignore flushes
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backinginfo block backing-info block backing-finfo block backing-fiinfo block backing-filinfo block backing-file
+(qemu) info block backing-file
backing-file: TEST_DIR/t.qcow2.base (file, read-only)
Cache mode: writeback, ignore flushes
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,cache=unsafe,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
+(qemu) info block
drive0 (NODE_NAME): TEST_DIR/t.qcow2 (qcow2)
Removable device: not locked, tray closed
Cache mode: writeback, ignore flushes
Backing file: TEST_DIR/t.qcow2.base (chain depth: 1)
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block finfo block fiinfo block filinfo block file
+(qemu) info block file
file: TEST_DIR/t.qcow2 (file)
Cache mode: writeback, ignore flushes
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backing
+(qemu) info block backing
backing: TEST_DIR/t.qcow2.base (qcow2, read-only)
Cache mode: writeback, ignore flushes
-(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo blockinfo block info block binfo block bainfo block bacinfo block backinfo block backiinfo block backininfo block backinginfo block backing-info block backing-finfo block backing-fiinfo block backing-filinfo block backing-file
+(qemu) info block backing-file
backing-file: TEST_DIR/t.qcow2.base (file, read-only)
Cache mode: writeback, ignore flushes
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0 -nodefaults
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filename=TEST_DIR/t.qcow2.base,backing.cache.no-flush=on,backing.node-name=backing,backing.file.node-name=backing-file,file.node-name=file,if=none,id=drive0: invalid cache option
@@ -311,7 +311,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,cache=invalid_value,backing.file.filenam
Testing: -drive file=TEST_DIR/t.qcow2,file.driver=file
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
=== Leaving out required options ===
@@ -319,6 +319,9 @@ QEMU X.Y.Z monitor - type 'help' for more information
Testing: -drive driver=file
QEMU_PROG: -drive driver=file: The 'file' block driver requires a file name
+Testing: -drive driver=file,filename=
+QEMU_PROG: -drive driver=file,filename=: The 'file' block driver requires a file name
+
Testing: -drive driver=nbd
QEMU_PROG: -drive driver=nbd: NBD server address missing
@@ -405,15 +408,15 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,throttling.bps-total=-5: bps/iops/max va
Testing: -drive file=TEST_DIR/t.qcow2,bps=0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,bps=1
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,bps=1000000000000000
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,bps=1000000000000001
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,bps=1000000000000001: bps/iops/max values must be within [0, 1000000000000000]
@@ -435,11 +438,11 @@ QEMU_PROG: -drive file.filename=foo:bar: Could not open 'foo:bar': No such file
Testing: -hda file:TEST_DIR/t.qcow2
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=file:TEST_DIR/t.qcow2
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file.filename=file:TEST_DIR/t.qcow2
QEMU_PROG: -drive file.filename=file:TEST_DIR/t.qcow2: Could not open 'file:TEST_DIR/t.qcow2': No such file or directory
@@ -451,78 +454,78 @@ wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=drive0 -snapshot
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file.filename=TEST_DIR/t.qcow2,driver=qcow2,snapshot=on,if=none,id=drive0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file.filename=TEST_DIR/t.qcow2,driver=qcow2,if=none,id=drive0 -snapshot
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=file:TEST_DIR/t.qcow2,if=none,id=drive0 -snapshot
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=file:TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=drive0 -snapshot
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
read 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Testing: -drive file=TEST_DIR/t.qcow2,snapshot=off,if=none,id=drive0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x2qemu-io drive0 "write -P 0x22qemu-io drive0 "write -P 0x22 qemu-io drive0 "write -P 0x22 0qemu-io drive0 "write -P 0x22 0 qemu-io drive0 "write -P 0x22 0 4qemu-io drive0 "write -P 0x22 0 4kqemu-io drive0 "write -P 0x22 0 4k"
+(qemu) qemu-io drive0 "write -P 0x22 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) qququiquit
+(qemu) quit
read 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on,if=none,id=drive0
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io dqemu-io drqemu-io driqemu-io drivqemu-io driveqemu-io drive0qemu-io drive0 qemu-io drive0 "qemu-io drive0 "wqemu-io drive0 "wrqemu-io drive0 "wriqemu-io drive0 "writqemu-io drive0 "writeqemu-io drive0 "write qemu-io drive0 "write -qemu-io drive0 "write -Pqemu-io drive0 "write -P qemu-io drive0 "write -P 0qemu-io drive0 "write -P 0xqemu-io drive0 "write -P 0x3qemu-io drive0 "write -P 0x33qemu-io drive0 "write -P 0x33 qemu-io drive0 "write -P 0x33 0qemu-io drive0 "write -P 0x33 0 qemu-io drive0 "write -P 0x33 0 4qemu-io drive0 "write -P 0x33 0 4kqemu-io drive0 "write -P 0x33 0 4k"
+(qemu) qemu-io drive0 "write -P 0x33 0 4k"
wrote 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-(qemu) ccocomcommcommicommitcommit commit dcommit drcommit dricommit drivcommit drivecommit drive0
-(qemu) qququiquit
+(qemu) commit drive0
+(qemu) quit
read 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/066 b/tests/qemu-iotests/066
index 364166d3b2..c2116a3088 100755
--- a/tests/qemu-iotests/066
+++ b/tests/qemu-iotests/066
@@ -42,16 +42,18 @@ _supported_fmt qcow2
_supported_proto generic
_supported_os Linux
+# Intentionally create an unaligned image
IMGOPTS="compat=1.1"
-IMG_SIZE=64M
+IMG_SIZE=$((64 * 1024 * 1024 + 512))
echo
-echo "=== Testing snapshotting an image with zero clusters ==="
+echo "=== Testing cluster discards ==="
echo
_make_test_img $IMG_SIZE
-# Write some normal clusters, zero them (creating preallocated zero clusters)
-# and discard those
-$QEMU_IO -c "write 0 256k" -c "write -z 0 256k" -c "discard 0 256k" "$TEST_IMG" \
+# Write some normal clusters, zero some of them (creating preallocated
+# zero clusters) and discard everything. Everything should now read as 0.
+$QEMU_IO -c "write 0 256k" -c "write -z 0 256k" -c "write 64M 512" \
+ -c "discard 0 $IMG_SIZE" -c "read -P 0 0 $IMG_SIZE" "$TEST_IMG" \
| _filter_qemu_io
# Check the image (there shouldn't be any leaks)
_check_test_img
diff --git a/tests/qemu-iotests/066.out b/tests/qemu-iotests/066.out
index 7bc9a107d5..7c1f31a1b1 100644
--- a/tests/qemu-iotests/066.out
+++ b/tests/qemu-iotests/066.out
@@ -1,13 +1,17 @@
QA output created by 066
-=== Testing snapshotting an image with zero clusters ===
+=== Testing cluster discards ===
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67109376
wrote 262144/262144 bytes at offset 0
256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 262144/262144 bytes at offset 0
256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-discard 262144/262144 bytes at offset 0
-256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 512/512 bytes at offset 67108864
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+discard 67109376/67109376 bytes at offset 0
+64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read 67109376/67109376 bytes at offset 0
+64 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
No errors were found on the image.
*** done
diff --git a/tests/qemu-iotests/068 b/tests/qemu-iotests/068
index 68f6e825d9..9c1687d01d 100755
--- a/tests/qemu-iotests/068
+++ b/tests/qemu-iotests/068
@@ -62,11 +62,11 @@ esac
# Give qemu some time to boot before saving the VM state
bash -c 'sleep 1; echo -e "savevm 0\nquit"' |\
$QEMU $platform_parm -nographic -monitor stdio -serial none -hda "$TEST_IMG" |\
- _filter_qemu
+ _filter_qemu | _filter_hmp
# Now try to continue from that VM state (this should just work)
echo quit |\
$QEMU $platform_parm -nographic -monitor stdio -serial none -hda "$TEST_IMG" -loadvm 0 |\
- _filter_qemu
+ _filter_qemu | _filter_hmp
# success, all done
echo "*** done"
diff --git a/tests/qemu-iotests/068.out b/tests/qemu-iotests/068.out
index 84f19b4ffd..0fa5340c22 100644
--- a/tests/qemu-iotests/068.out
+++ b/tests/qemu-iotests/068.out
@@ -4,8 +4,8 @@ QA output created by 068
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) ssasavsavesavevsavevmsavevm savevm 0
-(qemu) qququiquit
+(qemu) savevm 0
+(qemu) quit
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
*** done
diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
index 6161633a52..3b496a3918 100755
--- a/tests/qemu-iotests/109
+++ b/tests/qemu-iotests/109
@@ -81,7 +81,8 @@ for fmt in qcow qcow2 qed vdi vmdk vpc; do
# This first test should fail: The image format was probed, we may not
# write an image header at the start of the image
- run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR"
+ run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR" |
+ _filter_block_job_len
$QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io
@@ -104,7 +105,8 @@ for sample_img in empty.bochs iotest-dirtylog-10G-4M.vhdx parallels-v1 \
_make_test_img 64M
bzcat "$SAMPLE_IMG_DIR/$sample_img.bz2" > "$TEST_IMG.src"
- run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR" | _filter_block_job_offset
+ run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR" |
+ _filter_block_job_offset | _filter_block_job_len
$QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io
run_qemu "$TEST_IMG" "$TEST_IMG.src" "'format': 'raw'," "BLOCK_JOB_READY"
diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out
index 55fe536d56..dc02f9eefa 100644
--- a/tests/qemu-iotests/109.out
+++ b/tests/qemu-iotests/109.out
@@ -10,7 +10,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -31,7 +31,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 197120, "offset": 512, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 512, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -52,7 +52,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 262144, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 262144, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -73,7 +73,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -94,7 +94,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -115,7 +115,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -135,7 +135,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -155,7 +155,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -175,7 +175,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
@@ -195,7 +195,7 @@ Automatically detecting the format is dangerous for raw images, write operations
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
-{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/122.out b/tests/qemu-iotests/122.out
index 98814de5d6..9317d801ad 100644
--- a/tests/qemu-iotests/122.out
+++ b/tests/qemu-iotests/122.out
@@ -61,8 +61,8 @@ read 65536/65536 bytes at offset 4194304
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 65536/65536 bytes at offset 8388608
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-qemu-img: -B makes no sense when concatenating multiple input images
-qemu-img: -B makes no sense when concatenating multiple input images
+qemu-img: Having a backing file for the target makes no sense when concatenating multiple input images
+qemu-img: Having a backing file for the target makes no sense when concatenating multiple input images
=== Compression with misaligned allocations and image sizes ===
diff --git a/tests/qemu-iotests/130.out b/tests/qemu-iotests/130.out
index ae95b5027a..93020c328e 100644
--- a/tests/qemu-iotests/130.out
+++ b/tests/qemu-iotests/130.out
@@ -9,14 +9,14 @@ virtual size: 64M (67108864 bytes)
=== HMP commit ===
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) ccocomcommcommicommitcommit commit tcommit tecommit tescommit testcommit testdcommit testdicommit testdiscommit testdisk
+(qemu) commit testdisk
(qemu)
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64M (67108864 bytes)
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.orig backing_fmt=raw
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) ccocomcommcommicommitcommit commit tcommit tecommit tescommit testcommit testdcommit testdicommit testdiscommit testdisk
+(qemu) commit testdisk
(qemu)
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
diff --git a/tests/qemu-iotests/142 b/tests/qemu-iotests/142
index 29c0606bd7..9a5b713256 100755
--- a/tests/qemu-iotests/142
+++ b/tests/qemu-iotests/142
@@ -62,7 +62,7 @@ function do_run_qemu()
function run_qemu()
{
- do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu
+ do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qemu | _filter_hmp
}
size=128M
diff --git a/tests/qemu-iotests/142.out b/tests/qemu-iotests/142.out
index 600beca8fb..3667e38def 100644
--- a/tests/qemu-iotests/142.out
+++ b/tests/qemu-iotests/142.out
@@ -7,23 +7,23 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/
Testing: -drive file=TEST_DIR/t.qcow2,cache=none
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,cache=directsync
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,cache=writeback
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,cache=writethrough
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,cache=unsafe
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
Testing: -drive file=TEST_DIR/t.qcow2,cache=invalid_value
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,cache=invalid_value: invalid cache option
diff --git a/tests/qemu-iotests/145 b/tests/qemu-iotests/145
index 1eca0e8990..e6c6bc4a4f 100755
--- a/tests/qemu-iotests/145
+++ b/tests/qemu-iotests/145
@@ -43,7 +43,8 @@ _supported_proto generic
_supported_os Linux
_make_test_img 1M
-echo quit | $QEMU -nographic -hda "$TEST_IMG" -incoming 'exec:true' -snapshot -serial none -monitor stdio | _filter_qemu
+echo quit | $QEMU -nographic -hda "$TEST_IMG" -incoming 'exec:true' -snapshot -serial none -monitor stdio |
+ _filter_qemu | _filter_hmp
# success, all done
echo "*** done"
diff --git a/tests/qemu-iotests/145.out b/tests/qemu-iotests/145.out
index 75b5c8ac36..9a90009e44 100644
--- a/tests/qemu-iotests/145.out
+++ b/tests/qemu-iotests/145.out
@@ -1,5 +1,5 @@
QA output created by 145
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
QEMU X.Y.Z monitor - type 'help' for more information
-(qemu) qququiquit
+(qemu) quit
*** done
diff --git a/tests/qemu-iotests/181 b/tests/qemu-iotests/181
new file mode 100755
index 0000000000..e969a2a94f
--- /dev/null
+++ b/tests/qemu-iotests/181
@@ -0,0 +1,119 @@
+#!/bin/bash
+#
+# Test postcopy live migration with shared storage
+#
+# Copyright (C) 2017 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=kwolf@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1 # failure is the default!
+
+MIG_SOCKET="${TEST_DIR}/migrate"
+
+_cleanup()
+{
+ rm -f "${MIG_SOCKET}"
+ _cleanup_test_img
+ _cleanup_qemu
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.qemu
+
+_supported_fmt generic
+_supported_proto generic
+_supported_os Linux
+
+size=64M
+_make_test_img $size
+
+echo
+echo === Starting VMs ===
+echo
+
+qemu_comm_method="monitor"
+
+_launch_qemu \
+ -drive file="${TEST_IMG}",cache=${CACHEMODE},driver=$IMGFMT,id=disk
+src=$QEMU_HANDLE
+
+_launch_qemu \
+ -drive file="${TEST_IMG}",cache=${CACHEMODE},driver=$IMGFMT,id=disk \
+ -incoming "unix:${MIG_SOCKET}"
+dest=$QEMU_HANDLE
+
+echo
+echo === Write something on the source ===
+echo
+
+silent=
+_send_qemu_cmd $src 'qemu-io disk "write -P 0x55 0 64k"' "(qemu)"
+_send_qemu_cmd $src "" "ops/sec"
+_send_qemu_cmd $src 'qemu-io disk "read -P 0x55 0 64k"' "(qemu)"
+_send_qemu_cmd $src "" "ops/sec"
+
+echo
+echo === Do postcopy migration to destination ===
+echo
+
+# Slow down migration so much that it definitely won't finish before we can
+# switch to postcopy
+silent=yes
+_send_qemu_cmd $src 'migrate_set_speed 4k' "(qemu)"
+_send_qemu_cmd $src 'migrate_set_capability postcopy-ram on' "(qemu)"
+_send_qemu_cmd $src "migrate -d unix:${MIG_SOCKET}" "(qemu)"
+_send_qemu_cmd $src 'migrate_start_postcopy' "(qemu)"
+
+QEMU_COMM_TIMEOUT=1 qemu_cmd_repeat=10 silent=yes \
+ _send_qemu_cmd $src "info migrate" "completed\|failed"
+silent=yes _send_qemu_cmd $src "" "(qemu)"
+
+echo
+echo === Do some I/O on the destination ===
+echo
+
+# It is important that we use the BlockBackend of the guest device here instead
+# of the node name, which would create a new BlockBackend and not test whether
+# the guest has the necessary permissions to access the image now
+silent=
+_send_qemu_cmd $dest 'qemu-io disk "read -P 0x55 0 64k"' "(qemu)"
+_send_qemu_cmd $dest "" "ops/sec"
+_send_qemu_cmd $dest 'qemu-io disk "write -P 0x66 1M 64k"' "(qemu)"
+_send_qemu_cmd $dest "" "ops/sec"
+
+echo
+echo === Shut down and check image ===
+echo
+
+_send_qemu_cmd $src 'quit' ""
+_send_qemu_cmd $dest 'quit' ""
+wait=1 _cleanup_qemu
+
+_check_test_img
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/181.out b/tests/qemu-iotests/181.out
new file mode 100644
index 0000000000..6534ba2a76
--- /dev/null
+++ b/tests/qemu-iotests/181.out
@@ -0,0 +1,38 @@
+QA output created by 181
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+
+=== Starting VMs ===
+
+
+=== Write something on the source ===
+
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qemu-io disk "write -P 0x55 0 64k"
+wrote 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+(qemu)
+(qemu) qemu-io disk "read -P 0x55 0 64k"
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+=== Do postcopy migration to destination ===
+
+
+=== Do some I/O on the destination ===
+
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu) qemu-io disk "read -P 0x55 0 64k"
+read 65536/65536 bytes at offset 0
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+(qemu)
+(qemu) qemu-io disk "write -P 0x66 1M 64k"
+wrote 65536/65536 bytes at offset 1048576
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+=== Shut down and check image ===
+
+(qemu) quit
+(qemu)
+(qemu) quit
+No errors were found on the image.
+*** done
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
index 9c6f9721e5..f2a7199c4b 100644
--- a/tests/qemu-iotests/common
+++ b/tests/qemu-iotests/common
@@ -86,7 +86,8 @@ s/ .*//p
elif $xgroup
then
# arg after -x
- [ ! -s $tmp.list ] && ls [0-9][0-9][0-9] [0-9][0-9][0-9][0-9] >$tmp.list 2>/dev/null
+ # Populate $tmp.list with all tests
+ awk '/^[0-9]{3,}/ {print $1}' "${source_iotests}/group" > $tmp.list 2>/dev/null
group_list=`sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
s/ .*//p
}'`
@@ -138,7 +139,7 @@ common options
-v verbose
-d debug
-check options
+image format options
-raw test raw (default)
-bochs test bochs
-cloop test cloop
@@ -150,14 +151,18 @@ check options
-vpc test vpc
-vhdx test vhdx
-vmdk test vmdk
+ -luks test luks
+
+image protocol options
-file test file (default)
-rbd test rbd
-sheepdog test sheepdog
-nbd test nbd
-ssh test ssh
-nfs test nfs
- -luks test luks
-vxhs test vxhs
+
+other options
-xdiff graphical mode diff
-nocache use O_DIRECT on backing file
-misalign misalign memory allocations
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
index c4b51b3509..d1b45f5447 100644
--- a/tests/qemu-iotests/common.config
+++ b/tests/qemu-iotests/common.config
@@ -75,18 +75,12 @@ _fatal()
exit 1
}
-export PERL_PROG="`set_prog_path perl`"
-[ "$PERL_PROG" = "" ] && _fatal "perl not found"
-
export AWK_PROG="`set_prog_path awk`"
[ "$AWK_PROG" = "" ] && _fatal "awk not found"
export SED_PROG="`set_prog_path sed`"
[ "$SED_PROG" = "" ] && _fatal "sed not found"
-export BC_PROG="`set_prog_path bc`"
-[ "$BC_PROG" = "" ] && _fatal "bc not found"
-
export PS_ALL_FLAGS="-ef"
if [ -z "$QEMU_PROG" ]; then
@@ -223,23 +217,5 @@ fi
export SAMPLE_IMG_DIR
-_readlink()
-{
- if [ $# -ne 1 ]; then
- echo "Usage: _readlink filename" 1>&2
- exit 1
- fi
-
- perl -e "\$in=\"$1\";" -e '
- $lnk = readlink($in);
- if ($lnk =~ m!^/.*!) {
- print "$lnk\n";
- }
- else {
- chomp($dir = `dirname $in`);
- print "$dir/$lnk\n";
- }'
-}
-
# make sure this script returns success
true
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index c9a2d5c595..f58548dc44 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -86,12 +86,25 @@ _filter_qmp()
-e ' QMP_VERSION'
}
+# readline makes HMP command strings so long that git complains
+_filter_hmp()
+{
+ sed -e $'s/^\\((qemu) \\)\\?.*\e\\[D/\\1/g' \
+ -e $'s/\e\\[K//g'
+}
+
# replace block job offset
_filter_block_job_offset()
{
sed -e 's/, "offset": [0-9]\+,/, "offset": OFFSET,/'
}
+# replace block job len
+_filter_block_job_len()
+{
+ sed -e 's/, "len": [0-9]\+,/, "len": LEN,/g'
+}
+
# replace driver-specific options in the "Formatting..." line
_filter_img_create()
{
diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
index 42787896af..7a78a00999 100644
--- a/tests/qemu-iotests/common.qemu
+++ b/tests/qemu-iotests/common.qemu
@@ -59,7 +59,7 @@ function _timed_wait_for()
do
if [ -z "${silent}" ]; then
echo "${resp}" | _filter_testdir | _filter_qemu \
- | _filter_qemu_io | _filter_qmp
+ | _filter_qemu_io | _filter_qmp | _filter_hmp
fi
grep -q "${*}" < <(echo ${resp})
if [ $? -eq 0 ]; then
@@ -217,7 +217,7 @@ function _cleanup_qemu()
if [ -n "${wait}" ]; then
cat <&${QEMU_OUT[$i]} | _filter_testdir | _filter_qemu \
- | _filter_qemu_io | _filter_qmp
+ | _filter_qemu_io | _filter_qmp | _filter_hmp
fi
rm -f "${QEMU_FIFO_IN}_${i}" "${QEMU_FIFO_OUT}_${i}"
eval "exec ${QEMU_IN[$i]}<&-" # close file descriptors
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 62529eed6e..9fd3130bde 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -171,7 +171,9 @@ _make_test_img()
# Start an NBD server on the image file, which is what we'll be talking to
if [ $IMGPROTO = "nbd" ]; then
- eval "$QEMU_NBD -v -t -b 127.0.0.1 -p 10810 -f $IMGFMT $TEST_IMG_FILE >/dev/null &"
+ # Pass a sufficiently high number to -e that should be enough for all
+ # tests
+ eval "$QEMU_NBD -v -t -b 127.0.0.1 -p 10810 -f $IMGFMT -e 42 $TEST_IMG_FILE >/dev/null &"
sleep 1 # FIXME: qemu-nbd needs to be listening before we continue
fi
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 43142ddfcf..893962d41e 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -169,3 +169,4 @@
174 auto
175 auto quick
176 rw auto backing
+181 rw auto migration
diff --git a/util/qemu-progress.c b/util/qemu-progress.c
index f745233763..3c2223c1a2 100644
--- a/util/qemu-progress.c
+++ b/util/qemu-progress.c
@@ -88,6 +88,9 @@ static void progress_dummy_init(void)
action.sa_handler = sigusr_print;
action.sa_flags = 0;
sigaction(SIGUSR1, &action, NULL);
+#ifdef SIGINFO
+ sigaction(SIGINFO, &action, NULL);
+#endif
/*
* SIGUSR1 is SIG_IPI and gets blocked in qemu_init_main_loop(). In the
diff --git a/vl.c b/vl.c
index f46e070e0d..42d4bce439 100644
--- a/vl.c
+++ b/vl.c
@@ -3231,6 +3231,8 @@ int main(int argc, char **argv, char **envp)
}
}
}
+ error_report("'-hdachs' is deprecated, please use '-device"
+ " ide-hd,cyls=c,heads=h,secs=s,...' instead");
break;
case QEMU_OPTION_numa:
opts = qemu_opts_parse_noisily(qemu_find_opts("numa"),