summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-02-13 10:16:23 +0000
committerPeter Maydell <peter.maydell@linaro.org>2017-02-13 10:16:23 +0000
commit0b4384d0bb98f0016ba671b1c9cc75c2f31cd057 (patch)
treedb1dee0698068c944569f72e325dc816065cc86d
parented3d90df7c75203d9d4bae135f0a3c75be209f78 (diff)
parent10d6eda1926804a09aa0710ca62933087813de0b (diff)
downloadqemu-0b4384d0bb98f0016ba671b1c9cc75c2f31cd057.tar.gz
Merge remote-tracking branch 'remotes/maxreitz/tags/pull-block-2017-02-12' into staging
Block patches # gpg: Signature made Sun 12 Feb 2017 01:26:20 GMT # gpg: using RSA key 0xF407DB0061D5CF40 # gpg: Good signature from "Max Reitz <mreitz@redhat.com>" # Primary key fingerprint: 91BE B60A 30DB 3E88 57D1 1829 F407 DB00 61D5 CF40 * remotes/maxreitz/tags/pull-block-2017-02-12: (21 commits) qemu-img: Avoid setting ret to unused value in img_convert() qemu-img: Use qemu_strtoul() rather than raw strtoul() qemu-io: don't allow I/O operations larger than BDRV_REQUEST_MAX_BYTES qcow2: Optimize the refcount-block overlap check qemu-io: Add failure regression tests qemu-iotests: Add _unsupported_fmt helper qemu-io: Return non-zero exit code on failure block/nfs: fix naming of runtime opts block/nfs: fix NULL pointer dereference in URI parsing block: bdrv_invalidate_cache: invalidate children first block/qapi: reduce the execution time of qmp_query_blockstats block/qapi: reduce the coupling between the bdrv_query_stats and bdrv_query_bds_stats qemu-iotest: test to lookup protocol-based image with relative backing qemu-iotests: Don't create fifos / pidfiles with protocol paths block: check full backing filename when searching protocol filenames block/vmdk: Fix the endian problem of buf_len and lba iotests: record separate timings per format,protocol pair iotests: Fix reference output for 059 qapi: Tweak error message of bdrv_query_image_info qemu-img: Improve commit invalid base message ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--block.c24
-rw-r--r--block/nfs.c49
-rw-r--r--block/qapi.c99
-rw-r--r--block/qcow2-refcount.c24
-rw-r--r--block/qcow2.c1
-rw-r--r--block/qcow2.h1
-rw-r--r--block/vmdk.c4
-rw-r--r--qemu-img.c44
-rw-r--r--qemu-io-cmds.c20
-rw-r--r--qemu-io.c8
-rw-r--r--tests/qemu-iotests/.gitignore2
-rw-r--r--tests/qemu-iotests/059.out5
-rw-r--r--tests/qemu-iotests/070.out1
-rw-r--r--tests/qemu-iotests/075.out7
-rw-r--r--tests/qemu-iotests/076.out3
-rw-r--r--tests/qemu-iotests/078.out6
-rw-r--r--tests/qemu-iotests/080.out18
-rw-r--r--tests/qemu-iotests/083.out17
-rw-r--r--tests/qemu-iotests/088.out6
-rw-r--r--tests/qemu-iotests/092.out12
-rw-r--r--tests/qemu-iotests/116.out7
-rw-r--r--tests/qemu-iotests/131.out1
-rw-r--r--tests/qemu-iotests/140.out1
-rwxr-xr-xtests/qemu-iotests/17397
-rw-r--r--tests/qemu-iotests/173.out12
-rwxr-xr-xtests/qemu-iotests/17459
-rw-r--r--tests/qemu-iotests/174.out7
-rw-r--r--tests/qemu-iotests/Makefile2
-rwxr-xr-xtests/qemu-iotests/check12
-rw-r--r--tests/qemu-iotests/common.config6
-rw-r--r--tests/qemu-iotests/common.filter2
-rw-r--r--tests/qemu-iotests/common.qemu10
-rw-r--r--tests/qemu-iotests/common.rc17
-rw-r--r--tests/qemu-iotests/group2
34 files changed, 366 insertions, 220 deletions
diff --git a/block.c b/block.c
index 1dbc060c3f..743c349100 100644
--- a/block.c
+++ b/block.c
@@ -3145,6 +3145,7 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
int is_protocol = 0;
BlockDriverState *curr_bs = NULL;
BlockDriverState *retval = NULL;
+ Error *local_error = NULL;
if (!bs || !bs->drv || !backing_file) {
return NULL;
@@ -3165,6 +3166,18 @@ BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
retval = curr_bs->backing->bs;
break;
}
+ /* Also check against the full backing filename for the image */
+ bdrv_get_full_backing_filename(curr_bs, backing_file_full, PATH_MAX,
+ &local_error);
+ if (local_error == NULL) {
+ if (strcmp(backing_file, backing_file_full) == 0) {
+ retval = curr_bs->backing->bs;
+ break;
+ }
+ } else {
+ error_free(local_error);
+ local_error = NULL;
+ }
} else {
/* If not an absolute filename path, make it relative to the current
* image's filename path */
@@ -3235,19 +3248,18 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp)
if (!(bs->open_flags & BDRV_O_INACTIVE)) {
return;
}
- bs->open_flags &= ~BDRV_O_INACTIVE;
- if (bs->drv->bdrv_invalidate_cache) {
- bs->drv->bdrv_invalidate_cache(bs, &local_err);
+ QLIST_FOREACH(child, &bs->children, next) {
+ bdrv_invalidate_cache(child->bs, &local_err);
if (local_err) {
- bs->open_flags |= BDRV_O_INACTIVE;
error_propagate(errp, local_err);
return;
}
}
- QLIST_FOREACH(child, &bs->children, next) {
- bdrv_invalidate_cache(child->bs, &local_err);
+ bs->open_flags &= ~BDRV_O_INACTIVE;
+ if (bs->drv->bdrv_invalidate_cache) {
+ bs->drv->bdrv_invalidate_cache(bs, &local_err);
if (local_err) {
bs->open_flags |= BDRV_O_INACTIVE;
error_propagate(errp, local_err);
diff --git a/block/nfs.c b/block/nfs.c
index a564340d15..689eaa792e 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -108,12 +108,13 @@ static int nfs_parse_uri(const char *filename, QDict *options, Error **errp)
qdict_put(options, "path", qstring_from_str(uri->path));
for (i = 0; i < qp->n; i++) {
+ unsigned long long val;
if (!qp->p[i].value) {
error_setg(errp, "Value for NFS parameter expected: %s",
qp->p[i].name);
goto out;
}
- if (parse_uint_full(qp->p[i].value, NULL, 0)) {
+ if (parse_uint_full(qp->p[i].value, &val, 0)) {
error_setg(errp, "Illegal value for NFS parameter: %s",
qp->p[i].name);
goto out;
@@ -358,27 +359,27 @@ static QemuOptsList runtime_opts = {
.help = "Path of the image on the host",
},
{
- .name = "uid",
+ .name = "user",
.type = QEMU_OPT_NUMBER,
.help = "UID value to use when talking to the server",
},
{
- .name = "gid",
+ .name = "group",
.type = QEMU_OPT_NUMBER,
.help = "GID value to use when talking to the server",
},
{
- .name = "tcp-syncnt",
+ .name = "tcp-syn-count",
.type = QEMU_OPT_NUMBER,
.help = "Number of SYNs to send during the session establish",
},
{
- .name = "readahead",
+ .name = "readahead-size",
.type = QEMU_OPT_NUMBER,
.help = "Set the readahead size in bytes",
},
{
- .name = "pagecache",
+ .name = "page-cache-size",
.type = QEMU_OPT_NUMBER,
.help = "Set the pagecache size in bytes",
},
@@ -507,29 +508,29 @@ static int64_t nfs_client_open(NFSClient *client, QDict *options,
goto fail;
}
- if (qemu_opt_get(opts, "uid")) {
- client->uid = qemu_opt_get_number(opts, "uid", 0);
+ if (qemu_opt_get(opts, "user")) {
+ client->uid = qemu_opt_get_number(opts, "user", 0);
nfs_set_uid(client->context, client->uid);
}
- if (qemu_opt_get(opts, "gid")) {
- client->gid = qemu_opt_get_number(opts, "gid", 0);
+ if (qemu_opt_get(opts, "group")) {
+ client->gid = qemu_opt_get_number(opts, "group", 0);
nfs_set_gid(client->context, client->gid);
}
- if (qemu_opt_get(opts, "tcp-syncnt")) {
- client->tcp_syncnt = qemu_opt_get_number(opts, "tcp-syncnt", 0);
+ if (qemu_opt_get(opts, "tcp-syn-count")) {
+ client->tcp_syncnt = qemu_opt_get_number(opts, "tcp-syn-count", 0);
nfs_set_tcp_syncnt(client->context, client->tcp_syncnt);
}
#ifdef LIBNFS_FEATURE_READAHEAD
- if (qemu_opt_get(opts, "readahead")) {
+ if (qemu_opt_get(opts, "readahead-size")) {
if (open_flags & BDRV_O_NOCACHE) {
error_setg(errp, "Cannot enable NFS readahead "
"if cache.direct = on");
goto fail;
}
- client->readahead = qemu_opt_get_number(opts, "readahead", 0);
+ client->readahead = qemu_opt_get_number(opts, "readahead-size", 0);
if (client->readahead > QEMU_NFS_MAX_READAHEAD_SIZE) {
error_report("NFS Warning: Truncating NFS readahead "
"size to %d", QEMU_NFS_MAX_READAHEAD_SIZE);
@@ -544,13 +545,13 @@ static int64_t nfs_client_open(NFSClient *client, QDict *options,
#endif
#ifdef LIBNFS_FEATURE_PAGECACHE
- if (qemu_opt_get(opts, "pagecache")) {
+ if (qemu_opt_get(opts, "page-cache-size")) {
if (open_flags & BDRV_O_NOCACHE) {
error_setg(errp, "Cannot enable NFS pagecache "
"if cache.direct = on");
goto fail;
}
- client->pagecache = qemu_opt_get_number(opts, "pagecache", 0);
+ client->pagecache = qemu_opt_get_number(opts, "page-cache-size", 0);
if (client->pagecache > QEMU_NFS_MAX_PAGECACHE_SIZE) {
error_report("NFS Warning: Truncating NFS pagecache "
"size to %d pages", QEMU_NFS_MAX_PAGECACHE_SIZE);
@@ -803,22 +804,22 @@ static void nfs_refresh_filename(BlockDriverState *bs, QDict *options)
qdict_put(opts, "path", qstring_from_str(client->path));
if (client->uid) {
- qdict_put(opts, "uid", qint_from_int(client->uid));
+ qdict_put(opts, "user", qint_from_int(client->uid));
}
if (client->gid) {
- qdict_put(opts, "gid", qint_from_int(client->gid));
+ qdict_put(opts, "group", qint_from_int(client->gid));
}
if (client->tcp_syncnt) {
- qdict_put(opts, "tcp-syncnt",
- qint_from_int(client->tcp_syncnt));
+ qdict_put(opts, "tcp-syn-cnt",
+ qint_from_int(client->tcp_syncnt));
}
if (client->readahead) {
- qdict_put(opts, "readahead",
- qint_from_int(client->readahead));
+ qdict_put(opts, "readahead-size",
+ qint_from_int(client->readahead));
}
if (client->pagecache) {
- qdict_put(opts, "pagecache",
- qint_from_int(client->pagecache));
+ qdict_put(opts, "page-cache-size",
+ qint_from_int(client->pagecache));
}
if (client->debug) {
qdict_put(opts, "debug", qint_from_int(client->debug));
diff --git a/block/qapi.c b/block/qapi.c
index a62e862f3c..ac480aa93c 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -237,8 +237,8 @@ void bdrv_query_image_info(BlockDriverState *bs,
size = bdrv_getlength(bs);
if (size < 0) {
- error_setg_errno(errp, -size, "Can't get size of device '%s'",
- bdrv_get_device_name(bs));
+ error_setg_errno(errp, -size, "Can't get image size '%s'",
+ bs->exact_filename);
goto out;
}
@@ -357,10 +357,6 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
qapi_free_BlockInfo(info);
}
-static BlockStats *bdrv_query_stats(BlockBackend *blk,
- const BlockDriverState *bs,
- bool query_backing);
-
static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
{
BlockAcctStats *stats = blk_get_stats(blk);
@@ -428,9 +424,18 @@ static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
}
}
-static void bdrv_query_bds_stats(BlockStats *s, const BlockDriverState *bs,
+static BlockStats *bdrv_query_bds_stats(const BlockDriverState *bs,
bool query_backing)
{
+ BlockStats *s = NULL;
+
+ s = g_malloc0(sizeof(*s));
+ s->stats = g_malloc0(sizeof(*s->stats));
+
+ if (!bs) {
+ return s;
+ }
+
if (bdrv_get_node_name(bs)[0]) {
s->has_node_name = true;
s->node_name = g_strdup(bdrv_get_node_name(bs));
@@ -440,32 +445,12 @@ static void bdrv_query_bds_stats(BlockStats *s, const BlockDriverState *bs,
if (bs->file) {
s->has_parent = true;
- s->parent = bdrv_query_stats(NULL, bs->file->bs, query_backing);
+ s->parent = bdrv_query_bds_stats(bs->file->bs, query_backing);
}
if (query_backing && bs->backing) {
s->has_backing = true;
- s->backing = bdrv_query_stats(NULL, bs->backing->bs, query_backing);
- }
-
-}
-
-static BlockStats *bdrv_query_stats(BlockBackend *blk,
- const BlockDriverState *bs,
- bool query_backing)
-{
- BlockStats *s;
-
- s = g_malloc0(sizeof(*s));
- s->stats = g_malloc0(sizeof(*s->stats));
-
- if (blk) {
- s->has_device = true;
- s->device = g_strdup(blk_name(blk));
- bdrv_query_blk_stats(s->stats, blk);
- }
- if (bs) {
- bdrv_query_bds_stats(s, bs, query_backing);
+ s->backing = bdrv_query_bds_stats(bs->backing->bs, query_backing);
}
return s;
@@ -494,42 +479,44 @@ BlockInfoList *qmp_query_block(Error **errp)
return head;
}
-static bool next_query_bds(BlockBackend **blk, BlockDriverState **bs,
- bool query_nodes)
-{
- if (query_nodes) {
- *bs = bdrv_next_node(*bs);
- return !!*bs;
- }
-
- *blk = blk_next(*blk);
- *bs = *blk ? blk_bs(*blk) : NULL;
-
- return !!*blk;
-}
-
BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
bool query_nodes,
Error **errp)
{
BlockStatsList *head = NULL, **p_next = &head;
- BlockBackend *blk = NULL;
- BlockDriverState *bs = NULL;
+ BlockBackend *blk;
+ BlockDriverState *bs;
/* Just to be safe if query_nodes is not always initialized */
- query_nodes = has_query_nodes && query_nodes;
-
- while (next_query_bds(&blk, &bs, query_nodes)) {
- BlockStatsList *info = g_malloc0(sizeof(*info));
- AioContext *ctx = blk ? blk_get_aio_context(blk)
- : bdrv_get_aio_context(bs);
+ if (has_query_nodes && query_nodes) {
+ for (bs = bdrv_next_node(NULL); bs; bs = bdrv_next_node(bs)) {
+ BlockStatsList *info = g_malloc0(sizeof(*info));
+ AioContext *ctx = bdrv_get_aio_context(bs);
- aio_context_acquire(ctx);
- info->value = bdrv_query_stats(blk, bs, !query_nodes);
- aio_context_release(ctx);
+ aio_context_acquire(ctx);
+ info->value = bdrv_query_bds_stats(bs, false);
+ aio_context_release(ctx);
- *p_next = info;
- p_next = &info->next;
+ *p_next = info;
+ p_next = &info->next;
+ }
+ } else {
+ for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
+ BlockStatsList *info = g_malloc0(sizeof(*info));
+ AioContext *ctx = blk_get_aio_context(blk);
+ BlockStats *s;
+
+ aio_context_acquire(ctx);
+ s = bdrv_query_bds_stats(blk_bs(blk), true);
+ s->has_device = true;
+ s->device = g_strdup(blk_name(blk));
+ bdrv_query_blk_stats(s->stats, blk);
+ aio_context_release(ctx);
+
+ info->value = s;
+ *p_next = info;
+ p_next = &info->next;
+ }
}
return head;
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index cbfb3fe064..3dbde18612 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -83,6 +83,16 @@ static Qcow2SetRefcountFunc *const set_refcount_funcs[] = {
/*********************************************************/
/* refcount handling */
+static void update_max_refcount_table_index(BDRVQcow2State *s)
+{
+ unsigned i = s->refcount_table_size - 1;
+ while (i > 0 && (s->refcount_table[i] & REFT_OFFSET_MASK) == 0) {
+ i--;
+ }
+ /* Set s->max_refcount_table_index to the index of the last used entry */
+ s->max_refcount_table_index = i;
+}
+
int qcow2_refcount_init(BlockDriverState *bs)
{
BDRVQcow2State *s = bs->opaque;
@@ -111,6 +121,7 @@ int qcow2_refcount_init(BlockDriverState *bs)
}
for(i = 0; i < s->refcount_table_size; i++)
be64_to_cpus(&s->refcount_table[i]);
+ update_max_refcount_table_index(s);
}
return 0;
fail:
@@ -439,6 +450,10 @@ static int alloc_refcount_block(BlockDriverState *bs,
}
s->refcount_table[refcount_table_index] = new_block;
+ /* If there's a hole in s->refcount_table then it can happen
+ * that refcount_table_index < s->max_refcount_table_index */
+ s->max_refcount_table_index =
+ MAX(s->max_refcount_table_index, refcount_table_index);
/* The new refcount block may be where the caller intended to put its
* data, so let it restart the search. */
@@ -580,6 +595,7 @@ static int alloc_refcount_block(BlockDriverState *bs,
s->refcount_table = new_table;
s->refcount_table_size = table_size;
s->refcount_table_offset = table_offset;
+ update_max_refcount_table_index(s);
/* Free old table. */
qcow2_free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t),
@@ -2171,6 +2187,7 @@ write_refblocks:
s->refcount_table = on_disk_reftable;
s->refcount_table_offset = reftable_offset;
s->refcount_table_size = reftable_size;
+ update_max_refcount_table_index(s);
return 0;
@@ -2383,7 +2400,11 @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
}
if ((chk & QCOW2_OL_REFCOUNT_BLOCK) && s->refcount_table) {
- for (i = 0; i < s->refcount_table_size; i++) {
+ unsigned last_entry = s->max_refcount_table_index;
+ assert(last_entry < s->refcount_table_size);
+ assert(last_entry + 1 == s->refcount_table_size ||
+ (s->refcount_table[last_entry + 1] & REFT_OFFSET_MASK) == 0);
+ for (i = 0; i <= last_entry; i++) {
if ((s->refcount_table[i] & REFT_OFFSET_MASK) &&
overlaps_with(s->refcount_table[i] & REFT_OFFSET_MASK,
s->cluster_size)) {
@@ -2871,6 +2892,7 @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
/* Now update the rest of the in-memory information */
old_reftable = s->refcount_table;
s->refcount_table = new_reftable;
+ update_max_refcount_table_index(s);
s->refcount_bits = 1 << refcount_order;
s->refcount_max = UINT64_C(1) << (s->refcount_bits - 1);
diff --git a/block/qcow2.c b/block/qcow2.c
index 96fb8a8f16..3e274bd1ba 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2743,6 +2743,7 @@ static int make_completely_empty(BlockDriverState *bs)
s->refcount_table_offset = s->cluster_size;
s->refcount_table_size = s->cluster_size / sizeof(uint64_t);
+ s->max_refcount_table_index = 0;
g_free(s->refcount_table);
s->refcount_table = new_reftable;
diff --git a/block/qcow2.h b/block/qcow2.h
index 182341483a..f8aeb08794 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -251,6 +251,7 @@ typedef struct BDRVQcow2State {
uint64_t *refcount_table;
uint64_t refcount_table_offset;
uint32_t refcount_table_size;
+ uint32_t max_refcount_table_index; /* Last used entry in refcount_table */
uint64_t free_cluster_index;
uint64_t free_byte_offset;
diff --git a/block/vmdk.c b/block/vmdk.c
index 7750212969..393c84d8b1 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1361,8 +1361,8 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
goto out;
}
- data->lba = offset >> BDRV_SECTOR_BITS;
- data->size = buf_len;
+ data->lba = cpu_to_le64(offset >> BDRV_SECTOR_BITS);
+ data->size = cpu_to_le32(buf_len);
n_bytes = buf_len + sizeof(VmdkGrainMarker);
iov = (struct iovec) {
diff --git a/qemu-img.c b/qemu-img.c
index 74e3362653..cff22e3005 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -912,7 +912,9 @@ static int img_commit(int argc, char **argv)
if (base) {
base_bs = bdrv_find_backing_image(bs, base);
if (!base_bs) {
- error_setg(&local_err, QERR_BASE_NOT_FOUND, base);
+ error_setg(&local_err,
+ "Did not find '%s' in the backing chain of '%s'",
+ base, filename);
goto done;
}
} else {
@@ -1966,10 +1968,10 @@ static int img_convert(int argc, char **argv)
}
if (sn_opts) {
- ret = bdrv_snapshot_load_tmp(bs[0],
- qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID),
- qemu_opt_get(sn_opts, SNAPSHOT_OPT_NAME),
- &local_err);
+ bdrv_snapshot_load_tmp(bs[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) {
error_report("No support for concatenating multiple snapshot");
@@ -3621,24 +3623,24 @@ static int img_bench(int argc, char **argv)
break;
case 'c':
{
- char *end;
- errno = 0;
- count = strtoul(optarg, &end, 0);
- if (errno || *end || count > INT_MAX) {
+ unsigned long res;
+
+ if (qemu_strtoul(optarg, NULL, 0, &res) < 0 || res > INT_MAX) {
error_report("Invalid request count specified");
return 1;
}
+ count = res;
break;
}
case 'd':
{
- char *end;
- errno = 0;
- depth = strtoul(optarg, &end, 0);
- if (errno || *end || depth > INT_MAX) {
+ unsigned long res;
+
+ if (qemu_strtoul(optarg, NULL, 0, &res) < 0 || res > INT_MAX) {
error_report("Invalid queue depth specified");
return 1;
}
+ depth = res;
break;
}
case 'f':
@@ -3705,24 +3707,24 @@ static int img_bench(int argc, char **argv)
break;
case OPTION_PATTERN:
{
- char *end;
- errno = 0;
- pattern = strtoul(optarg, &end, 0);
- if (errno || *end || pattern > 0xff) {
+ unsigned long res;
+
+ if (qemu_strtoul(optarg, NULL, 0, &res) < 0 || res > 0xff) {
error_report("Invalid pattern byte specified");
return 1;
}
+ pattern = res;
break;
}
case OPTION_FLUSH_INTERVAL:
{
- char *end;
- errno = 0;
- flush_interval = strtoul(optarg, &end, 0);
- if (errno || *end || flush_interval > INT_MAX) {
+ unsigned long res;
+
+ if (qemu_strtoul(optarg, NULL, 0, &res) < 0 || res > INT_MAX) {
error_report("Invalid flush interval specified");
return 1;
}
+ flush_interval = res;
break;
}
case OPTION_NO_DRAIN:
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 95bcde1d88..e415b03cd0 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -388,9 +388,15 @@ create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov,
goto fail;
}
- if (len > SIZE_MAX) {
- printf("Argument '%s' exceeds maximum size %llu\n", arg,
- (unsigned long long)SIZE_MAX);
+ if (len > BDRV_REQUEST_MAX_BYTES) {
+ printf("Argument '%s' exceeds maximum size %" PRIu64 "\n", arg,
+ (uint64_t)BDRV_REQUEST_MAX_BYTES);
+ goto fail;
+ }
+
+ if (count > BDRV_REQUEST_MAX_BYTES - len) {
+ printf("The total number of bytes exceed the maximum size %" PRIu64
+ "\n", (uint64_t)BDRV_REQUEST_MAX_BYTES);
goto fail;
}
@@ -682,9 +688,9 @@ static int read_f(BlockBackend *blk, int argc, char **argv)
if (count < 0) {
print_cvtnum_err(count, argv[optind]);
return 0;
- } else if (count > SIZE_MAX) {
+ } else if (count > BDRV_REQUEST_MAX_BYTES) {
printf("length cannot exceed %" PRIu64 ", given %s\n",
- (uint64_t) SIZE_MAX, argv[optind]);
+ (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
return 0;
}
@@ -1004,9 +1010,9 @@ static int write_f(BlockBackend *blk, int argc, char **argv)
if (count < 0) {
print_cvtnum_err(count, argv[optind]);
return 0;
- } else if (count > SIZE_MAX) {
+ } else if (count > BDRV_REQUEST_MAX_BYTES) {
printf("length cannot exceed %" PRIu64 ", given %s\n",
- (uint64_t) SIZE_MAX, argv[optind]);
+ (uint64_t)BDRV_REQUEST_MAX_BYTES, argv[optind]);
return 0;
}
diff --git a/qemu-io.c b/qemu-io.c
index 23a229f880..427cbaef57 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -595,13 +595,17 @@ int main(int argc, char **argv)
exit(1);
}
opts = qemu_opts_to_qdict(qopts, NULL);
- openfile(NULL, flags, writethrough, opts);
+ if (openfile(NULL, flags, writethrough, opts)) {
+ exit(1);
+ }
} else {
if (format) {
opts = qdict_new();
qdict_put(opts, "driver", qstring_from_str(format));
}
- openfile(argv[optind], flags, writethrough, opts);
+ if (openfile(argv[optind], flags, writethrough, opts)) {
+ exit(1);
+ }
}
}
command_loop();
diff --git a/tests/qemu-iotests/.gitignore b/tests/qemu-iotests/.gitignore
index 0711cbdbf3..da62054000 100644
--- a/tests/qemu-iotests/.gitignore
+++ b/tests/qemu-iotests/.gitignore
@@ -1,5 +1,5 @@
check.log
-check.time
+check.time*
common.env
*.out.bad
*.notrun
diff --git a/tests/qemu-iotests/059.out b/tests/qemu-iotests/059.out
index 678adb4379..6154509bc3 100644
--- a/tests/qemu-iotests/059.out
+++ b/tests/qemu-iotests/059.out
@@ -3,17 +3,14 @@ QA output created by 059
=== Testing invalid granularity ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.vmdk: Invalid granularity, image may be corrupt
-no file open, try 'help open'
=== Testing too big L2 table size ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.vmdk: L2 table size too big
-no file open, try 'help open'
=== Testing too big L1 table size ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.vmdk: L1 size too big
-no file open, try 'help open'
=== Testing monolithicFlat creation and opening ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2147483648 subformat=monolithicFlat
@@ -2361,5 +2358,5 @@ Offset Length Mapped to File
0x140000000 0x10000 0x50000 TEST_DIR/iotest-version3-s003.vmdk
=== Testing afl image with a very large capacity ===
-qemu-img: Can't get size of device 'image': File too large
+qemu-img: Can't get image size 'TEST_DIR/afl9.IMGFMT': File too large
*** done
diff --git a/tests/qemu-iotests/070.out b/tests/qemu-iotests/070.out
index 131a5b17dc..c269d99483 100644
--- a/tests/qemu-iotests/070.out
+++ b/tests/qemu-iotests/070.out
@@ -4,7 +4,6 @@ QA output created by 070
can't open device TEST_DIR/iotest-dirtylog-10G-4M.vhdx: VHDX image file 'TEST_DIR/iotest-dirtylog-10G-4M.vhdx' opened read-only, but contains a log that needs to be replayed
To replay the log, run:
qemu-img check -r all 'TEST_DIR/iotest-dirtylog-10G-4M.vhdx'
- no file open, try 'help open'
=== Verify open image replays log ===
read 18874368/18874368 bytes at offset 0
18 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
diff --git a/tests/qemu-iotests/075.out b/tests/qemu-iotests/075.out
index 87beae4e3c..b234b758e0 100644
--- a/tests/qemu-iotests/075.out
+++ b/tests/qemu-iotests/075.out
@@ -10,29 +10,22 @@ read 512/512 bytes at offset 1048064
== block_size must be a multiple of 512 ==
can't open device TEST_DIR/simple-pattern.cloop: block_size 513 must be a multiple of 512
-no file open, try 'help open'
== block_size cannot be zero ==
can't open device TEST_DIR/simple-pattern.cloop: block_size cannot be zero
-no file open, try 'help open'
== huge block_size ===
can't open device TEST_DIR/simple-pattern.cloop: block_size 4294966784 must be 64 MB or less
-no file open, try 'help open'
== offsets_size overflow ===
can't open device TEST_DIR/simple-pattern.cloop: n_blocks 4294967295 must be 536870911 or less
-no file open, try 'help open'
== refuse images that require too many offsets ===
can't open device TEST_DIR/simple-pattern.cloop: image requires too many offsets, try increasing block size
-no file open, try 'help open'
== refuse images with non-monotonically increasing offsets ==
can't open device TEST_DIR/simple-pattern.cloop: offsets not monotonically increasing at index 1, image file is corrupt
-no file open, try 'help open'
== refuse images with invalid compressed block size ==
can't open device TEST_DIR/simple-pattern.cloop: invalid compressed block size at index 1, image file is corrupt
-no file open, try 'help open'
*** done
diff --git a/tests/qemu-iotests/076.out b/tests/qemu-iotests/076.out
index 72645b2522..9c66c5fb46 100644
--- a/tests/qemu-iotests/076.out
+++ b/tests/qemu-iotests/076.out
@@ -6,15 +6,12 @@ read 65536/65536 bytes at offset 0
== Negative catalog size ==
can't open device TEST_DIR/parallels-v1: Catalog too large
-no file open, try 'help open'
== Overflow in catalog allocation ==
can't open device TEST_DIR/parallels-v1: Catalog too large
-no file open, try 'help open'
== Zero sectors per track ==
can't open device TEST_DIR/parallels-v1: Invalid image: Zero sectors per track
-no file open, try 'help open'
== Read from a valid v2 image ==
read 65536/65536 bytes at offset 0
diff --git a/tests/qemu-iotests/078.out b/tests/qemu-iotests/078.out
index 42b8a83015..c3d6aa4fe4 100644
--- a/tests/qemu-iotests/078.out
+++ b/tests/qemu-iotests/078.out
@@ -6,23 +6,17 @@ read 512/512 bytes at offset 0
== Negative catalog size ==
can't open device TEST_DIR/empty.bochs: Catalog size is too large
-no file open, try 'help open'
== Overflow for catalog size * sizeof(uint32_t) ==
can't open device TEST_DIR/empty.bochs: Catalog size is too large
-no file open, try 'help open'
== Too small catalog bitmap for image size ==
can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size
-no file open, try 'help open'
can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size
-no file open, try 'help open'
== Negative extent size ==
can't open device TEST_DIR/empty.bochs: Extent size 2147483648 is too large
-no file open, try 'help open'
== Zero extent size ==
can't open device TEST_DIR/empty.bochs: Extent size must be at least 512
-no file open, try 'help open'
*** done
diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out
index 0daac48b12..6a7fda1356 100644
--- a/tests/qemu-iotests/080.out
+++ b/tests/qemu-iotests/080.out
@@ -3,46 +3,33 @@ QA output created by 080
== Huge header size ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow2: qcow2 header exceeds cluster size
-no file open, try 'help open'
== Huge unknown header extension ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.qcow2: Invalid backing file offset
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow2: Header extension too large
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow2: Header extension too large
-no file open, try 'help open'
== Huge refcount table size ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.qcow2: Reference count table too large
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow2: Reference count table too large
-no file open, try 'help open'
== Misaligned refcount table ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.qcow2: Invalid reference count table offset
-no file open, try 'help open'
== Huge refcount offset ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.qcow2: Invalid reference count table offset
-no file open, try 'help open'
== Invalid snapshot table ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.qcow2: Too many snapshots
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow2: Too many snapshots
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow2: Invalid snapshot table offset
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow2: Invalid snapshot table offset
-no file open, try 'help open'
== Hitting snapshot table size limit ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
@@ -53,13 +40,9 @@ read 512/512 bytes at offset 0
== Invalid L1 table ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.qcow2: Active L1 table too large
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow2: Active L1 table too large
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow2: Invalid L1 table offset
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow2: Invalid L1 table offset
-no file open, try 'help open'
== Invalid L1 table (with internal snapshot in the image) ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
@@ -68,7 +51,6 @@ qemu-img: Could not open 'TEST_DIR/t.IMGFMT': L1 table is too small
== Invalid backing file size ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.qcow2: Backing file name too long
-no file open, try 'help open'
== Invalid L2 entry (huge physical offset) ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
diff --git a/tests/qemu-iotests/083.out b/tests/qemu-iotests/083.out
index ef3d1e32a5..0c13888ba1 100644
--- a/tests/qemu-iotests/083.out
+++ b/tests/qemu-iotests/083.out
@@ -2,52 +2,42 @@ QA output created by 083
=== Check disconnect before neg1 ===
can't open device nbd:127.0.0.1:PORT:exportname=foo
-no file open, try 'help open'
=== Check disconnect after neg1 ===
can't open device nbd:127.0.0.1:PORT:exportname=foo
-no file open, try 'help open'
=== Check disconnect 8 neg1 ===
can't open device nbd:127.0.0.1:PORT:exportname=foo
-no file open, try 'help open'
=== Check disconnect 16 neg1 ===
can't open device nbd:127.0.0.1:PORT:exportname=foo
-no file open, try 'help open'
=== Check disconnect before export ===
can't open device nbd:127.0.0.1:PORT:exportname=foo
-no file open, try 'help open'
=== Check disconnect after export ===
can't open device nbd:127.0.0.1:PORT:exportname=foo
-no file open, try 'help open'
=== Check disconnect 4 export ===
can't open device nbd:127.0.0.1:PORT:exportname=foo
-no file open, try 'help open'
=== Check disconnect 12 export ===
can't open device nbd:127.0.0.1:PORT:exportname=foo
-no file open, try 'help open'
=== Check disconnect 16 export ===
can't open device nbd:127.0.0.1:PORT:exportname=foo
-no file open, try 'help open'
=== Check disconnect before neg2 ===
can't open device nbd:127.0.0.1:PORT:exportname=foo
-no file open, try 'help open'
=== Check disconnect after neg2 ===
@@ -56,12 +46,10 @@ read failed: Input/output error
=== Check disconnect 8 neg2 ===
can't open device nbd:127.0.0.1:PORT:exportname=foo
-no file open, try 'help open'
=== Check disconnect 10 neg2 ===
can't open device nbd:127.0.0.1:PORT:exportname=foo
-no file open, try 'help open'
=== Check disconnect before request ===
@@ -99,27 +87,22 @@ read 512/512 bytes at offset 0
=== Check disconnect before neg-classic ===
can't open device nbd:127.0.0.1:PORT
-no file open, try 'help open'
=== Check disconnect 8 neg-classic ===
can't open device nbd:127.0.0.1:PORT
-no file open, try 'help open'
=== Check disconnect 16 neg-classic ===
can't open device nbd:127.0.0.1:PORT
-no file open, try 'help open'
=== Check disconnect 24 neg-classic ===
can't open device nbd:127.0.0.1:PORT
-no file open, try 'help open'
=== Check disconnect 28 neg-classic ===
can't open device nbd:127.0.0.1:PORT
-no file open, try 'help open'
=== Check disconnect after neg-classic ===
diff --git a/tests/qemu-iotests/088.out b/tests/qemu-iotests/088.out
index a2a83b8a1c..1f6bcf0abc 100644
--- a/tests/qemu-iotests/088.out
+++ b/tests/qemu-iotests/088.out
@@ -3,15 +3,9 @@ QA output created by 088
== Invalid block size ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.vpc: Invalid block size 0
-no file open, try 'help open'
can't open device TEST_DIR/t.vpc: Invalid block size 0
-no file open, try 'help open'
can't open device TEST_DIR/t.vpc: Invalid block size 128
-no file open, try 'help open'
can't open device TEST_DIR/t.vpc: Invalid block size 128
-no file open, try 'help open'
can't open device TEST_DIR/t.vpc: Invalid block size 305419896
-no file open, try 'help open'
can't open device TEST_DIR/t.vpc: Invalid block size 305419896
-no file open, try 'help open'
*** done
diff --git a/tests/qemu-iotests/092.out b/tests/qemu-iotests/092.out
index e18f54c200..6eda321fc6 100644
--- a/tests/qemu-iotests/092.out
+++ b/tests/qemu-iotests/092.out
@@ -3,36 +3,24 @@ QA output created by 092
== Invalid cluster size ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.qcow: Cluster size must be between 512 and 64k
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow: Cluster size must be between 512 and 64k
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow: Cluster size must be between 512 and 64k
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow: Cluster size must be between 512 and 64k
-no file open, try 'help open'
== Invalid L2 table size ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.qcow: L2 table size must be between 512 and 64k
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow: L2 table size must be between 512 and 64k
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow: L2 table size must be between 512 and 64k
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow: L2 table size must be between 512 and 64k
-no file open, try 'help open'
== Invalid size ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.qcow: Image too large
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow: Image too large
-no file open, try 'help open'
== Invalid backing file length ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
can't open device TEST_DIR/t.qcow: Backing file name too long
-no file open, try 'help open'
can't open device TEST_DIR/t.qcow: Backing file name too long
-no file open, try 'help open'
*** done
diff --git a/tests/qemu-iotests/116.out b/tests/qemu-iotests/116.out
index 1f11d4446d..24bee57783 100644
--- a/tests/qemu-iotests/116.out
+++ b/tests/qemu-iotests/116.out
@@ -3,35 +3,28 @@ QA output created by 116
== truncated header cluster ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
-no file open, try 'help open'
== invalid header magic ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
can't open device TEST_DIR/t.qed: Image not in QED format
-no file open, try 'help open'
== invalid cluster size ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
-no file open, try 'help open'
== invalid table size ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
-no file open, try 'help open'
== invalid header size ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
-no file open, try 'help open'
== invalid L1 table offset ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
-no file open, try 'help open'
== invalid image size ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
can't open device TEST_DIR/t.qed: Could not open 'TEST_DIR/t.qed': Invalid argument
-no file open, try 'help open'
*** done
diff --git a/tests/qemu-iotests/131.out b/tests/qemu-iotests/131.out
index ae2412ebf7..27c2c5389b 100644
--- a/tests/qemu-iotests/131.out
+++ b/tests/qemu-iotests/131.out
@@ -23,7 +23,6 @@ read 32768/32768 bytes at offset 0
32 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== Corrupt image ==
can't open device TEST_DIR/t.parallels: parallels: Image was not closed correctly; cannot be opened read/write
-no file open, try 'help open'
ERROR image was not closed correctly
1 errors were found on the image.
diff --git a/tests/qemu-iotests/140.out b/tests/qemu-iotests/140.out
index 0409cd0174..6c0445603a 100644
--- a/tests/qemu-iotests/140.out
+++ b/tests/qemu-iotests/140.out
@@ -9,7 +9,6 @@ read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
can't open device nbd+unix:///drv?socket=TEST_DIR/nbd: No export with name 'drv' available
-no file open, try 'help open'
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
*** done
diff --git a/tests/qemu-iotests/173 b/tests/qemu-iotests/173
new file mode 100755
index 0000000000..bdaa092979
--- /dev/null
+++ b/tests/qemu-iotests/173
@@ -0,0 +1,97 @@
+#!/bin/bash
+#
+# Test QAPI commands looking up protocol based images with relative
+# filename backing strings
+#
+# 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=jcody@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_qemu
+ rm -f "${QEMU_TEST_DIR}/image.base" "${QEMU_TEST_DIR}/image.snp1"
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+. ./common.qemu
+
+_supported_fmt qcow2
+_supported_proto nfs
+_supported_os Linux
+
+size=100M
+
+BASE_IMG="${TEST_DIR}/image.base"
+TOP_IMG="${TEST_DIR}/image.snp1"
+
+TEST_IMG="${BASE_IMG}" _make_test_img $size
+
+TEST_IMG="${TOP_IMG}" _make_test_img $size
+
+echo
+echo === Running QEMU, using block-stream to find backing image ===
+echo
+
+qemu_comm_method="qmp"
+_launch_qemu -drive file="${BASE_IMG}",if=virtio,id=disk2
+h=$QEMU_HANDLE
+
+_send_qemu_cmd $h "{ 'execute': 'qmp_capabilities' }" "return"
+
+_send_qemu_cmd $h "{ 'arguments': {
+ 'device': 'disk2',
+ 'format': '${IMGFMT}',
+ 'mode': 'existing',
+ 'snapshot-file': '${TOP_IMG}',
+ 'snapshot-node-name': 'snp1'
+ },
+ 'execute': 'blockdev-snapshot-sync'
+ }" "return"
+
+
+_send_qemu_cmd $h "{ 'arguments': {
+ 'backing-file': 'image.base',
+ 'device': 'disk2',
+ 'image-node-name': 'snp1'
+ },
+ 'execute': 'change-backing-file'
+ }" "return"
+
+_send_qemu_cmd $h "{ 'arguments': {
+ 'base': '${BASE_IMG}',
+ 'device': 'disk2'
+ },
+ 'execute': 'block-stream'
+ }" "BLOCK_JOB_COMPLETED"
+
+_cleanup_qemu
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/173.out b/tests/qemu-iotests/173.out
new file mode 100644
index 0000000000..f477a0099a
--- /dev/null
+++ b/tests/qemu-iotests/173.out
@@ -0,0 +1,12 @@
+QA output created by 173
+Formatting 'TEST_DIR/image.base', fmt=IMGFMT size=104857600
+Formatting 'TEST_DIR/image.snp1', fmt=IMGFMT size=104857600
+
+=== Running QEMU, using block-stream to find backing image ===
+
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"return": {}}
+{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "disk2", "len": 104857600, "offset": 104857600, "speed": 0, "type": "stream"}}
+*** done
diff --git a/tests/qemu-iotests/174 b/tests/qemu-iotests/174
new file mode 100755
index 0000000000..c1c20a1a57
--- /dev/null
+++ b/tests/qemu-iotests/174
@@ -0,0 +1,59 @@
+#!/bin/bash
+#
+# Test that qemu-io fail with non-zero exit code
+#
+# Copyright (C) 2017 Nir Soffer <nirsof@gmail.com>
+#
+# 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=nirsof@gmail.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_unsupported_fmt raw
+
+
+size=256K
+IMGFMT=raw IMGOPTS= _make_test_img $size | _filter_imgfmt
+
+echo
+echo "== reading wrong format should fail =="
+$QEMU_IO -f $IMGFMT -c "read 0 $size" "$TEST_IMG" 2>/dev/null
+test $? -eq 1 || _fail "did not fail"
+
+echo
+echo "== reading missing file should fail =="
+$QEMU_IO -c "read 0 $size" "$TEST_DIR/missing" 2>/dev/null
+test $? -eq 1 || _fail "did not fail"
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/174.out b/tests/qemu-iotests/174.out
new file mode 100644
index 0000000000..a06d23792e
--- /dev/null
+++ b/tests/qemu-iotests/174.out
@@ -0,0 +1,7 @@
+QA output created by 174
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=262144
+
+== reading wrong format should fail ==
+
+== reading missing file should fail ==
+*** done
diff --git a/tests/qemu-iotests/Makefile b/tests/qemu-iotests/Makefile
index 2fb527c5b5..27380e60c1 100644
--- a/tests/qemu-iotests/Makefile
+++ b/tests/qemu-iotests/Makefile
@@ -1,5 +1,5 @@
-CLEANFILES= *.out.bad *.notrun check.log check.time
+CLEANFILES= *.out.bad *.notrun check.log check.time*
# no default target
default:
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index 4cba2151e4..4b1c6749b7 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -129,6 +129,8 @@ fi
# exit 1
#fi
+TIMESTAMP_FILE=check.time-$IMGPROTO-$IMGFMT
+
tmp="${TEST_DIR}"/$$
_wallclock()
@@ -155,9 +157,9 @@ _wrapup()
:
elif $needwrap
then
- if [ -f check.time -a -f $tmp.time ]
+ if [ -f $TIMESTAMP_FILE -a -f $tmp.time ]
then
- cat check.time $tmp.time \
+ cat $TIMESTAMP_FILE $tmp.time \
| $AWK_PROG '
{ t[$1] = $2 }
END { if (NR > 0) {
@@ -165,7 +167,7 @@ END { if (NR > 0) {
}
}' \
| sort -n >$tmp.out
- mv $tmp.out check.time
+ mv $tmp.out $TIMESTAMP_FILE
fi
if [ -f $tmp.expunged ]
@@ -223,7 +225,7 @@ echo "preamble" > "${TEST_DIR}"/check.sts
# don't leave old full output behind on a clean run
rm -f check.full
-[ -f check.time ] || touch check.time
+[ -f $TIMESTAMP_FILE ] || touch $TIMESTAMP_FILE
FULL_IMGFMT_DETAILS=`_full_imgfmt_details`
FULL_IMGPROTO_DETAILS=`_full_imgproto_details`
@@ -277,7 +279,7 @@ do
# really going to try and run this one
#
rm -f $seq.out.bad
- lasttime=`sed -n -e "/^$seq /s/.* //p" <check.time`
+ lasttime=`sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE`
if [ "X$lasttime" != X ]; then
echo -n " ${lasttime}s ..."
else
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
index f6384fbae7..55527aac87 100644
--- a/tests/qemu-iotests/common.config
+++ b/tests/qemu-iotests/common.config
@@ -109,7 +109,7 @@ _qemu_wrapper()
{
(
if [ -n "${QEMU_NEED_PID}" ]; then
- echo $BASHPID > "${TEST_DIR}/qemu-${_QEMU_HANDLE}.pid"
+ echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid"
fi
exec "$QEMU_PROG" $QEMU_OPTIONS "$@"
)
@@ -151,7 +151,7 @@ _qemu_io_wrapper()
_qemu_nbd_wrapper()
{
(
- echo $BASHPID > "${TEST_DIR}/qemu-nbd.pid"
+ echo $BASHPID > "${QEMU_TEST_DIR}/qemu-nbd.pid"
exec "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS "$@"
)
}
@@ -186,6 +186,8 @@ if [ -z "$TEST_DIR" ]; then
TEST_DIR=`pwd`/scratch
fi
+QEMU_TEST_DIR="${TEST_DIR}"
+
if [ ! -e "$TEST_DIR" ]; then
mkdir "$TEST_DIR"
fi
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 240ed0697a..4befd865f4 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -35,7 +35,7 @@ _filter_generated_node_ids()
# replace occurrences of the actual TEST_DIR value with TEST_DIR
_filter_testdir()
{
- sed -e "s#$TEST_DIR#TEST_DIR#g"
+ sed -e "s#$TEST_DIR/#TEST_DIR/#g"
}
# replace occurrences of the actual IMGFMT value with IMGFMT
diff --git a/tests/qemu-iotests/common.qemu b/tests/qemu-iotests/common.qemu
index e657361790..42787896af 100644
--- a/tests/qemu-iotests/common.qemu
+++ b/tests/qemu-iotests/common.qemu
@@ -27,8 +27,8 @@
QEMU_COMM_TIMEOUT=10
-QEMU_FIFO_IN="${TEST_DIR}/qmp-in-$$"
-QEMU_FIFO_OUT="${TEST_DIR}/qmp-out-$$"
+QEMU_FIFO_IN="${QEMU_TEST_DIR}/qmp-in-$$"
+QEMU_FIFO_OUT="${QEMU_TEST_DIR}/qmp-out-$$"
QEMU_HANDLE=0
@@ -204,9 +204,9 @@ function _cleanup_qemu()
for i in "${!QEMU_OUT[@]}"
do
local QEMU_PID
- if [ -f "${TEST_DIR}/qemu-${i}.pid" ]; then
- read QEMU_PID < "${TEST_DIR}/qemu-${i}.pid"
- rm -f "${TEST_DIR}/qemu-${i}.pid"
+ if [ -f "${QEMU_TEST_DIR}/qemu-${i}.pid" ]; then
+ read QEMU_PID < "${QEMU_TEST_DIR}/qemu-${i}.pid"
+ rm -f "${QEMU_TEST_DIR}/qemu-${i}.pid"
if [ -z "${wait}" ] && [ -n "${QEMU_PID}" ]; then
kill -KILL ${QEMU_PID} 2>/dev/null
fi
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 3213765f4e..a3d904fc22 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -193,11 +193,11 @@ _cleanup_test_img()
case "$IMGPROTO" in
nbd)
- if [ -f "${TEST_DIR}/qemu-nbd.pid" ]; then
+ if [ -f "${QEMU_TEST_DIR}/qemu-nbd.pid" ]; then
local QEMU_NBD_PID
- read QEMU_NBD_PID < "${TEST_DIR}/qemu-nbd.pid"
+ read QEMU_NBD_PID < "${QEMU_TEST_DIR}/qemu-nbd.pid"
kill ${QEMU_NBD_PID}
- rm -f "${TEST_DIR}/qemu-nbd.pid"
+ rm -f "${QEMU_TEST_DIR}/qemu-nbd.pid"
fi
rm -f "$TEST_IMG_FILE"
;;
@@ -355,6 +355,17 @@ _supported_fmt()
_notrun "not suitable for this image format: $IMGFMT"
}
+# tests whether $IMGFMT is one of the unsupported image format for a test
+#
+_unsupported_fmt()
+{
+ for f; do
+ if [ "$f" = "$IMGFMT" ]; then
+ _notrun "not suitable for this image format: $IMGFMT"
+ fi
+ done
+}
+
# tests whether $IMGPROTO is one of the supported image protocols for a test
#
_supported_proto()
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 866c1a032d..985b9a6a36 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -165,3 +165,5 @@
170 rw auto quick
171 rw auto quick
172 auto
+173 rw auto
+174 auto