mirror of
https://github.com/xemu-project/xemu.git
synced 2025-02-17 18:48:36 +00:00
Block patches
-----BEGIN PGP SIGNATURE----- iQFGBAABCAAwFiEEkb62CjDbPohX0Rgp9AfbAGHVz0AFAlifubwSHG1yZWl0ekBy ZWRoYXQuY29tAAoJEPQH2wBh1c9ASDEH+gLn/7Xm29Lex3SZFzuTQx+/mmXB756M q/lsV7q4f18QH7pMdf02LPlPnPcbmYZnGcm65ezGzZ1y0e3+jAdzF98gLfPYmXxZ qZREgOH+zmH/IEx1Iq62I3BNYvi0zk/z/PoHNtm+1rrl3oTx1GgYgj5dDYXA8gHl IYWHLexUqQtEbUplqMSOviALuoMscIvAsFsPImhl8Mq4d4ft3RuNJdCqW+K5AkqK i0mQTnuuTCcnBhNMr+kYFGAAsABVsb+apcj7Tsq2phazLv+K5h8zzJrtci02E2M2 CwOo3N/aNkw/Yizdzv1mslYNJb9dYcx6aRiJp+Xcuy1qV0LXEmCZxYs= =qWhR -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
0b4384d0bb
24
block.c
24
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);
|
||||
|
49
block/nfs.c
49
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));
|
||||
|
97
block/qapi.c
97
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;
|
||||
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);
|
||||
|
||||
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);
|
||||
aio_context_acquire(ctx);
|
||||
info->value = bdrv_query_bds_stats(bs, false);
|
||||
aio_context_release(ctx);
|
||||
|
||||
aio_context_acquire(ctx);
|
||||
info->value = bdrv_query_stats(blk, bs, !query_nodes);
|
||||
aio_context_release(ctx);
|
||||
*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;
|
||||
|
||||
*p_next = info;
|
||||
p_next = &info->next;
|
||||
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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
44
qemu-img.c
44
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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
2
tests/qemu-iotests/.gitignore
vendored
2
tests/qemu-iotests/.gitignore
vendored
@ -1,5 +1,5 @@
|
||||
check.log
|
||||
check.time
|
||||
check.time*
|
||||
common.env
|
||||
*.out.bad
|
||||
*.notrun
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 ===
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
97
tests/qemu-iotests/173
Executable file
97
tests/qemu-iotests/173
Executable file
@ -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
|
12
tests/qemu-iotests/173.out
Normal file
12
tests/qemu-iotests/173.out
Normal file
@ -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
|
59
tests/qemu-iotests/174
Executable file
59
tests/qemu-iotests/174
Executable file
@ -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
|
7
tests/qemu-iotests/174.out
Normal file
7
tests/qemu-iotests/174.out
Normal file
@ -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
|
@ -1,5 +1,5 @@
|
||||
|
||||
CLEANFILES= *.out.bad *.notrun check.log check.time
|
||||
CLEANFILES= *.out.bad *.notrun check.log check.time*
|
||||
|
||||
# no default target
|
||||
default:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -165,3 +165,5 @@
|
||||
170 rw auto quick
|
||||
171 rw auto quick
|
||||
172 auto
|
||||
173 rw auto
|
||||
174 auto
|
||||
|
Loading…
x
Reference in New Issue
Block a user