Block patches for 2.3

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJUiBMJAAoJEH8JsnLIjy/Wc38P/0V+g9OEY0zl0ZtV/HcWcJuE
 NPKfwov5y0HBJchuBYLCeesOr7PqTa78sHAMO1W8ST8p8S9Nq5cspomfOlFRrO5w
 E8Tgzhc8cd8BBzqgALKy8tm7aV7+YK9OsJ8ycTRJ8DvxZpkqoPehX68yKZes7WEe
 7FyTsije7mIbesPttO+sE05dm6sB1k/xsDGLt8AkP2CWkKwGtXUnPBB2KrDhE0lC
 EWZZ/VHWrZQcL+utf6Ca8gh1KwVVCtqgJ8T10Fhmr0EBH3R61FDnW2MB5HQ11bGN
 iblZZ0i98mmInMmGj/X8jAgdSJybPr01C0iZkPUJP3YIV/ZK+uM5QXJtTC2AOosM
 pawf9vF3yNRPyt5EcqwpvdrfH4js+UVTJJ5TbVLSjGIcSoi0V3AQ/cC3YXWvIDUm
 ZSvADjrJCg+r4UmXKxoybWiN34wbsGZukC8U4YWQROSJW0IC0T/+fORxFSgHbP9C
 9qKpek80sK002N92p42hVYAdNnvr7OYgpEMgBphS/DrclRSc1Wd92aXh5c6HGYO9
 p2YsLwa+vnyA2uZ/r1Kkr4a4tn+/P7vAID9YEx8oDhQbfXageUAVXSLBjJ4iGRhp
 J961rEpUEVpHIYV4vGSeq5ryHXbvtmiYNqpBnTZs/uaDSm7AMpFxN7EDI59UMarL
 zT+ScRhR7HAiDF2QaIuX
 =XM+2
 -----END PGP SIGNATURE-----

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

Block patches for 2.3

# gpg: Signature made Wed 10 Dec 2014 09:31:53 GMT using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream: (73 commits)
  vmdk: Set errp on failures in vmdk_open_vmdk4
  vmdk: Remove unnecessary initialization
  vmdk: Check descriptor file length when reading it
  vmdk: Clean up descriptor file reading
  vmdk: Fix comment to match code of extent lines
  vmdk: Use g_random_int to generate CID
  block: Use g_new0() for a bit of extra type checking
  block: remove BLOCK_OPT_NOCOW from vpc_create_opts
  block: remove BLOCK_OPT_NOCOW from vdi_create_opts
  qemu-iotests: Skip 099 for VMDK subformats with desc file
  block/raw-posix: Fix ret in raw_open_common()
  qcow2: Respect bdrv_truncate() error
  qcow2: Flushing the caches in qcow2_close may fail
  qcow2: Prevent numerical overflow
  iotests: Add test for unsupported image creation
  iotests: Only kill NBD server if it runs
  qemu-img: Check create_opts before image amendment
  qemu-img: Check create_opts before image creation
  block: Check create_opts before image creation
  block/nfs: Add create_opts
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-12-11 12:36:32 +00:00
commit 7c3843332d
93 changed files with 2363 additions and 554 deletions

View File

@ -73,7 +73,7 @@ void aio_set_fd_handler(AioContext *ctx,
} else { } else {
if (node == NULL) { if (node == NULL) {
/* Alloc and insert if it's not already there */ /* Alloc and insert if it's not already there */
node = g_malloc0(sizeof(AioHandler)); node = g_new0(AioHandler, 1);
node->pfd.fd = fd; node->pfd.fd = fd;
QLIST_INSERT_HEAD(&ctx->aio_handlers, node, node); QLIST_INSERT_HEAD(&ctx->aio_handlers, node, node);

View File

@ -67,7 +67,7 @@ void aio_set_fd_handler(AioContext *ctx,
if (node == NULL) { if (node == NULL) {
/* Alloc and insert if it's not already there */ /* Alloc and insert if it's not already there */
node = g_malloc0(sizeof(AioHandler)); node = g_new0(AioHandler, 1);
node->pfd.fd = fd; node->pfd.fd = fd;
QLIST_INSERT_HEAD(&ctx->aio_handlers, node, node); QLIST_INSERT_HEAD(&ctx->aio_handlers, node, node);
} }
@ -129,7 +129,7 @@ void aio_set_event_notifier(AioContext *ctx,
} else { } else {
if (node == NULL) { if (node == NULL) {
/* Alloc and insert if it's not already there */ /* Alloc and insert if it's not already there */
node = g_malloc0(sizeof(AioHandler)); node = g_new0(AioHandler, 1);
node->e = e; node->e = e;
node->pfd.fd = (uintptr_t)event_notifier_get_handle(e); node->pfd.fd = (uintptr_t)event_notifier_get_handle(e);
node->pfd.events = G_IO_IN; node->pfd.events = G_IO_IN;

View File

@ -44,7 +44,7 @@ struct QEMUBH {
QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque) QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
{ {
QEMUBH *bh; QEMUBH *bh;
bh = g_malloc0(sizeof(QEMUBH)); bh = g_new0(QEMUBH, 1);
bh->ctx = ctx; bh->ctx = ctx;
bh->cb = cb; bh->cb = cb;
bh->opaque = opaque; bh->opaque = opaque;

100
block.c
View File

@ -629,7 +629,7 @@ BlockDriver *bdrv_find_protocol(const char *filename,
} }
if (!path_has_protocol(filename) || !allow_protocol_prefix) { if (!path_has_protocol(filename) || !allow_protocol_prefix) {
return bdrv_find_format("file"); return &bdrv_file;
} }
p = strchr(filename, ':'); p = strchr(filename, ':');
@ -648,22 +648,49 @@ BlockDriver *bdrv_find_protocol(const char *filename,
return NULL; return NULL;
} }
/*
* Guess image format by probing its contents.
* This is not a good idea when your image is raw (CVE-2008-2004), but
* we do it anyway for backward compatibility.
*
* @buf contains the image's first @buf_size bytes.
* @buf_size is the buffer size in bytes (generally BLOCK_PROBE_BUF_SIZE,
* but can be smaller if the image file is smaller)
* @filename is its filename.
*
* For all block drivers, call the bdrv_probe() method to get its
* probing score.
* Return the first block driver with the highest probing score.
*/
BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
const char *filename)
{
int score_max = 0, score;
BlockDriver *drv = NULL, *d;
QLIST_FOREACH(d, &bdrv_drivers, list) {
if (d->bdrv_probe) {
score = d->bdrv_probe(buf, buf_size, filename);
if (score > score_max) {
score_max = score;
drv = d;
}
}
}
return drv;
}
static int find_image_format(BlockDriverState *bs, const char *filename, static int find_image_format(BlockDriverState *bs, const char *filename,
BlockDriver **pdrv, Error **errp) BlockDriver **pdrv, Error **errp)
{ {
int score, score_max; BlockDriver *drv;
BlockDriver *drv1, *drv; uint8_t buf[BLOCK_PROBE_BUF_SIZE];
uint8_t buf[2048];
int ret = 0; int ret = 0;
/* Return the raw BlockDriver * to scsi-generic devices or empty drives */ /* Return the raw BlockDriver * to scsi-generic devices or empty drives */
if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) { if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) {
drv = bdrv_find_format("raw"); *pdrv = &bdrv_raw;
if (!drv) {
error_setg(errp, "Could not find raw image format");
ret = -ENOENT;
}
*pdrv = drv;
return ret; return ret;
} }
@ -675,17 +702,7 @@ static int find_image_format(BlockDriverState *bs, const char *filename,
return ret; return ret;
} }
score_max = 0; drv = bdrv_probe_all(buf, ret, filename);
drv = NULL;
QLIST_FOREACH(drv1, &bdrv_drivers, list) {
if (drv1->bdrv_probe) {
score = drv1->bdrv_probe(buf, ret, filename);
if (score > score_max) {
score_max = score;
drv = drv1;
}
}
}
if (!drv) { if (!drv) {
error_setg(errp, "Could not determine image format: No compatible " error_setg(errp, "Could not determine image format: No compatible "
"driver found"); "driver found");
@ -1180,7 +1197,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
{ {
char *backing_filename = g_malloc0(PATH_MAX); char *backing_filename = g_malloc0(PATH_MAX);
int ret = 0; int ret = 0;
BlockDriver *back_drv = NULL;
BlockDriverState *backing_hd; BlockDriverState *backing_hd;
Error *local_err = NULL; Error *local_err = NULL;
@ -1213,14 +1229,14 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
backing_hd = bdrv_new(); backing_hd = bdrv_new();
if (bs->backing_format[0] != '\0') { if (bs->backing_format[0] != '\0' && !qdict_haskey(options, "driver")) {
back_drv = bdrv_find_format(bs->backing_format); qdict_put(options, "driver", qstring_from_str(bs->backing_format));
} }
assert(bs->backing_hd == NULL); assert(bs->backing_hd == NULL);
ret = bdrv_open(&backing_hd, ret = bdrv_open(&backing_hd,
*backing_filename ? backing_filename : NULL, NULL, options, *backing_filename ? backing_filename : NULL, NULL, options,
bdrv_backing_flags(bs->open_flags), back_drv, &local_err); bdrv_backing_flags(bs->open_flags), NULL, &local_err);
if (ret < 0) { if (ret < 0) {
bdrv_unref(backing_hd); bdrv_unref(backing_hd);
backing_hd = NULL; backing_hd = NULL;
@ -1294,7 +1310,6 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
/* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
char *tmp_filename = g_malloc0(PATH_MAX + 1); char *tmp_filename = g_malloc0(PATH_MAX + 1);
int64_t total_size; int64_t total_size;
BlockDriver *bdrv_qcow2;
QemuOpts *opts = NULL; QemuOpts *opts = NULL;
QDict *snapshot_options; QDict *snapshot_options;
BlockDriverState *bs_snapshot; BlockDriverState *bs_snapshot;
@ -1319,11 +1334,10 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
goto out; goto out;
} }
bdrv_qcow2 = bdrv_find_format("qcow2"); opts = qemu_opts_create(bdrv_qcow2.create_opts, NULL, 0,
opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0,
&error_abort); &error_abort);
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size); qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
ret = bdrv_create(bdrv_qcow2, tmp_filename, opts, &local_err); ret = bdrv_create(&bdrv_qcow2, tmp_filename, opts, &local_err);
qemu_opts_del(opts); qemu_opts_del(opts);
if (ret < 0) { if (ret < 0) {
error_setg_errno(errp, -ret, "Could not create temporary overlay " error_setg_errno(errp, -ret, "Could not create temporary overlay "
@ -1343,7 +1357,7 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
bs_snapshot = bdrv_new(); bs_snapshot = bdrv_new();
ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options, ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
flags, bdrv_qcow2, &local_err); flags, &bdrv_qcow2, &local_err);
if (ret < 0) { if (ret < 0) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto out; goto out;
@ -1467,6 +1481,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
} }
/* Image format probing */ /* Image format probing */
bs->probed = !drv;
if (!drv && file) { if (!drv && file) {
ret = find_image_format(file, filename, &drv, &local_err); ret = find_image_format(file, filename, &drv, &local_err);
if (ret < 0) { if (ret < 0) {
@ -3801,6 +3816,14 @@ bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base)
return top != NULL; return top != NULL;
} }
BlockDriverState *bdrv_next_node(BlockDriverState *bs)
{
if (!bs) {
return QTAILQ_FIRST(&graph_bdrv_states);
}
return QTAILQ_NEXT(bs, node_list);
}
BlockDriverState *bdrv_next(BlockDriverState *bs) BlockDriverState *bdrv_next(BlockDriverState *bs)
{ {
if (!bs) { if (!bs) {
@ -3809,6 +3832,11 @@ BlockDriverState *bdrv_next(BlockDriverState *bs)
return QTAILQ_NEXT(bs, device_list); return QTAILQ_NEXT(bs, device_list);
} }
const char *bdrv_get_node_name(const BlockDriverState *bs)
{
return bs->node_name;
}
/* TODO check what callers really want: bs->node_name or blk_name() */ /* TODO check what callers really want: bs->node_name or blk_name() */
const char *bdrv_get_device_name(const BlockDriverState *bs) const char *bdrv_get_device_name(const BlockDriverState *bs)
{ {
@ -5541,6 +5569,18 @@ void bdrv_img_create(const char *filename, const char *fmt,
return; return;
} }
if (!drv->create_opts) {
error_setg(errp, "Format driver '%s' does not support image creation",
drv->format_name);
return;
}
if (!proto_drv->create_opts) {
error_setg(errp, "Protocol driver '%s' does not support image creation",
proto_drv->format_name);
return;
}
create_opts = qemu_opts_append(create_opts, drv->create_opts); create_opts = qemu_opts_append(create_opts, drv->create_opts);
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts); create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);

View File

@ -24,6 +24,7 @@
#include "block/accounting.h" #include "block/accounting.h"
#include "block/block_int.h" #include "block/block_int.h"
#include "qemu/timer.h"
void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie, void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
int64_t bytes, enum BlockAcctType type) int64_t bytes, enum BlockAcctType type)
@ -31,7 +32,7 @@ void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
assert(type < BLOCK_MAX_IOTYPE); assert(type < BLOCK_MAX_IOTYPE);
cookie->bytes = bytes; cookie->bytes = bytes;
cookie->start_time_ns = get_clock(); cookie->start_time_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
cookie->type = type; cookie->type = type;
} }
@ -41,7 +42,8 @@ void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie)
stats->nr_bytes[cookie->type] += cookie->bytes; stats->nr_bytes[cookie->type] += cookie->bytes;
stats->nr_ops[cookie->type]++; stats->nr_ops[cookie->type]++;
stats->total_time_ns[cookie->type] += get_clock() - cookie->start_time_ns; stats->total_time_ns[cookie->type] +=
qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - cookie->start_time_ns;
} }

View File

@ -721,91 +721,48 @@ static int64_t blkdebug_getlength(BlockDriverState *bs)
static void blkdebug_refresh_filename(BlockDriverState *bs) static void blkdebug_refresh_filename(BlockDriverState *bs)
{ {
BDRVBlkdebugState *s = bs->opaque;
struct BlkdebugRule *rule;
QDict *opts; QDict *opts;
QList *inject_error_list = NULL, *set_state_list = NULL; const QDictEntry *e;
QList *suspend_list = NULL; bool force_json = false;
int event;
if (!bs->file->full_open_options) { for (e = qdict_first(bs->options); e; e = qdict_next(bs->options, e)) {
if (strcmp(qdict_entry_key(e), "config") &&
strcmp(qdict_entry_key(e), "x-image") &&
strcmp(qdict_entry_key(e), "image") &&
strncmp(qdict_entry_key(e), "image.", strlen("image.")))
{
force_json = true;
break;
}
}
if (force_json && !bs->file->full_open_options) {
/* The config file cannot be recreated, so creating a plain filename /* The config file cannot be recreated, so creating a plain filename
* is impossible */ * is impossible */
return; return;
} }
if (!force_json && bs->file->exact_filename[0]) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename),
"blkdebug:%s:%s",
qdict_get_try_str(bs->options, "config") ?: "",
bs->file->exact_filename);
}
opts = qdict_new(); opts = qdict_new();
qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("blkdebug"))); qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("blkdebug")));
QINCREF(bs->file->full_open_options); QINCREF(bs->file->full_open_options);
qdict_put_obj(opts, "image", QOBJECT(bs->file->full_open_options)); qdict_put_obj(opts, "image", QOBJECT(bs->file->full_open_options));
for (event = 0; event < BLKDBG_EVENT_MAX; event++) { for (e = qdict_first(bs->options); e; e = qdict_next(bs->options, e)) {
QLIST_FOREACH(rule, &s->rules[event], next) { if (strcmp(qdict_entry_key(e), "x-image") &&
if (rule->action == ACTION_INJECT_ERROR) { strcmp(qdict_entry_key(e), "image") &&
QDict *inject_error = qdict_new(); strncmp(qdict_entry_key(e), "image.", strlen("image.")))
{
qdict_put_obj(inject_error, "event", QOBJECT(qstring_from_str( qobject_incref(qdict_entry_value(e));
BlkdebugEvent_lookup[rule->event]))); qdict_put_obj(opts, qdict_entry_key(e), qdict_entry_value(e));
qdict_put_obj(inject_error, "state",
QOBJECT(qint_from_int(rule->state)));
qdict_put_obj(inject_error, "errno", QOBJECT(qint_from_int(
rule->options.inject.error)));
qdict_put_obj(inject_error, "sector", QOBJECT(qint_from_int(
rule->options.inject.sector)));
qdict_put_obj(inject_error, "once", QOBJECT(qbool_from_int(
rule->options.inject.once)));
qdict_put_obj(inject_error, "immediately",
QOBJECT(qbool_from_int(
rule->options.inject.immediately)));
if (!inject_error_list) {
inject_error_list = qlist_new();
} }
qlist_append_obj(inject_error_list, QOBJECT(inject_error));
} else if (rule->action == ACTION_SET_STATE) {
QDict *set_state = qdict_new();
qdict_put_obj(set_state, "event", QOBJECT(qstring_from_str(
BlkdebugEvent_lookup[rule->event])));
qdict_put_obj(set_state, "state",
QOBJECT(qint_from_int(rule->state)));
qdict_put_obj(set_state, "new_state", QOBJECT(qint_from_int(
rule->options.set_state.new_state)));
if (!set_state_list) {
set_state_list = qlist_new();
}
qlist_append_obj(set_state_list, QOBJECT(set_state));
} else if (rule->action == ACTION_SUSPEND) {
QDict *suspend = qdict_new();
qdict_put_obj(suspend, "event", QOBJECT(qstring_from_str(
BlkdebugEvent_lookup[rule->event])));
qdict_put_obj(suspend, "state",
QOBJECT(qint_from_int(rule->state)));
qdict_put_obj(suspend, "tag", QOBJECT(qstring_from_str(
rule->options.suspend.tag)));
if (!suspend_list) {
suspend_list = qlist_new();
}
qlist_append_obj(suspend_list, QOBJECT(suspend));
}
}
}
if (inject_error_list) {
qdict_put_obj(opts, "inject-error", QOBJECT(inject_error_list));
}
if (set_state_list) {
qdict_put_obj(opts, "set-state", QOBJECT(set_state_list));
}
if (suspend_list) {
qdict_put_obj(opts, "suspend", QOBJECT(suspend_list));
} }
bs->full_open_options = opts; bs->full_open_options = opts;

View File

@ -497,6 +497,16 @@ BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
return bdrv_aio_ioctl(blk->bs, req, buf, cb, opaque); return bdrv_aio_ioctl(blk->bs, req, buf, cb, opaque);
} }
int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors)
{
return bdrv_co_discard(blk->bs, sector_num, nb_sectors);
}
int blk_co_flush(BlockBackend *blk)
{
return bdrv_co_flush(blk->bs);
}
int blk_flush(BlockBackend *blk) int blk_flush(BlockBackend *blk)
{ {
return bdrv_flush(blk->bs); return bdrv_flush(blk->bs);
@ -549,6 +559,11 @@ void blk_set_enable_write_cache(BlockBackend *blk, bool wce)
bdrv_set_enable_write_cache(blk->bs, wce); bdrv_set_enable_write_cache(blk->bs, wce);
} }
void blk_invalidate_cache(BlockBackend *blk, Error **errp)
{
bdrv_invalidate_cache(blk->bs, errp);
}
int blk_is_inserted(BlockBackend *blk) int blk_is_inserted(BlockBackend *blk)
{ {
return bdrv_is_inserted(blk->bs); return bdrv_is_inserted(blk->bs);
@ -609,6 +624,29 @@ void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
bdrv_set_aio_context(blk->bs, new_context); bdrv_set_aio_context(blk->bs, new_context);
} }
void blk_add_aio_context_notifier(BlockBackend *blk,
void (*attached_aio_context)(AioContext *new_context, void *opaque),
void (*detach_aio_context)(void *opaque), void *opaque)
{
bdrv_add_aio_context_notifier(blk->bs, attached_aio_context,
detach_aio_context, opaque);
}
void blk_remove_aio_context_notifier(BlockBackend *blk,
void (*attached_aio_context)(AioContext *,
void *),
void (*detach_aio_context)(void *),
void *opaque)
{
bdrv_remove_aio_context_notifier(blk->bs, attached_aio_context,
detach_aio_context, opaque);
}
void blk_add_close_notifier(BlockBackend *blk, Notifier *notify)
{
bdrv_add_close_notifier(blk->bs, notify);
}
void blk_io_plug(BlockBackend *blk) void blk_io_plug(BlockBackend *blk)
{ {
bdrv_io_plug(blk->bs); bdrv_io_plug(blk->bs);

View File

@ -409,6 +409,19 @@ out:
return ret; return ret;
} }
static QemuOptsList nfs_create_opts = {
.name = "nfs-create-opts",
.head = QTAILQ_HEAD_INITIALIZER(nfs_create_opts.head),
.desc = {
{
.name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE,
.help = "Virtual disk size"
},
{ /* end of list */ }
}
};
static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp) static int nfs_file_create(const char *url, QemuOpts *opts, Error **errp)
{ {
int ret = 0; int ret = 0;
@ -470,6 +483,8 @@ static BlockDriver bdrv_nfs = {
.instance_size = sizeof(NFSClient), .instance_size = sizeof(NFSClient),
.bdrv_needs_filename = true, .bdrv_needs_filename = true,
.create_opts = &nfs_create_opts,
.bdrv_has_zero_init = nfs_has_zero_init, .bdrv_has_zero_init = nfs_has_zero_init,
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size, .bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
.bdrv_truncate = nfs_file_truncate, .bdrv_truncate = nfs_file_truncate,

View File

@ -40,6 +40,13 @@ BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs)
info->encrypted = bs->encrypted; info->encrypted = bs->encrypted;
info->encryption_key_missing = bdrv_key_required(bs); info->encryption_key_missing = bdrv_key_required(bs);
info->cache = g_new(BlockdevCacheInfo, 1);
*info->cache = (BlockdevCacheInfo) {
.writeback = bdrv_enable_write_cache(bs),
.direct = !!(bs->open_flags & BDRV_O_NOCACHE),
.no_flush = !!(bs->open_flags & BDRV_O_NO_FLUSH),
};
if (bs->node_name[0]) { if (bs->node_name[0]) {
info->has_node_name = true; info->has_node_name = true;
info->node_name = g_strdup(bs->node_name); info->node_name = g_strdup(bs->node_name);
@ -300,7 +307,8 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
qapi_free_BlockInfo(info); qapi_free_BlockInfo(info);
} }
static BlockStats *bdrv_query_stats(const BlockDriverState *bs) static BlockStats *bdrv_query_stats(const BlockDriverState *bs,
bool query_backing)
{ {
BlockStats *s; BlockStats *s;
@ -311,6 +319,11 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *bs)
s->device = g_strdup(bdrv_get_device_name(bs)); s->device = g_strdup(bdrv_get_device_name(bs));
} }
if (bdrv_get_node_name(bs)[0]) {
s->has_node_name = true;
s->node_name = g_strdup(bdrv_get_node_name(bs));
}
s->stats = g_malloc0(sizeof(*s->stats)); s->stats = g_malloc0(sizeof(*s->stats));
s->stats->rd_bytes = bs->stats.nr_bytes[BLOCK_ACCT_READ]; s->stats->rd_bytes = bs->stats.nr_bytes[BLOCK_ACCT_READ];
s->stats->wr_bytes = bs->stats.nr_bytes[BLOCK_ACCT_WRITE]; s->stats->wr_bytes = bs->stats.nr_bytes[BLOCK_ACCT_WRITE];
@ -325,12 +338,12 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *bs)
if (bs->file) { if (bs->file) {
s->has_parent = true; s->has_parent = true;
s->parent = bdrv_query_stats(bs->file); s->parent = bdrv_query_stats(bs->file, query_backing);
} }
if (bs->backing_hd) { if (query_backing && bs->backing_hd) {
s->has_backing = true; s->has_backing = true;
s->backing = bdrv_query_stats(bs->backing_hd); s->backing = bdrv_query_stats(bs->backing_hd, query_backing);
} }
return s; return s;
@ -361,17 +374,22 @@ BlockInfoList *qmp_query_block(Error **errp)
return NULL; return NULL;
} }
BlockStatsList *qmp_query_blockstats(Error **errp) BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
bool query_nodes,
Error **errp)
{ {
BlockStatsList *head = NULL, **p_next = &head; BlockStatsList *head = NULL, **p_next = &head;
BlockDriverState *bs = NULL; BlockDriverState *bs = NULL;
while ((bs = bdrv_next(bs))) { /* Just to be safe if query_nodes is not always initialized */
query_nodes = has_query_nodes && query_nodes;
while ((bs = query_nodes ? bdrv_next_node(bs) : bdrv_next(bs))) {
BlockStatsList *info = g_malloc0(sizeof(*info)); BlockStatsList *info = g_malloc0(sizeof(*info));
AioContext *ctx = bdrv_get_aio_context(bs); AioContext *ctx = bdrv_get_aio_context(bs);
aio_context_acquire(ctx); aio_context_acquire(ctx);
info->value = bdrv_query_stats(bs); info->value = bdrv_query_stats(bs, !query_nodes);
aio_context_release(ctx); aio_context_release(ctx);
*p_next = info; *p_next = info;

View File

@ -1263,7 +1263,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
again: again:
start = offset; start = offset;
remaining = *num << BDRV_SECTOR_BITS; remaining = (uint64_t)*num << BDRV_SECTOR_BITS;
cluster_offset = 0; cluster_offset = 0;
*host_offset = 0; *host_offset = 0;
cur_bytes = 0; cur_bytes = 0;

View File

@ -117,7 +117,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
#ifdef DEBUG_EXT #ifdef DEBUG_EXT
printf("ext.magic = 0x%x\n", ext.magic); printf("ext.magic = 0x%x\n", ext.magic);
#endif #endif
if (ext.len > end_offset - offset) { if (offset > end_offset || ext.len > end_offset - offset) {
error_setg(errp, "Header extension too large"); error_setg(errp, "Header extension too large");
return -EINVAL; return -EINVAL;
} }
@ -1428,11 +1428,24 @@ static void qcow2_close(BlockDriverState *bs)
s->l1_table = NULL; s->l1_table = NULL;
if (!(bs->open_flags & BDRV_O_INCOMING)) { if (!(bs->open_flags & BDRV_O_INCOMING)) {
qcow2_cache_flush(bs, s->l2_table_cache); int ret1, ret2;
qcow2_cache_flush(bs, s->refcount_block_cache);
ret1 = qcow2_cache_flush(bs, s->l2_table_cache);
ret2 = qcow2_cache_flush(bs, s->refcount_block_cache);
if (ret1) {
error_report("Failed to flush the L2 table cache: %s",
strerror(-ret1));
}
if (ret2) {
error_report("Failed to flush the refcount block cache: %s",
strerror(-ret2));
}
if (!ret1 && !ret2) {
qcow2_mark_clean(bs); qcow2_mark_clean(bs);
} }
}
qcow2_cache_destroy(bs, s->l2_table_cache); qcow2_cache_destroy(bs, s->l2_table_cache);
qcow2_cache_destroy(bs, s->refcount_block_cache); qcow2_cache_destroy(bs, s->refcount_block_cache);
@ -1915,10 +1928,9 @@ static int qcow2_create2(const char *filename, int64_t total_size,
* refcount of the cluster that is occupied by the header and the refcount * refcount of the cluster that is occupied by the header and the refcount
* table) * table)
*/ */
BlockDriver* drv = bdrv_find_format("qcow2");
assert(drv != NULL);
ret = bdrv_open(&bs, filename, NULL, NULL, ret = bdrv_open(&bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv, &local_err); BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH,
&bdrv_qcow2, &local_err);
if (ret < 0) { if (ret < 0) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto out; goto out;
@ -1970,7 +1982,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
/* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning */ /* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning */
ret = bdrv_open(&bs, filename, NULL, NULL, ret = bdrv_open(&bs, filename, NULL, NULL,
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_BACKING, BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_BACKING,
drv, &local_err); &bdrv_qcow2, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto out; goto out;
@ -2150,8 +2162,7 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
/* align end of file to a sector boundary to ease reading with /* align end of file to a sector boundary to ease reading with
sector based I/Os */ sector based I/Os */
cluster_offset = bdrv_getlength(bs->file); cluster_offset = bdrv_getlength(bs->file);
bdrv_truncate(bs->file, cluster_offset); return bdrv_truncate(bs->file, cluster_offset);
return 0;
} }
if (nb_sectors != s->cluster_sectors) { if (nb_sectors != s->cluster_sectors) {
@ -2847,7 +2858,7 @@ static QemuOptsList qcow2_create_opts = {
} }
}; };
static BlockDriver bdrv_qcow2 = { BlockDriver bdrv_qcow2 = {
.format_name = "qcow2", .format_name = "qcow2",
.instance_size = sizeof(BDRVQcowState), .instance_size = sizeof(BDRVQcowState),
.bdrv_probe = qcow2_probe, .bdrv_probe = qcow2_probe,

View File

@ -446,6 +446,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
} }
if (fstat(s->fd, &st) < 0) { if (fstat(s->fd, &st) < 0) {
ret = -errno;
error_setg_errno(errp, errno, "Could not stat file"); error_setg_errno(errp, errno, "Could not stat file");
goto fail; goto fail;
} }
@ -1684,7 +1685,7 @@ static QemuOptsList raw_create_opts = {
} }
}; };
static BlockDriver bdrv_file = { BlockDriver bdrv_file = {
.format_name = "file", .format_name = "file",
.protocol_name = "file", .protocol_name = "file",
.instance_size = sizeof(BDRVRawState), .instance_size = sizeof(BDRVRawState),
@ -1922,7 +1923,7 @@ static int fd_open(BlockDriverState *bs)
return 0; return 0;
last_media_present = (s->fd >= 0); last_media_present = (s->fd >= 0);
if (s->fd >= 0 && if (s->fd >= 0 &&
(get_clock() - s->fd_open_time) >= FD_OPEN_TIMEOUT) { (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
qemu_close(s->fd); qemu_close(s->fd);
s->fd = -1; s->fd = -1;
#ifdef DEBUG_FLOPPY #ifdef DEBUG_FLOPPY
@ -1931,7 +1932,7 @@ static int fd_open(BlockDriverState *bs)
} }
if (s->fd < 0) { if (s->fd < 0) {
if (s->fd_got_error && if (s->fd_got_error &&
(get_clock() - s->fd_error_time) < FD_OPEN_TIMEOUT) { (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
#ifdef DEBUG_FLOPPY #ifdef DEBUG_FLOPPY
printf("No floppy (open delayed)\n"); printf("No floppy (open delayed)\n");
#endif #endif
@ -1939,7 +1940,7 @@ static int fd_open(BlockDriverState *bs)
} }
s->fd = qemu_open(bs->filename, s->open_flags & ~O_NONBLOCK); s->fd = qemu_open(bs->filename, s->open_flags & ~O_NONBLOCK);
if (s->fd < 0) { if (s->fd < 0) {
s->fd_error_time = get_clock(); s->fd_error_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
s->fd_got_error = 1; s->fd_got_error = 1;
if (last_media_present) if (last_media_present)
s->fd_media_changed = 1; s->fd_media_changed = 1;
@ -1954,7 +1955,7 @@ static int fd_open(BlockDriverState *bs)
} }
if (!last_media_present) if (!last_media_present)
s->fd_media_changed = 1; s->fd_media_changed = 1;
s->fd_open_time = get_clock(); s->fd_open_time = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
s->fd_got_error = 0; s->fd_got_error = 0;
return 0; return 0;
} }

View File

@ -540,7 +540,7 @@ static QemuOptsList raw_create_opts = {
} }
}; };
static BlockDriver bdrv_file = { BlockDriver bdrv_file = {
.format_name = "file", .format_name = "file",
.protocol_name = "file", .protocol_name = "file",
.instance_size = sizeof(BDRVRawState), .instance_size = sizeof(BDRVRawState),

View File

@ -58,8 +58,58 @@ static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num,
static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num, static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, QEMUIOVector *qiov) int nb_sectors, QEMUIOVector *qiov)
{ {
void *buf = NULL;
BlockDriver *drv;
QEMUIOVector local_qiov;
int ret;
if (bs->probed && sector_num == 0) {
/* As long as these conditions are true, we can't get partial writes to
* the probe buffer and can just directly check the request. */
QEMU_BUILD_BUG_ON(BLOCK_PROBE_BUF_SIZE != 512);
QEMU_BUILD_BUG_ON(BDRV_SECTOR_SIZE != 512);
if (nb_sectors == 0) {
/* qemu_iovec_to_buf() would fail, but we want to return success
* instead of -EINVAL in this case. */
return 0;
}
buf = qemu_try_blockalign(bs->file, 512);
if (!buf) {
ret = -ENOMEM;
goto fail;
}
ret = qemu_iovec_to_buf(qiov, 0, buf, 512);
if (ret != 512) {
ret = -EINVAL;
goto fail;
}
drv = bdrv_probe_all(buf, 512, NULL);
if (drv != bs->drv) {
ret = -EPERM;
goto fail;
}
/* Use the checked buffer, a malicious guest might be overwriting its
* original buffer in the background. */
qemu_iovec_init(&local_qiov, qiov->niov + 1);
qemu_iovec_add(&local_qiov, buf, 512);
qemu_iovec_concat(&local_qiov, qiov, 512, qiov->size - 512);
qiov = &local_qiov;
}
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
return bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov); ret = bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov);
fail:
if (qiov == &local_qiov) {
qemu_iovec_destroy(&local_qiov);
}
qemu_vfree(buf);
return ret;
} }
static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs, static int64_t coroutine_fn raw_co_get_block_status(BlockDriverState *bs,
@ -158,6 +208,18 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp) Error **errp)
{ {
bs->sg = bs->file->sg; bs->sg = bs->file->sg;
if (bs->probed && !bdrv_is_read_only(bs)) {
fprintf(stderr,
"WARNING: Image format was not specified for '%s' and probing "
"guessed raw.\n"
" Automatically detecting the format is dangerous for "
"raw images, write operations on block 0 will be restricted.\n"
" Specify the 'raw' format explicitly to remove the "
"restrictions.\n",
bs->file->filename);
}
return 0; return 0;
} }
@ -173,7 +235,7 @@ static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
return 1; return 1;
} }
static BlockDriver bdrv_raw = { BlockDriver bdrv_raw = {
.format_name = "raw", .format_name = "raw",
.bdrv_probe = &raw_probe, .bdrv_probe = &raw_probe,
.bdrv_reopen_prepare = &raw_reopen_prepare, .bdrv_reopen_prepare = &raw_reopen_prepare,

View File

@ -852,11 +852,6 @@ static QemuOptsList vdi_create_opts = {
.def_value_str = "off" .def_value_str = "off"
}, },
#endif #endif
{
.name = BLOCK_OPT_NOCOW,
.type = QEMU_OPT_BOOL,
.help = "Turn off copy-on-write (valid only on btrfs)"
},
/* TODO: An additional option to set UUID values might be useful. */ /* TODO: An additional option to set UUID values might be useful. */
{ /* end of list */ } { /* end of list */ }
} }

View File

@ -28,6 +28,7 @@
#include "qemu/module.h" #include "qemu/module.h"
#include "migration/migration.h" #include "migration/migration.h"
#include <zlib.h> #include <zlib.h>
#include <glib.h>
#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D') #define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
#define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V') #define VMDK4_MAGIC (('K' << 24) | ('D' << 16) | ('M' << 8) | 'V')
@ -556,8 +557,16 @@ static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
return NULL; return NULL;
} }
size = MIN(size, 1 << 20); /* avoid unbounded allocation */ if (size < 4) {
buf = g_malloc0(size + 1); /* Both descriptor file and sparse image must be much larger than 4
* bytes, also callers of vmdk_read_desc want to compare the first 4
* bytes with VMDK4_MAGIC, let's error out if less is read. */
error_setg(errp, "File is too small, not a valid image");
return NULL;
}
size = MIN(size, (1 << 20) - 1); /* avoid unbounded allocation */
buf = g_malloc(size + 1);
ret = bdrv_pread(file, desc_offset, buf, size); ret = bdrv_pread(file, desc_offset, buf, size);
if (ret < 0) { if (ret < 0) {
@ -565,6 +574,7 @@ static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
g_free(buf); g_free(buf);
return NULL; return NULL;
} }
buf[ret] = 0;
return buf; return buf;
} }
@ -635,6 +645,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
bs->file->total_sectors * 512 - 1536, bs->file->total_sectors * 512 - 1536,
&footer, sizeof(footer)); &footer, sizeof(footer));
if (ret < 0) { if (ret < 0) {
error_setg_errno(errp, -ret, "Failed to read footer");
return ret; return ret;
} }
@ -646,6 +657,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
le32_to_cpu(footer.eos_marker.size) != 0 || le32_to_cpu(footer.eos_marker.size) != 0 ||
le32_to_cpu(footer.eos_marker.type) != MARKER_END_OF_STREAM) le32_to_cpu(footer.eos_marker.type) != MARKER_END_OF_STREAM)
{ {
error_setg(errp, "Invalid footer");
return -EINVAL; return -EINVAL;
} }
@ -676,6 +688,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gt) l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gt)
* le64_to_cpu(header.granularity); * le64_to_cpu(header.granularity);
if (l1_entry_sectors == 0) { if (l1_entry_sectors == 0) {
error_setg(errp, "L1 entry size is invalid");
return -EINVAL; return -EINVAL;
} }
l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1) l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
@ -784,10 +797,12 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
VmdkExtent *extent; VmdkExtent *extent;
while (*p) { while (*p) {
/* parse extent line: /* parse extent line in one of below formats:
*
* RW [size in sectors] FLAT "file-name.vmdk" OFFSET * RW [size in sectors] FLAT "file-name.vmdk" OFFSET
* or
* RW [size in sectors] SPARSE "file-name.vmdk" * RW [size in sectors] SPARSE "file-name.vmdk"
* RW [size in sectors] VMFS "file-name.vmdk"
* RW [size in sectors] VMFSSPARSE "file-name.vmdk"
*/ */
flat_offset = -1; flat_offset = -1;
ret = sscanf(p, "%10s %" SCNd64 " %10s \"%511[^\n\r\"]\" %" SCNd64, ret = sscanf(p, "%10s %" SCNd64 " %10s \"%511[^\n\r\"]\" %" SCNd64,
@ -902,7 +917,7 @@ exit:
static int vmdk_open(BlockDriverState *bs, QDict *options, int flags, static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp) Error **errp)
{ {
char *buf = NULL; char *buf;
int ret; int ret;
BDRVVmdkState *s = bs->opaque; BDRVVmdkState *s = bs->opaque;
uint32_t magic; uint32_t magic;
@ -1538,7 +1553,7 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
/* update CID on the first write every time the virtual disk is /* update CID on the first write every time the virtual disk is
* opened */ * opened */
if (!s->cid_updated) { if (!s->cid_updated) {
ret = vmdk_write_cid(bs, time(NULL)); ret = vmdk_write_cid(bs, g_random_int());
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -1922,7 +1937,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
} }
/* generate descriptor file */ /* generate descriptor file */
desc = g_strdup_printf(desc_template, desc = g_strdup_printf(desc_template,
(uint32_t)time(NULL), g_random_int(),
parent_cid, parent_cid,
fmt, fmt,
parent_desc_line, parent_desc_line,

View File

@ -893,11 +893,6 @@ static QemuOptsList vpc_create_opts = {
"Type of virtual hard disk format. Supported formats are " "Type of virtual hard disk format. Supported formats are "
"{dynamic (default) | fixed} " "{dynamic (default) | fixed} "
}, },
{
.name = BLOCK_OPT_NOCOW,
.type = QEMU_OPT_BOOL,
.help = "Turn off copy-on-write (valid only on btrfs)"
},
{ /* end of list */ } { /* end of list */ }
} }
}; };

View File

@ -2917,6 +2917,12 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp)
} }
bdrv_qcow = bdrv_find_format("qcow"); bdrv_qcow = bdrv_find_format("qcow");
if (!bdrv_qcow) {
error_setg(errp, "Failed to locate qcow driver");
ret = -ENOENT;
goto err;
}
opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort); opts = qemu_opts_create(bdrv_qcow->create_opts, NULL, 0, &error_abort);
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512); qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512);
qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:"); qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:");

View File

@ -10,6 +10,7 @@
*/ */
#include "sysemu/blockdev.h" #include "sysemu/blockdev.h"
#include "sysemu/block-backend.h"
#include "hw/block/block.h" #include "hw/block/block.h"
#include "monitor/monitor.h" #include "monitor/monitor.h"
#include "qapi/qmp/qerror.h" #include "qapi/qmp/qerror.h"
@ -73,7 +74,7 @@ static void nbd_close_notifier(Notifier *n, void *data)
void qmp_nbd_server_add(const char *device, bool has_writable, bool writable, void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
Error **errp) Error **errp)
{ {
BlockDriverState *bs; BlockBackend *blk;
NBDExport *exp; NBDExport *exp;
NBDCloseNotifier *n; NBDCloseNotifier *n;
@ -87,12 +88,12 @@ void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
return; return;
} }
bs = bdrv_find(device); blk = blk_by_name(device);
if (!bs) { if (!blk) {
error_set(errp, QERR_DEVICE_NOT_FOUND, device); error_set(errp, QERR_DEVICE_NOT_FOUND, device);
return; return;
} }
if (!bdrv_is_inserted(bs)) { if (!blk_is_inserted(blk)) {
error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device); error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
return; return;
} }
@ -100,18 +101,18 @@ void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
if (!has_writable) { if (!has_writable) {
writable = false; writable = false;
} }
if (bdrv_is_read_only(bs)) { if (blk_is_read_only(blk)) {
writable = false; writable = false;
} }
exp = nbd_export_new(bs, 0, -1, writable ? 0 : NBD_FLAG_READ_ONLY, NULL); exp = nbd_export_new(blk, 0, -1, writable ? 0 : NBD_FLAG_READ_ONLY, NULL);
nbd_export_set_name(exp, device); nbd_export_set_name(exp, device);
n = g_new0(NBDCloseNotifier, 1); n = g_new0(NBDCloseNotifier, 1);
n->n.notify = nbd_close_notifier; n->n.notify = nbd_close_notifier;
n->exp = exp; n->exp = exp;
bdrv_add_close_notifier(bs, &n->n); blk_add_close_notifier(blk, &n->n);
QTAILQ_INSERT_TAIL(&close_notifiers, n, next); QTAILQ_INSERT_TAIL(&close_notifiers, n, next);
} }

View File

@ -1105,6 +1105,7 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
Error **errp) Error **errp)
{ {
BlockDriverState *bs = bdrv_find(device); BlockDriverState *bs = bdrv_find(device);
AioContext *aio_context;
QEMUSnapshotInfo sn; QEMUSnapshotInfo sn;
Error *local_err = NULL; Error *local_err = NULL;
SnapshotInfo *info = NULL; SnapshotInfo *info = NULL;
@ -1128,25 +1129,34 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
return NULL; return NULL;
} }
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE, errp)) {
goto out_aio_context;
}
ret = bdrv_snapshot_find_by_id_and_name(bs, id, name, &sn, &local_err); ret = bdrv_snapshot_find_by_id_and_name(bs, id, name, &sn, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return NULL; goto out_aio_context;
} }
if (!ret) { if (!ret) {
error_setg(errp, error_setg(errp,
"Snapshot with id '%s' and name '%s' does not exist on " "Snapshot with id '%s' and name '%s' does not exist on "
"device '%s'", "device '%s'",
STR_OR_NULL(id), STR_OR_NULL(name), device); STR_OR_NULL(id), STR_OR_NULL(name), device);
return NULL; goto out_aio_context;
} }
bdrv_snapshot_delete(bs, id, name, &local_err); bdrv_snapshot_delete(bs, id, name, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return NULL; goto out_aio_context;
} }
aio_context_release(aio_context);
info = g_new0(SnapshotInfo, 1); info = g_new0(SnapshotInfo, 1);
info->id = g_strdup(sn.id_str); info->id = g_strdup(sn.id_str);
info->name = g_strdup(sn.name); info->name = g_strdup(sn.name);
@ -1157,9 +1167,13 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
info->vm_clock_sec = sn.vm_clock_nsec / 1000000000; info->vm_clock_sec = sn.vm_clock_nsec / 1000000000;
return info; return info;
out_aio_context:
aio_context_release(aio_context);
return NULL;
} }
/* New and old BlockDriverState structs for group snapshots */ /* New and old BlockDriverState structs for atomic group operations */
typedef struct BlkTransactionState BlkTransactionState; typedef struct BlkTransactionState BlkTransactionState;
@ -1193,6 +1207,7 @@ struct BlkTransactionState {
typedef struct InternalSnapshotState { typedef struct InternalSnapshotState {
BlkTransactionState common; BlkTransactionState common;
BlockDriverState *bs; BlockDriverState *bs;
AioContext *aio_context;
QEMUSnapshotInfo sn; QEMUSnapshotInfo sn;
} InternalSnapshotState; } InternalSnapshotState;
@ -1226,11 +1241,19 @@ static void internal_snapshot_prepare(BlkTransactionState *common,
return; return;
} }
/* AioContext is released in .clean() */
state->aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(state->aio_context);
if (!bdrv_is_inserted(bs)) { if (!bdrv_is_inserted(bs)) {
error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device); error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
return; return;
} }
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) {
return;
}
if (bdrv_is_read_only(bs)) { if (bdrv_is_read_only(bs)) {
error_set(errp, QERR_DEVICE_IS_READ_ONLY, device); error_set(errp, QERR_DEVICE_IS_READ_ONLY, device);
return; return;
@ -1303,11 +1326,22 @@ static void internal_snapshot_abort(BlkTransactionState *common)
} }
} }
static void internal_snapshot_clean(BlkTransactionState *common)
{
InternalSnapshotState *state = DO_UPCAST(InternalSnapshotState,
common, common);
if (state->aio_context) {
aio_context_release(state->aio_context);
}
}
/* external snapshot private data */ /* external snapshot private data */
typedef struct ExternalSnapshotState { typedef struct ExternalSnapshotState {
BlkTransactionState common; BlkTransactionState common;
BlockDriverState *old_bs; BlockDriverState *old_bs;
BlockDriverState *new_bs; BlockDriverState *new_bs;
AioContext *aio_context;
} ExternalSnapshotState; } ExternalSnapshotState;
static void external_snapshot_prepare(BlkTransactionState *common, static void external_snapshot_prepare(BlkTransactionState *common,
@ -1374,6 +1408,10 @@ static void external_snapshot_prepare(BlkTransactionState *common,
return; return;
} }
/* Acquire AioContext now so any threads operating on old_bs stop */
state->aio_context = bdrv_get_aio_context(state->old_bs);
aio_context_acquire(state->aio_context);
if (!bdrv_is_inserted(state->old_bs)) { if (!bdrv_is_inserted(state->old_bs)) {
error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device); error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
return; return;
@ -1432,6 +1470,8 @@ static void external_snapshot_commit(BlkTransactionState *common)
ExternalSnapshotState *state = ExternalSnapshotState *state =
DO_UPCAST(ExternalSnapshotState, common, common); DO_UPCAST(ExternalSnapshotState, common, common);
bdrv_set_aio_context(state->new_bs, state->aio_context);
/* This removes our old bs and adds the new bs */ /* This removes our old bs and adds the new bs */
bdrv_append(state->new_bs, state->old_bs); bdrv_append(state->new_bs, state->old_bs);
/* We don't need (or want) to use the transactional /* We don't need (or want) to use the transactional
@ -1439,6 +1479,8 @@ static void external_snapshot_commit(BlkTransactionState *common)
* don't want to abort all of them if one of them fails the reopen */ * don't want to abort all of them if one of them fails the reopen */
bdrv_reopen(state->new_bs, state->new_bs->open_flags & ~BDRV_O_RDWR, bdrv_reopen(state->new_bs, state->new_bs->open_flags & ~BDRV_O_RDWR,
NULL); NULL);
aio_context_release(state->aio_context);
} }
static void external_snapshot_abort(BlkTransactionState *common) static void external_snapshot_abort(BlkTransactionState *common)
@ -1448,23 +1490,38 @@ static void external_snapshot_abort(BlkTransactionState *common)
if (state->new_bs) { if (state->new_bs) {
bdrv_unref(state->new_bs); bdrv_unref(state->new_bs);
} }
if (state->aio_context) {
aio_context_release(state->aio_context);
}
} }
typedef struct DriveBackupState { typedef struct DriveBackupState {
BlkTransactionState common; BlkTransactionState common;
BlockDriverState *bs; BlockDriverState *bs;
AioContext *aio_context;
BlockJob *job; BlockJob *job;
} DriveBackupState; } DriveBackupState;
static void drive_backup_prepare(BlkTransactionState *common, Error **errp) static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
{ {
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common); DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
BlockDriverState *bs;
DriveBackup *backup; DriveBackup *backup;
Error *local_err = NULL; Error *local_err = NULL;
assert(common->action->kind == TRANSACTION_ACTION_KIND_DRIVE_BACKUP); assert(common->action->kind == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
backup = common->action->drive_backup; backup = common->action->drive_backup;
bs = bdrv_find(backup->device);
if (!bs) {
error_set(errp, QERR_DEVICE_NOT_FOUND, backup->device);
return;
}
/* AioContext is released in .clean() */
state->aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(state->aio_context);
qmp_drive_backup(backup->device, backup->target, qmp_drive_backup(backup->device, backup->target,
backup->has_format, backup->format, backup->has_format, backup->format,
backup->sync, backup->sync,
@ -1475,12 +1532,10 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
&local_err); &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
state->bs = NULL;
state->job = NULL;
return; return;
} }
state->bs = bdrv_find(backup->device); state->bs = bs;
state->job = state->bs->job; state->job = state->bs->job;
} }
@ -1495,6 +1550,15 @@ static void drive_backup_abort(BlkTransactionState *common)
} }
} }
static void drive_backup_clean(BlkTransactionState *common)
{
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
if (state->aio_context) {
aio_context_release(state->aio_context);
}
}
static void abort_prepare(BlkTransactionState *common, Error **errp) static void abort_prepare(BlkTransactionState *common, Error **errp)
{ {
error_setg(errp, "Transaction aborted using Abort action"); error_setg(errp, "Transaction aborted using Abort action");
@ -1516,6 +1580,7 @@ static const BdrvActionOps actions[] = {
.instance_size = sizeof(DriveBackupState), .instance_size = sizeof(DriveBackupState),
.prepare = drive_backup_prepare, .prepare = drive_backup_prepare,
.abort = drive_backup_abort, .abort = drive_backup_abort,
.clean = drive_backup_clean,
}, },
[TRANSACTION_ACTION_KIND_ABORT] = { [TRANSACTION_ACTION_KIND_ABORT] = {
.instance_size = sizeof(BlkTransactionState), .instance_size = sizeof(BlkTransactionState),
@ -1526,13 +1591,13 @@ static const BdrvActionOps actions[] = {
.instance_size = sizeof(InternalSnapshotState), .instance_size = sizeof(InternalSnapshotState),
.prepare = internal_snapshot_prepare, .prepare = internal_snapshot_prepare,
.abort = internal_snapshot_abort, .abort = internal_snapshot_abort,
.clean = internal_snapshot_clean,
}, },
}; };
/* /*
* 'Atomic' group snapshots. The snapshots are taken as a set, and if any fail * 'Atomic' group operations. The operations are performed as a set, and if
* then we do not pivot any of the devices in the group, and abandon the * any fail then we roll back all operations in the group.
* snapshots
*/ */
void qmp_transaction(TransactionActionList *dev_list, Error **errp) void qmp_transaction(TransactionActionList *dev_list, Error **errp)
{ {
@ -1543,10 +1608,10 @@ void qmp_transaction(TransactionActionList *dev_list, Error **errp)
QSIMPLEQ_HEAD(snap_bdrv_states, BlkTransactionState) snap_bdrv_states; QSIMPLEQ_HEAD(snap_bdrv_states, BlkTransactionState) snap_bdrv_states;
QSIMPLEQ_INIT(&snap_bdrv_states); QSIMPLEQ_INIT(&snap_bdrv_states);
/* drain all i/o before any snapshots */ /* drain all i/o before any operations */
bdrv_drain_all(); bdrv_drain_all();
/* We don't do anything in this loop that commits us to the snapshot */ /* We don't do anything in this loop that commits us to the operations */
while (NULL != dev_entry) { while (NULL != dev_entry) {
TransactionAction *dev_info = NULL; TransactionAction *dev_info = NULL;
const BdrvActionOps *ops; const BdrvActionOps *ops;
@ -1581,10 +1646,7 @@ void qmp_transaction(TransactionActionList *dev_list, Error **errp)
goto exit; goto exit;
delete_and_fail: delete_and_fail:
/* /* failure, and it is all-or-none; roll back all operations */
* failure, and it is all-or-none; abandon each new bs, and keep using
* the original bs for all images
*/
QSIMPLEQ_FOREACH(state, &snap_bdrv_states, entry) { QSIMPLEQ_FOREACH(state, &snap_bdrv_states, entry) {
if (state->ops->abort) { if (state->ops->abort) {
state->ops->abort(state); state->ops->abort(state);
@ -1603,14 +1665,18 @@ exit:
static void eject_device(BlockBackend *blk, int force, Error **errp) static void eject_device(BlockBackend *blk, int force, Error **errp)
{ {
BlockDriverState *bs = blk_bs(blk); BlockDriverState *bs = blk_bs(blk);
AioContext *aio_context;
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) { if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
return; goto out;
} }
if (!blk_dev_has_removable_media(blk)) { if (!blk_dev_has_removable_media(blk)) {
error_setg(errp, "Device '%s' is not removable", error_setg(errp, "Device '%s' is not removable",
bdrv_get_device_name(bs)); bdrv_get_device_name(bs));
return; goto out;
} }
if (blk_dev_is_medium_locked(blk) && !blk_dev_is_tray_open(blk)) { if (blk_dev_is_medium_locked(blk) && !blk_dev_is_tray_open(blk)) {
@ -1618,11 +1684,14 @@ static void eject_device(BlockBackend *blk, int force, Error **errp)
if (!force) { if (!force) {
error_setg(errp, "Device '%s' is locked", error_setg(errp, "Device '%s' is locked",
bdrv_get_device_name(bs)); bdrv_get_device_name(bs));
return; goto out;
} }
} }
bdrv_close(bs); bdrv_close(bs);
out:
aio_context_release(aio_context);
} }
void qmp_eject(const char *device, bool has_force, bool force, Error **errp) void qmp_eject(const char *device, bool has_force, bool force, Error **errp)
@ -1644,6 +1713,7 @@ void qmp_block_passwd(bool has_device, const char *device,
{ {
Error *local_err = NULL; Error *local_err = NULL;
BlockDriverState *bs; BlockDriverState *bs;
AioContext *aio_context;
int err; int err;
bs = bdrv_lookup_bs(has_device ? device : NULL, bs = bdrv_lookup_bs(has_device ? device : NULL,
@ -1654,16 +1724,23 @@ void qmp_block_passwd(bool has_device, const char *device,
return; return;
} }
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
err = bdrv_set_key(bs, password); err = bdrv_set_key(bs, password);
if (err == -EINVAL) { if (err == -EINVAL) {
error_set(errp, QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs)); error_set(errp, QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs));
return; goto out;
} else if (err < 0) { } else if (err < 0) {
error_set(errp, QERR_INVALID_PASSWORD); error_set(errp, QERR_INVALID_PASSWORD);
return; goto out;
} }
out:
aio_context_release(aio_context);
} }
/* Assumes AioContext is held */
static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename, static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
int bdrv_flags, BlockDriver *drv, int bdrv_flags, BlockDriver *drv,
const char *password, Error **errp) const char *password, Error **errp)
@ -1696,6 +1773,7 @@ void qmp_change_blockdev(const char *device, const char *filename,
{ {
BlockBackend *blk; BlockBackend *blk;
BlockDriverState *bs; BlockDriverState *bs;
AioContext *aio_context;
BlockDriver *drv = NULL; BlockDriver *drv = NULL;
int bdrv_flags; int bdrv_flags;
Error *err = NULL; Error *err = NULL;
@ -1707,24 +1785,30 @@ void qmp_change_blockdev(const char *device, const char *filename,
} }
bs = blk_bs(blk); bs = blk_bs(blk);
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
if (format) { if (format) {
drv = bdrv_find_whitelisted_format(format, bs->read_only); drv = bdrv_find_whitelisted_format(format, bs->read_only);
if (!drv) { if (!drv) {
error_set(errp, QERR_INVALID_BLOCK_FORMAT, format); error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
return; goto out;
} }
} }
eject_device(blk, 0, &err); eject_device(blk, 0, &err);
if (err) { if (err) {
error_propagate(errp, err); error_propagate(errp, err);
return; goto out;
} }
bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR; bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR;
bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0; bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0;
qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, drv, NULL, errp); qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, drv, NULL, errp);
out:
aio_context_release(aio_context);
} }
/* throttling disk I/O limits */ /* throttling disk I/O limits */
@ -2548,6 +2632,7 @@ void qmp_change_backing_file(const char *device,
Error **errp) Error **errp)
{ {
BlockDriverState *bs = NULL; BlockDriverState *bs = NULL;
AioContext *aio_context;
BlockDriverState *image_bs = NULL; BlockDriverState *image_bs = NULL;
Error *local_err = NULL; Error *local_err = NULL;
bool ro; bool ro;
@ -2561,34 +2646,37 @@ void qmp_change_backing_file(const char *device,
return; return;
} }
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
image_bs = bdrv_lookup_bs(NULL, image_node_name, &local_err); image_bs = bdrv_lookup_bs(NULL, image_node_name, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; goto out;
} }
if (!image_bs) { if (!image_bs) {
error_setg(errp, "image file not found"); error_setg(errp, "image file not found");
return; goto out;
} }
if (bdrv_find_base(image_bs) == image_bs) { if (bdrv_find_base(image_bs) == image_bs) {
error_setg(errp, "not allowing backing file change on an image " error_setg(errp, "not allowing backing file change on an image "
"without a backing file"); "without a backing file");
return; goto out;
} }
/* even though we are not necessarily operating on bs, we need it to /* even though we are not necessarily operating on bs, we need it to
* determine if block ops are currently prohibited on the chain */ * determine if block ops are currently prohibited on the chain */
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_CHANGE, errp)) { if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_CHANGE, errp)) {
return; goto out;
} }
/* final sanity check */ /* final sanity check */
if (!bdrv_chain_contains(bs, image_bs)) { if (!bdrv_chain_contains(bs, image_bs)) {
error_setg(errp, "'%s' and image file are not in the same chain", error_setg(errp, "'%s' and image file are not in the same chain",
device); device);
return; goto out;
} }
/* if not r/w, reopen to make r/w */ /* if not r/w, reopen to make r/w */
@ -2599,7 +2687,7 @@ void qmp_change_backing_file(const char *device,
bdrv_reopen(image_bs, open_flags | BDRV_O_RDWR, &local_err); bdrv_reopen(image_bs, open_flags | BDRV_O_RDWR, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
return; goto out;
} }
} }
@ -2619,6 +2707,9 @@ void qmp_change_backing_file(const char *device,
error_propagate(errp, local_err); /* will preserve prior errp */ error_propagate(errp, local_err); /* will preserve prior errp */
} }
} }
out:
aio_context_release(aio_context);
} }
void qmp_blockdev_add(BlockdevOptions *options, Error **errp) void qmp_blockdev_add(BlockdevOptions *options, Error **errp)

157
hmp.c
View File

@ -290,70 +290,74 @@ void hmp_info_cpus(Monitor *mon, const QDict *qdict)
qapi_free_CpuInfoList(cpu_list); qapi_free_CpuInfoList(cpu_list);
} }
void hmp_info_block(Monitor *mon, const QDict *qdict) static void print_block_info(Monitor *mon, BlockInfo *info,
BlockDeviceInfo *inserted, bool verbose)
{ {
BlockInfoList *block_list, *info;
ImageInfo *image_info; ImageInfo *image_info;
const char *device = qdict_get_try_str(qdict, "device");
bool verbose = qdict_get_try_bool(qdict, "verbose", 0);
block_list = qmp_query_block(NULL); assert(!info || !info->has_inserted || info->inserted == inserted);
for (info = block_list; info; info = info->next) { if (info) {
if (device && strcmp(device, info->value->device)) { monitor_printf(mon, "%s", info->device);
continue; if (inserted && inserted->has_node_name) {
monitor_printf(mon, " (%s)", inserted->node_name);
}
} else {
assert(inserted);
monitor_printf(mon, "%s",
inserted->has_node_name
? inserted->node_name
: "<anonymous>");
} }
if (info != block_list) { if (inserted) {
monitor_printf(mon, "\n");
}
monitor_printf(mon, "%s", info->value->device);
if (info->value->has_inserted) {
monitor_printf(mon, ": %s (%s%s%s)\n", monitor_printf(mon, ": %s (%s%s%s)\n",
info->value->inserted->file, inserted->file,
info->value->inserted->drv, inserted->drv,
info->value->inserted->ro ? ", read-only" : "", inserted->ro ? ", read-only" : "",
info->value->inserted->encrypted ? ", encrypted" : ""); inserted->encrypted ? ", encrypted" : "");
} else { } else {
monitor_printf(mon, ": [not inserted]\n"); monitor_printf(mon, ": [not inserted]\n");
} }
if (info->value->has_io_status && info->value->io_status != BLOCK_DEVICE_IO_STATUS_OK) { if (info) {
if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
monitor_printf(mon, " I/O status: %s\n", monitor_printf(mon, " I/O status: %s\n",
BlockDeviceIoStatus_lookup[info->value->io_status]); BlockDeviceIoStatus_lookup[info->io_status]);
} }
if (info->value->removable) { if (info->removable) {
monitor_printf(mon, " Removable device: %slocked, tray %s\n", monitor_printf(mon, " Removable device: %slocked, tray %s\n",
info->value->locked ? "" : "not ", info->locked ? "" : "not ",
info->value->tray_open ? "open" : "closed"); info->tray_open ? "open" : "closed");
}
} }
if (!info->value->has_inserted) { if (!inserted) {
continue; return;
} }
if (info->value->inserted->has_backing_file) { monitor_printf(mon, " Cache mode: %s%s%s\n",
inserted->cache->writeback ? "writeback" : "writethrough",
inserted->cache->direct ? ", direct" : "",
inserted->cache->no_flush ? ", ignore flushes" : "");
if (inserted->has_backing_file) {
monitor_printf(mon, monitor_printf(mon,
" Backing file: %s " " Backing file: %s "
"(chain depth: %" PRId64 ")\n", "(chain depth: %" PRId64 ")\n",
info->value->inserted->backing_file, inserted->backing_file,
info->value->inserted->backing_file_depth); inserted->backing_file_depth);
} }
if (info->value->inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) { if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
monitor_printf(mon, " Detect zeroes: %s\n", monitor_printf(mon, " Detect zeroes: %s\n",
BlockdevDetectZeroesOptions_lookup[info->value->inserted->detect_zeroes]); BlockdevDetectZeroesOptions_lookup[inserted->detect_zeroes]);
} }
if (info->value->inserted->bps if (inserted->bps || inserted->bps_rd || inserted->bps_wr ||
|| info->value->inserted->bps_rd inserted->iops || inserted->iops_rd || inserted->iops_wr)
|| info->value->inserted->bps_wr
|| info->value->inserted->iops
|| info->value->inserted->iops_rd
|| info->value->inserted->iops_wr)
{ {
monitor_printf(mon, " I/O throttling: bps=%" PRId64 monitor_printf(mon, " I/O throttling: bps=%" PRId64
" bps_rd=%" PRId64 " bps_wr=%" PRId64 " bps_rd=%" PRId64 " bps_wr=%" PRId64
@ -366,24 +370,24 @@ void hmp_info_block(Monitor *mon, const QDict *qdict)
" iops_rd_max=%" PRId64 " iops_rd_max=%" PRId64
" iops_wr_max=%" PRId64 " iops_wr_max=%" PRId64
" iops_size=%" PRId64 "\n", " iops_size=%" PRId64 "\n",
info->value->inserted->bps, inserted->bps,
info->value->inserted->bps_rd, inserted->bps_rd,
info->value->inserted->bps_wr, inserted->bps_wr,
info->value->inserted->bps_max, inserted->bps_max,
info->value->inserted->bps_rd_max, inserted->bps_rd_max,
info->value->inserted->bps_wr_max, inserted->bps_wr_max,
info->value->inserted->iops, inserted->iops,
info->value->inserted->iops_rd, inserted->iops_rd,
info->value->inserted->iops_wr, inserted->iops_wr,
info->value->inserted->iops_max, inserted->iops_max,
info->value->inserted->iops_rd_max, inserted->iops_rd_max,
info->value->inserted->iops_wr_max, inserted->iops_wr_max,
info->value->inserted->iops_size); inserted->iops_size);
} }
if (verbose) { if (verbose) {
monitor_printf(mon, "\nImages:\n"); monitor_printf(mon, "\nImages:\n");
image_info = info->value->inserted->image; image_info = inserted->image;
while (1) { while (1) {
bdrv_image_info_dump((fprintf_function)monitor_printf, bdrv_image_info_dump((fprintf_function)monitor_printf,
mon, image_info); mon, image_info);
@ -394,16 +398,67 @@ void hmp_info_block(Monitor *mon, const QDict *qdict)
} }
} }
} }
}
void hmp_info_block(Monitor *mon, const QDict *qdict)
{
BlockInfoList *block_list, *info;
BlockDeviceInfoList *blockdev_list, *blockdev;
const char *device = qdict_get_try_str(qdict, "device");
bool verbose = qdict_get_try_bool(qdict, "verbose", 0);
bool nodes = qdict_get_try_bool(qdict, "nodes", 0);
bool printed = false;
/* Print BlockBackend information */
if (!nodes) {
block_list = qmp_query_block(false);
} else {
block_list = NULL;
}
for (info = block_list; info; info = info->next) {
if (device && strcmp(device, info->value->device)) {
continue;
}
if (info != block_list) {
monitor_printf(mon, "\n");
}
print_block_info(mon, info->value, info->value->has_inserted
? info->value->inserted : NULL,
verbose);
printed = true;
} }
qapi_free_BlockInfoList(block_list); qapi_free_BlockInfoList(block_list);
if ((!device && !nodes) || printed) {
return;
}
/* Print node information */
blockdev_list = qmp_query_named_block_nodes(NULL);
for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) {
assert(blockdev->value->has_node_name);
if (device && strcmp(device, blockdev->value->node_name)) {
continue;
}
if (blockdev != blockdev_list) {
monitor_printf(mon, "\n");
}
print_block_info(mon, NULL, blockdev->value, verbose);
}
qapi_free_BlockDeviceInfoList(blockdev_list);
} }
void hmp_info_blockstats(Monitor *mon, const QDict *qdict) void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
{ {
BlockStatsList *stats_list, *stats; BlockStatsList *stats_list, *stats;
stats_list = qmp_query_blockstats(NULL); stats_list = qmp_query_blockstats(false, false, NULL);
for (stats = stats_list; stats; stats = stats->next) { for (stats = stats_list; stats; stats = stats->next) {
if (!stats->value->has_device) { if (!stats->value->has_device) {

View File

@ -197,7 +197,13 @@ void virtio_blk_data_plane_create(VirtIODevice *vdev, VirtIOBlkConf *conf,
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_RESIZE, s->blocker); blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_RESIZE, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker); blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_DRIVE_DEL, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_BACKUP_SOURCE, s->blocker); blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_BACKUP_SOURCE, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_CHANGE, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_COMMIT, s->blocker); blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_COMMIT, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_EJECT, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_EXTERNAL_SNAPSHOT, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE,
s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_MIRROR, s->blocker); blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_MIRROR, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_STREAM, s->blocker); blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_STREAM, s->blocker);
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_REPLACE, s->blocker); blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_REPLACE, s->blocker);

View File

@ -811,6 +811,7 @@ static int nvme_init(PCIDevice *pci_dev)
NVME_CAP_SET_AMS(n->bar.cap, 1); NVME_CAP_SET_AMS(n->bar.cap, 1);
NVME_CAP_SET_TO(n->bar.cap, 0xf); NVME_CAP_SET_TO(n->bar.cap, 0xf);
NVME_CAP_SET_CSS(n->bar.cap, 1); NVME_CAP_SET_CSS(n->bar.cap, 1);
NVME_CAP_SET_MPSMAX(n->bar.cap, 4);
n->bar.vs = 0x00010001; n->bar.vs = 0x00010001;
n->bar.intmc = n->bar.intms = 0; n->bar.intmc = n->bar.intms = 0;

View File

@ -688,7 +688,7 @@ typedef struct NvmeCtrl {
NvmeBar bar; NvmeBar bar;
BlockConf conf; BlockConf conf;
uint16_t page_size; uint32_t page_size;
uint16_t page_bits; uint16_t page_bits;
uint16_t max_prp_ents; uint16_t max_prp_ents;
uint16_t cqe_size; uint16_t cqe_size;

View File

@ -34,15 +34,15 @@
#include <hw/ide/pci.h> #include <hw/ide/pci.h>
#include <hw/ide/ahci.h> #include <hw/ide/ahci.h>
/* #define DEBUG_AHCI */ #define DEBUG_AHCI 0
#ifdef DEBUG_AHCI
#define DPRINTF(port, fmt, ...) \ #define DPRINTF(port, fmt, ...) \
do { fprintf(stderr, "ahci: %s: [%d] ", __FUNCTION__, port); \ do { \
fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) if (DEBUG_AHCI) { \
#else fprintf(stderr, "ahci: %s: [%d] ", __func__, port); \
#define DPRINTF(port, fmt, ...) do {} while(0) fprintf(stderr, fmt, ## __VA_ARGS__); \
#endif } \
} while (0)
static void check_cmd(AHCIState *s, int port); static void check_cmd(AHCIState *s, int port);
static int handle_cmd(AHCIState *s,int port,int slot); static int handle_cmd(AHCIState *s,int port,int slot);
@ -551,7 +551,7 @@ static void ahci_reset_port(AHCIState *s, int port)
static void debug_print_fis(uint8_t *fis, int cmd_len) static void debug_print_fis(uint8_t *fis, int cmd_len)
{ {
#ifdef DEBUG_AHCI #if DEBUG_AHCI
int i; int i;
fprintf(stderr, "fis:"); fprintf(stderr, "fis:");
@ -580,7 +580,7 @@ static void ahci_write_fis_sdb(AHCIState *s, int port, uint32_t finished)
sdb_fis = (SDBFIS *)&ad->res_fis[RES_FIS_SDBFIS]; sdb_fis = (SDBFIS *)&ad->res_fis[RES_FIS_SDBFIS];
ide_state = &ad->port.ifs[0]; ide_state = &ad->port.ifs[0];
sdb_fis->type = 0xA1; sdb_fis->type = SATA_FIS_TYPE_SDB;
/* Interrupt pending & Notification bit */ /* Interrupt pending & Notification bit */
sdb_fis->flags = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0); sdb_fis->flags = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
sdb_fis->status = ide_state->status & 0x77; sdb_fis->status = ide_state->status & 0x77;
@ -631,7 +631,7 @@ static void ahci_write_fis_pio(AHCIDevice *ad, uint16_t len)
pio_fis = &ad->res_fis[RES_FIS_PSFIS]; pio_fis = &ad->res_fis[RES_FIS_PSFIS];
pio_fis[0] = 0x5f; pio_fis[0] = SATA_FIS_TYPE_PIO_SETUP;
pio_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0); pio_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
pio_fis[2] = s->status; pio_fis[2] = s->status;
pio_fis[3] = s->error; pio_fis[3] = s->error;
@ -690,7 +690,7 @@ static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis)
d2h_fis = &ad->res_fis[RES_FIS_RFIS]; d2h_fis = &ad->res_fis[RES_FIS_RFIS];
d2h_fis[0] = 0x34; d2h_fis[0] = SATA_FIS_TYPE_REGISTER_D2H;
d2h_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0); d2h_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
d2h_fis[2] = s->status; d2h_fis[2] = s->status;
d2h_fis[3] = s->error; d2h_fis[3] = s->error;
@ -1154,9 +1154,7 @@ out:
static void ahci_start_dma(IDEDMA *dma, IDEState *s, static void ahci_start_dma(IDEDMA *dma, IDEState *s,
BlockCompletionFunc *dma_cb) BlockCompletionFunc *dma_cb)
{ {
#ifdef DEBUG_AHCI
AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma); AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
#endif
DPRINTF(ad->port_no, "\n"); DPRINTF(ad->port_no, "\n");
s->io_buffer_offset = 0; s->io_buffer_offset = 0;
dma_cb(s, 0); dma_cb(s, 0);

View File

@ -157,6 +157,9 @@
#define SATA_FIS_TYPE_REGISTER_H2D 0x27 #define SATA_FIS_TYPE_REGISTER_H2D 0x27
#define SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER 0x80 #define SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER 0x80
#define SATA_FIS_TYPE_REGISTER_D2H 0x34
#define SATA_FIS_TYPE_PIO_SETUP 0x5f
#define SATA_FIS_TYPE_SDB 0xA1
#define AHCI_CMD_HDR_CMD_FIS_LEN 0x1f #define AHCI_CMD_HDR_CMD_FIS_LEN 0x1f
#define AHCI_CMD_HDR_PRDT_LEN 16 #define AHCI_CMD_HDR_PRDT_LEN 16

View File

@ -163,6 +163,11 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
return -1; return -1;
} }
if (dev->conf.logical_block_size != 512) {
error_report("logical_block_size must be 512 for IDE");
return -1;
}
blkconf_serial(&dev->conf, &dev->serial); blkconf_serial(&dev->conf, &dev->serial);
if (kind != IDE_CD) { if (kind != IDE_CD) {
blkconf_geometry(&dev->conf, &dev->chs_trans, 65536, 16, 255, &err); blkconf_geometry(&dev->conf, &dev->chs_trans, 65536, 16, 255, &err);

View File

@ -374,6 +374,7 @@ BlockDriverState *bdrv_lookup_bs(const char *device,
const char *node_name, const char *node_name,
Error **errp); Error **errp);
bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base); bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base);
BlockDriverState *bdrv_next_node(BlockDriverState *bs);
BlockDriverState *bdrv_next(BlockDriverState *bs); BlockDriverState *bdrv_next(BlockDriverState *bs);
int bdrv_is_encrypted(BlockDriverState *bs); int bdrv_is_encrypted(BlockDriverState *bs);
int bdrv_key_required(BlockDriverState *bs); int bdrv_key_required(BlockDriverState *bs);
@ -381,6 +382,7 @@ int bdrv_set_key(BlockDriverState *bs, const char *key);
int bdrv_query_missing_keys(void); int bdrv_query_missing_keys(void);
void bdrv_iterate_format(void (*it)(void *opaque, const char *name), void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
void *opaque); void *opaque);
const char *bdrv_get_node_name(const BlockDriverState *bs);
const char *bdrv_get_device_name(const BlockDriverState *bs); const char *bdrv_get_device_name(const BlockDriverState *bs);
int bdrv_get_flags(BlockDriverState *bs); int bdrv_get_flags(BlockDriverState *bs);
int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num, int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,

View File

@ -57,6 +57,8 @@
#define BLOCK_OPT_REDUNDANCY "redundancy" #define BLOCK_OPT_REDUNDANCY "redundancy"
#define BLOCK_OPT_NOCOW "nocow" #define BLOCK_OPT_NOCOW "nocow"
#define BLOCK_PROBE_BUF_SIZE 512
typedef struct BdrvTrackedRequest { typedef struct BdrvTrackedRequest {
BlockDriverState *bs; BlockDriverState *bs;
int64_t offset; int64_t offset;
@ -324,6 +326,7 @@ struct BlockDriverState {
int sg; /* if true, the device is a /dev/sg* */ int sg; /* if true, the device is a /dev/sg* */
int copy_on_read; /* if true, copy read backing sectors into image int copy_on_read; /* if true, copy read backing sectors into image
note this is a reference count */ note this is a reference count */
bool probed;
BlockDriver *drv; /* NULL means no media */ BlockDriver *drv; /* NULL means no media */
void *opaque; void *opaque;
@ -411,7 +414,17 @@ struct BlockDriverState {
Error *backing_blocker; Error *backing_blocker;
}; };
/* Essential block drivers which must always be statically linked into qemu, and
* which therefore can be accessed without using bdrv_find_format() */
extern BlockDriver bdrv_file;
extern BlockDriver bdrv_raw;
extern BlockDriver bdrv_qcow2;
int get_tmp_filename(char *filename, int size); int get_tmp_filename(char *filename, int size);
BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
const char *filename);
void bdrv_set_io_limits(BlockDriverState *bs, void bdrv_set_io_limits(BlockDriverState *bs,
ThrottleConfig *cfg); ThrottleConfig *cfg);

View File

@ -85,14 +85,13 @@ int nbd_disconnect(int fd);
typedef struct NBDExport NBDExport; typedef struct NBDExport NBDExport;
typedef struct NBDClient NBDClient; typedef struct NBDClient NBDClient;
NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
off_t size, uint32_t nbdflags, uint32_t nbdflags, void (*close)(NBDExport *));
void (*close)(NBDExport *));
void nbd_export_close(NBDExport *exp); void nbd_export_close(NBDExport *exp);
void nbd_export_get(NBDExport *exp); void nbd_export_get(NBDExport *exp);
void nbd_export_put(NBDExport *exp); void nbd_export_put(NBDExport *exp);
BlockDriverState *nbd_export_get_blockdev(NBDExport *exp); BlockBackend *nbd_export_get_blockdev(NBDExport *exp);
NBDExport *nbd_export_find(const char *name); NBDExport *nbd_export_find(const char *name);
void nbd_export_set_name(NBDExport *exp, const char *name); void nbd_export_set_name(NBDExport *exp, const char *name);

View File

@ -108,6 +108,8 @@ int blk_aio_multiwrite(BlockBackend *blk, BlockRequest *reqs, int num_reqs);
int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf); int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf);
BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf, BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
BlockCompletionFunc *cb, void *opaque); BlockCompletionFunc *cb, void *opaque);
int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors);
int blk_co_flush(BlockBackend *blk);
int blk_flush(BlockBackend *blk); int blk_flush(BlockBackend *blk);
int blk_flush_all(void); int blk_flush_all(void);
void blk_drain_all(void); void blk_drain_all(void);
@ -120,6 +122,7 @@ int blk_is_read_only(BlockBackend *blk);
int blk_is_sg(BlockBackend *blk); int blk_is_sg(BlockBackend *blk);
int blk_enable_write_cache(BlockBackend *blk); int blk_enable_write_cache(BlockBackend *blk);
void blk_set_enable_write_cache(BlockBackend *blk, bool wce); void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
void blk_invalidate_cache(BlockBackend *blk, Error **errp);
int blk_is_inserted(BlockBackend *blk); int blk_is_inserted(BlockBackend *blk);
void blk_lock_medium(BlockBackend *blk, bool locked); void blk_lock_medium(BlockBackend *blk, bool locked);
void blk_eject(BlockBackend *blk, bool eject_flag); void blk_eject(BlockBackend *blk, bool eject_flag);
@ -132,6 +135,15 @@ void blk_op_block_all(BlockBackend *blk, Error *reason);
void blk_op_unblock_all(BlockBackend *blk, Error *reason); void blk_op_unblock_all(BlockBackend *blk, Error *reason);
AioContext *blk_get_aio_context(BlockBackend *blk); AioContext *blk_get_aio_context(BlockBackend *blk);
void blk_set_aio_context(BlockBackend *blk, AioContext *new_context); void blk_set_aio_context(BlockBackend *blk, AioContext *new_context);
void blk_add_aio_context_notifier(BlockBackend *blk,
void (*attached_aio_context)(AioContext *new_context, void *opaque),
void (*detach_aio_context)(void *opaque), void *opaque);
void blk_remove_aio_context_notifier(BlockBackend *blk,
void (*attached_aio_context)(AioContext *,
void *),
void (*detach_aio_context)(void *),
void *opaque);
void blk_add_close_notifier(BlockBackend *blk, Notifier *notify);
void blk_io_plug(BlockBackend *blk); void blk_io_plug(BlockBackend *blk);
void blk_io_unplug(BlockBackend *blk); void blk_io_unplug(BlockBackend *blk);
BlockAcctStats *blk_get_stats(BlockBackend *blk); BlockAcctStats *blk_get_stats(BlockBackend *blk);

View File

@ -2628,10 +2628,10 @@ static mon_cmd_t info_cmds[] = {
}, },
{ {
.name = "block", .name = "block",
.args_type = "verbose:-v,device:B?", .args_type = "nodes:-n,verbose:-v,device:B?",
.params = "[-v] [device]", .params = "[-n] [-v] [device]",
.help = "show info of one block device or all block devices " .help = "show info of one block device or all block devices "
"(and details of images with -v option)", "(-n: show named nodes; -v: show details)",
.mhandler.cmd = hmp_info_block, .mhandler.cmd = hmp_info_block,
}, },
{ {
@ -4695,7 +4695,7 @@ static void monitor_find_completion_by_table(Monitor *mon,
} }
} }
str = args[nb_args - 1]; str = args[nb_args - 1];
if (*ptype == '-' && ptype[1] != '\0') { while (*ptype == '-' && ptype[1] != '\0') {
ptype = next_arg_type(ptype); ptype = next_arg_type(ptype);
} }
switch(*ptype) { switch(*ptype) {

63
nbd.c
View File

@ -17,8 +17,7 @@
*/ */
#include "block/nbd.h" #include "block/nbd.h"
#include "block/block.h" #include "sysemu/block-backend.h"
#include "block/block_int.h"
#include "block/coroutine.h" #include "block/coroutine.h"
@ -101,7 +100,7 @@ struct NBDExport {
int refcount; int refcount;
void (*close)(NBDExport *exp); void (*close)(NBDExport *exp);
BlockDriverState *bs; BlockBackend *blk;
char *name; char *name;
off_t dev_offset; off_t dev_offset;
off_t size; off_t size;
@ -929,7 +928,7 @@ static void nbd_request_put(NBDRequest *req)
nbd_client_put(client); nbd_client_put(client);
} }
static void bs_aio_attached(AioContext *ctx, void *opaque) static void blk_aio_attached(AioContext *ctx, void *opaque)
{ {
NBDExport *exp = opaque; NBDExport *exp = opaque;
NBDClient *client; NBDClient *client;
@ -943,7 +942,7 @@ static void bs_aio_attached(AioContext *ctx, void *opaque)
} }
} }
static void bs_aio_detach(void *opaque) static void blk_aio_detach(void *opaque)
{ {
NBDExport *exp = opaque; NBDExport *exp = opaque;
NBDClient *client; NBDClient *client;
@ -957,27 +956,26 @@ static void bs_aio_detach(void *opaque)
exp->ctx = NULL; exp->ctx = NULL;
} }
NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset, NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
off_t size, uint32_t nbdflags, uint32_t nbdflags, void (*close)(NBDExport *))
void (*close)(NBDExport *))
{ {
NBDExport *exp = g_malloc0(sizeof(NBDExport)); NBDExport *exp = g_malloc0(sizeof(NBDExport));
exp->refcount = 1; exp->refcount = 1;
QTAILQ_INIT(&exp->clients); QTAILQ_INIT(&exp->clients);
exp->bs = bs; exp->blk = blk;
exp->dev_offset = dev_offset; exp->dev_offset = dev_offset;
exp->nbdflags = nbdflags; exp->nbdflags = nbdflags;
exp->size = size == -1 ? bdrv_getlength(bs) : size; exp->size = size == -1 ? blk_getlength(blk) : size;
exp->close = close; exp->close = close;
exp->ctx = bdrv_get_aio_context(bs); exp->ctx = blk_get_aio_context(blk);
bdrv_ref(bs); blk_ref(blk);
bdrv_add_aio_context_notifier(bs, bs_aio_attached, bs_aio_detach, exp); blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, exp);
/* /*
* NBD exports are used for non-shared storage migration. Make sure * NBD exports are used for non-shared storage migration. Make sure
* that BDRV_O_INCOMING is cleared and the image is ready for write * that BDRV_O_INCOMING is cleared and the image is ready for write
* access since the export could be available before migration handover. * access since the export could be available before migration handover.
*/ */
bdrv_invalidate_cache(bs, NULL); blk_invalidate_cache(blk, NULL);
return exp; return exp;
} }
@ -1024,11 +1022,11 @@ void nbd_export_close(NBDExport *exp)
} }
nbd_export_set_name(exp, NULL); nbd_export_set_name(exp, NULL);
nbd_export_put(exp); nbd_export_put(exp);
if (exp->bs) { if (exp->blk) {
bdrv_remove_aio_context_notifier(exp->bs, bs_aio_attached, blk_remove_aio_context_notifier(exp->blk, blk_aio_attached,
bs_aio_detach, exp); blk_aio_detach, exp);
bdrv_unref(exp->bs); blk_unref(exp->blk);
exp->bs = NULL; exp->blk = NULL;
} }
} }
@ -1056,9 +1054,9 @@ void nbd_export_put(NBDExport *exp)
} }
} }
BlockDriverState *nbd_export_get_blockdev(NBDExport *exp) BlockBackend *nbd_export_get_blockdev(NBDExport *exp)
{ {
return exp->bs; return exp->blk;
} }
void nbd_export_close_all(void) void nbd_export_close_all(void)
@ -1137,7 +1135,7 @@ static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *reque
command = request->type & NBD_CMD_MASK_COMMAND; command = request->type & NBD_CMD_MASK_COMMAND;
if (command == NBD_CMD_READ || command == NBD_CMD_WRITE) { if (command == NBD_CMD_READ || command == NBD_CMD_WRITE) {
req->data = qemu_blockalign(client->exp->bs, request->len); req->data = blk_blockalign(client->exp->blk, request->len);
} }
if (command == NBD_CMD_WRITE) { if (command == NBD_CMD_WRITE) {
TRACE("Reading %u byte(s)", request->len); TRACE("Reading %u byte(s)", request->len);
@ -1203,7 +1201,7 @@ static void nbd_trip(void *opaque)
TRACE("Request type is READ"); TRACE("Request type is READ");
if (request.type & NBD_CMD_FLAG_FUA) { if (request.type & NBD_CMD_FLAG_FUA) {
ret = bdrv_co_flush(exp->bs); ret = blk_co_flush(exp->blk);
if (ret < 0) { if (ret < 0) {
LOG("flush failed"); LOG("flush failed");
reply.error = -ret; reply.error = -ret;
@ -1211,8 +1209,9 @@ static void nbd_trip(void *opaque)
} }
} }
ret = bdrv_read(exp->bs, (request.from + exp->dev_offset) / 512, ret = blk_read(exp->blk,
req->data, request.len / 512); (request.from + exp->dev_offset) / BDRV_SECTOR_SIZE,
req->data, request.len / BDRV_SECTOR_SIZE);
if (ret < 0) { if (ret < 0) {
LOG("reading from file failed"); LOG("reading from file failed");
reply.error = -ret; reply.error = -ret;
@ -1234,8 +1233,9 @@ static void nbd_trip(void *opaque)
TRACE("Writing to device"); TRACE("Writing to device");
ret = bdrv_write(exp->bs, (request.from + exp->dev_offset) / 512, ret = blk_write(exp->blk,
req->data, request.len / 512); (request.from + exp->dev_offset) / BDRV_SECTOR_SIZE,
req->data, request.len / BDRV_SECTOR_SIZE);
if (ret < 0) { if (ret < 0) {
LOG("writing to file failed"); LOG("writing to file failed");
reply.error = -ret; reply.error = -ret;
@ -1243,7 +1243,7 @@ static void nbd_trip(void *opaque)
} }
if (request.type & NBD_CMD_FLAG_FUA) { if (request.type & NBD_CMD_FLAG_FUA) {
ret = bdrv_co_flush(exp->bs); ret = blk_co_flush(exp->blk);
if (ret < 0) { if (ret < 0) {
LOG("flush failed"); LOG("flush failed");
reply.error = -ret; reply.error = -ret;
@ -1262,7 +1262,7 @@ static void nbd_trip(void *opaque)
case NBD_CMD_FLUSH: case NBD_CMD_FLUSH:
TRACE("Request type is FLUSH"); TRACE("Request type is FLUSH");
ret = bdrv_co_flush(exp->bs); ret = blk_co_flush(exp->blk);
if (ret < 0) { if (ret < 0) {
LOG("flush failed"); LOG("flush failed");
reply.error = -ret; reply.error = -ret;
@ -1273,8 +1273,9 @@ static void nbd_trip(void *opaque)
break; break;
case NBD_CMD_TRIM: case NBD_CMD_TRIM:
TRACE("Request type is TRIM"); TRACE("Request type is TRIM");
ret = bdrv_co_discard(exp->bs, (request.from + exp->dev_offset) / 512, ret = blk_co_discard(exp->blk, (request.from + exp->dev_offset)
request.len / 512); / BDRV_SECTOR_SIZE,
request.len / BDRV_SECTOR_SIZE);
if (ret < 0) { if (ret < 0) {
LOG("discard failed"); LOG("discard failed");
reply.error = -ret; reply.error = -ret;

View File

@ -182,6 +182,22 @@
'*total-clusters': 'int', '*allocated-clusters': 'int', '*total-clusters': 'int', '*allocated-clusters': 'int',
'*fragmented-clusters': 'int', '*compressed-clusters': 'int' } } '*fragmented-clusters': 'int', '*compressed-clusters': 'int' } }
##
# @BlockdevCacheInfo
#
# Cache mode information for a block device
#
# @writeback: true if writeback mode is enabled
# @direct: true if the host page cache is bypassed (O_DIRECT)
# @no-flush: true if flush requests are ignored for the device
#
# Since: 2.3
##
{ 'type': 'BlockdevCacheInfo',
'data': { 'writeback': 'bool',
'direct': 'bool',
'no-flush': 'bool' } }
## ##
# @BlockDeviceInfo: # @BlockDeviceInfo:
# #
@ -239,6 +255,8 @@
# #
# @iops_size: #optional an I/O size in bytes (Since 1.7) # @iops_size: #optional an I/O size in bytes (Since 1.7)
# #
# @cache: the cache mode used for the block device (since: 2.3)
#
# Since: 0.14.0 # Since: 0.14.0
# #
## ##
@ -253,7 +271,7 @@
'*bps_max': 'int', '*bps_rd_max': 'int', '*bps_max': 'int', '*bps_rd_max': 'int',
'*bps_wr_max': 'int', '*iops_max': 'int', '*bps_wr_max': 'int', '*iops_max': 'int',
'*iops_rd_max': 'int', '*iops_wr_max': 'int', '*iops_rd_max': 'int', '*iops_wr_max': 'int',
'*iops_size': 'int' } } '*iops_size': 'int', 'cache': 'BlockdevCacheInfo' } }
## ##
# @BlockDeviceIoStatus: # @BlockDeviceIoStatus:
@ -405,6 +423,8 @@
# @device: #optional If the stats are for a virtual block device, the name # @device: #optional If the stats are for a virtual block device, the name
# corresponding to the virtual block device. # corresponding to the virtual block device.
# #
# @device: #optional The node name of the device. (Since 2.3)
#
# @stats: A @BlockDeviceStats for the device. # @stats: A @BlockDeviceStats for the device.
# #
# @parent: #optional This describes the file block device if it has one. # @parent: #optional This describes the file block device if it has one.
@ -415,7 +435,8 @@
# Since: 0.14.0 # Since: 0.14.0
## ##
{ 'type': 'BlockStats', { 'type': 'BlockStats',
'data': {'*device': 'str', 'stats': 'BlockDeviceStats', 'data': {'*device': 'str', '*node-name': 'str',
'stats': 'BlockDeviceStats',
'*parent': 'BlockStats', '*parent': 'BlockStats',
'*backing': 'BlockStats'} } '*backing': 'BlockStats'} }
@ -424,11 +445,20 @@
# #
# Query the @BlockStats for all virtual block devices. # Query the @BlockStats for all virtual block devices.
# #
# @query-nodes: #optional If true, the command will query all the block nodes
# that have a node name, in a list which will include "parent"
# information, but not "backing".
# If false or omitted, the behavior is as before - query all the
# device backends, recursively including their "parent" and
# "backing". (Since 2.3)
#
# Returns: A list of @BlockStats for each virtual block devices. # Returns: A list of @BlockStats for each virtual block devices.
# #
# Since: 0.14.0 # Since: 0.14.0
## ##
{ 'command': 'query-blockstats', 'returns': ['BlockStats'] } { 'command': 'query-blockstats',
'data': { '*query-nodes': 'bool' },
'returns': ['BlockStats'] }
## ##
# @BlockdevOnError: # @BlockdevOnError:

View File

@ -1531,6 +1531,20 @@ static int img_convert(int argc, char **argv)
goto out; goto out;
} }
if (!drv->create_opts) {
error_report("Format driver '%s' does not support image creation",
drv->format_name);
ret = -1;
goto out;
}
if (!proto_drv->create_opts) {
error_report("Protocol driver '%s' does not support image creation",
proto_drv->format_name);
ret = -1;
goto out;
}
create_opts = qemu_opts_append(create_opts, drv->create_opts); create_opts = qemu_opts_append(create_opts, drv->create_opts);
create_opts = qemu_opts_append(create_opts, proto_drv->create_opts); create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
@ -2972,6 +2986,13 @@ static int img_amend(int argc, char **argv)
goto out; goto out;
} }
if (!bs->drv->create_opts) {
error_report("Format driver '%s' does not support any options to amend",
fmt);
ret = -1;
goto out;
}
create_opts = qemu_opts_append(create_opts, bs->drv->create_opts); create_opts = qemu_opts_append(create_opts, bs->drv->create_opts);
opts = qemu_opts_create(create_opts, NULL, 0, &error_abort); opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
if (options && qemu_opts_do_parse(opts, options, NULL)) { if (options && qemu_opts_do_parse(opts, options, NULL)) {

View File

@ -51,7 +51,8 @@ static const cmdinfo_t close_cmd = {
.oneline = "close the current open file", .oneline = "close the current open file",
}; };
static int openfile(char *name, int flags, int growable, QDict *opts) static int openfile(char *name, BlockDriver *drv, int flags, int growable,
QDict *opts)
{ {
Error *local_err = NULL; Error *local_err = NULL;
@ -68,7 +69,7 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
flags |= BDRV_O_PROTOCOL; flags |= BDRV_O_PROTOCOL;
} }
if (bdrv_open(&qemuio_bs, name, NULL, opts, flags, NULL, &local_err) < 0) { if (bdrv_open(&qemuio_bs, name, NULL, opts, flags, drv, &local_err) < 0) {
fprintf(stderr, "%s: can't open%s%s: %s\n", progname, fprintf(stderr, "%s: can't open%s%s: %s\n", progname,
name ? " device " : "", name ?: "", name ? " device " : "", name ?: "",
error_get_pretty(local_err)); error_get_pretty(local_err));
@ -169,9 +170,9 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
qemu_opts_reset(&empty_opts); qemu_opts_reset(&empty_opts);
if (optind == argc - 1) { if (optind == argc - 1) {
return openfile(argv[optind], flags, growable, opts); return openfile(argv[optind], NULL, flags, growable, opts);
} else if (optind == argc) { } else if (optind == argc) {
return openfile(NULL, flags, growable, opts); return openfile(NULL, NULL, flags, growable, opts);
} else { } else {
QDECREF(opts); QDECREF(opts);
return qemuio_command_usage(&open_cmd); return qemuio_command_usage(&open_cmd);
@ -196,11 +197,12 @@ static const cmdinfo_t quit_cmd = {
static void usage(const char *name) static void usage(const char *name)
{ {
printf( printf(
"Usage: %s [-h] [-V] [-rsnm] [-c STRING] ... [file]\n" "Usage: %s [-h] [-V] [-rsnm] [-f FMT] [-c STRING] ... [file]\n"
"QEMU Disk exerciser\n" "QEMU Disk exerciser\n"
"\n" "\n"
" -c, --cmd STRING execute command with its arguments\n" " -c, --cmd STRING execute command with its arguments\n"
" from the given string\n" " from the given string\n"
" -f, --format FMT specifies the block driver to use\n"
" -r, --read-only export read-only\n" " -r, --read-only export read-only\n"
" -s, --snapshot use snapshot file\n" " -s, --snapshot use snapshot file\n"
" -n, --nocache disable host cache\n" " -n, --nocache disable host cache\n"
@ -364,12 +366,13 @@ int main(int argc, char **argv)
{ {
int readonly = 0; int readonly = 0;
int growable = 0; int growable = 0;
const char *sopt = "hVc:d:rsnmgkt:T:"; const char *sopt = "hVc:d:f:rsnmgkt:T:";
const struct option lopt[] = { const struct option lopt[] = {
{ "help", 0, NULL, 'h' }, { "help", 0, NULL, 'h' },
{ "version", 0, NULL, 'V' }, { "version", 0, NULL, 'V' },
{ "offset", 1, NULL, 'o' }, { "offset", 1, NULL, 'o' },
{ "cmd", 1, NULL, 'c' }, { "cmd", 1, NULL, 'c' },
{ "format", 1, NULL, 'f' },
{ "read-only", 0, NULL, 'r' }, { "read-only", 0, NULL, 'r' },
{ "snapshot", 0, NULL, 's' }, { "snapshot", 0, NULL, 's' },
{ "nocache", 0, NULL, 'n' }, { "nocache", 0, NULL, 'n' },
@ -384,6 +387,7 @@ int main(int argc, char **argv)
int c; int c;
int opt_index = 0; int opt_index = 0;
int flags = BDRV_O_UNMAP; int flags = BDRV_O_UNMAP;
BlockDriver *drv = NULL;
Error *local_error = NULL; Error *local_error = NULL;
#ifdef CONFIG_POSIX #ifdef CONFIG_POSIX
@ -393,6 +397,8 @@ int main(int argc, char **argv)
progname = basename(argv[0]); progname = basename(argv[0]);
qemu_init_exec_dir(argv[0]); qemu_init_exec_dir(argv[0]);
bdrv_init();
while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) { while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
switch (c) { switch (c) {
case 's': case 's':
@ -407,6 +413,13 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
break; break;
case 'f':
drv = bdrv_find_format(optarg);
if (!drv) {
error_report("Invalid format '%s'", optarg);
exit(EXIT_FAILURE);
}
break;
case 'c': case 'c':
add_user_command(optarg); add_user_command(optarg);
break; break;
@ -455,7 +468,6 @@ int main(int argc, char **argv)
error_free(local_error); error_free(local_error);
exit(1); exit(1);
} }
bdrv_init();
/* initialize commands */ /* initialize commands */
qemuio_add_command(&quit_cmd); qemuio_add_command(&quit_cmd);
@ -477,7 +489,7 @@ int main(int argc, char **argv)
} }
if ((argc - optind) == 1) { if ((argc - optind) == 1) {
openfile(argv[optind], flags, growable, NULL); openfile(argv[optind], drv, flags, growable, NULL);
} }
command_loop(); command_loop();

View File

@ -146,7 +146,7 @@ static void read_partition(uint8_t *p, struct partition_record *r)
r->nb_sectors_abs = p[12] | p[13] << 8 | p[14] << 16 | p[15] << 24; r->nb_sectors_abs = p[12] | p[13] << 8 | p[14] << 16 | p[15] << 24;
} }
static int find_partition(BlockDriverState *bs, int partition, static int find_partition(BlockBackend *blk, int partition,
off_t *offset, off_t *size) off_t *offset, off_t *size)
{ {
struct partition_record mbr[4]; struct partition_record mbr[4];
@ -155,7 +155,7 @@ static int find_partition(BlockDriverState *bs, int partition,
int ext_partnum = 4; int ext_partnum = 4;
int ret; int ret;
if ((ret = bdrv_read(bs, 0, data, 1)) < 0) { if ((ret = blk_read(blk, 0, data, 1)) < 0) {
errno = -ret; errno = -ret;
err(EXIT_FAILURE, "error while reading"); err(EXIT_FAILURE, "error while reading");
} }
@ -175,7 +175,7 @@ static int find_partition(BlockDriverState *bs, int partition,
uint8_t data1[512]; uint8_t data1[512];
int j; int j;
if ((ret = bdrv_read(bs, mbr[i].start_sector_abs, data1, 1)) < 0) { if ((ret = blk_read(blk, mbr[i].start_sector_abs, data1, 1)) < 0) {
errno = -ret; errno = -ret;
err(EXIT_FAILURE, "error while reading"); err(EXIT_FAILURE, "error while reading");
} }
@ -720,17 +720,17 @@ int main(int argc, char **argv)
} }
bs->detect_zeroes = detect_zeroes; bs->detect_zeroes = detect_zeroes;
fd_size = bdrv_getlength(bs); fd_size = blk_getlength(blk);
if (partition != -1) { if (partition != -1) {
ret = find_partition(bs, partition, &dev_offset, &fd_size); ret = find_partition(blk, partition, &dev_offset, &fd_size);
if (ret < 0) { if (ret < 0) {
errno = -ret; errno = -ret;
err(EXIT_FAILURE, "Could not find partition %d", partition); err(EXIT_FAILURE, "Could not find partition %d", partition);
} }
} }
exp = nbd_export_new(bs, dev_offset, fd_size, nbdflags, nbd_export_closed); exp = nbd_export_new(blk, dev_offset, fd_size, nbdflags, nbd_export_closed);
if (sockpath) { if (sockpath) {
fd = unix_socket_incoming(sockpath); fd = unix_socket_incoming(sockpath);

View File

@ -2790,6 +2790,14 @@ STEXI
@findex -qmp @findex -qmp
Like -monitor but opens in 'control' mode. Like -monitor but opens in 'control' mode.
ETEXI ETEXI
DEF("qmp-pretty", HAS_ARG, QEMU_OPTION_qmp_pretty, \
"-qmp-pretty dev like -qmp but uses pretty JSON formatting\n",
QEMU_ARCH_ALL)
STEXI
@item -qmp-pretty @var{dev}
@findex -qmp-pretty
Like -qmp but uses pretty JSON formatting.
ETEXI
DEF("mon", HAS_ARG, QEMU_OPTION_mon, \ DEF("mon", HAS_ARG, QEMU_OPTION_mon, \
"-mon [chardev=]name[,mode=readline|control][,default]\n", QEMU_ARCH_ALL) "-mon [chardev=]name[,mode=readline|control][,default]\n", QEMU_ARCH_ALL)

View File

@ -2347,7 +2347,7 @@ EQMP
{ {
.name = "query-blockstats", .name = "query-blockstats",
.args_type = "", .args_type = "query-nodes:b?",
.mhandler.cmd_new = qmp_marshal_input_query_blockstats, .mhandler.cmd_new = qmp_marshal_input_query_blockstats,
}, },

View File

@ -86,8 +86,9 @@ static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
QString *qkey; QString *qkey;
int j; int j;
if (s->count) if (s->count) {
qstring_append(s->str, ", "); qstring_append(s->str, s->pretty ? "," : ", ");
}
if (s->pretty) { if (s->pretty) {
qstring_append(s->str, "\n"); qstring_append(s->str, "\n");
@ -109,8 +110,9 @@ static void to_json_list_iter(QObject *obj, void *opaque)
ToJsonIterState *s = opaque; ToJsonIterState *s = opaque;
int j; int j;
if (s->count) if (s->count) {
qstring_append(s->str, ", "); qstring_append(s->str, s->pretty ? "," : ", ");
}
if (s->pretty) { if (s->pretty) {
qstring_append(s->str, "\n"); qstring_append(s->str, "\n");

View File

@ -487,7 +487,8 @@ static void qtest_shutdown(void)
*/ */
static QPCIDevice *ahci_boot(void) static QPCIDevice *ahci_boot(void)
{ {
qtest_boot("-drive if=none,id=drive0,file=%s,cache=writeback,serial=%s" qtest_boot("-drive if=none,id=drive0,file=%s,cache=writeback,serial=%s,"
"format=raw"
" -M q35 " " -M q35 "
"-device ide-hd,drive=drive0 " "-device ide-hd,drive=drive0 "
"-global ide-hd.ver=%s", "-global ide-hd.ver=%s",

View File

@ -716,7 +716,7 @@ static void test_acpi_one(const char *params, test_data *data)
int i; int i;
args = g_strdup_printf("-net none -display none %s " args = g_strdup_printf("-net none -display none %s "
"-drive id=hd0,if=none,file=%s " "-drive id=hd0,if=none,file=%s,format=raw "
"-device ide-hd,drive=hd0 ", "-device ide-hd,drive=hd0 ",
params ? params : "", disk); params ? params : "", disk);

View File

@ -103,7 +103,7 @@ static void test_after_failed_device_add(void)
static void test_drive_del_device_del(void) static void test_drive_del_device_del(void)
{ {
/* Start with a drive used by a device that unplugs instantaneously */ /* Start with a drive used by a device that unplugs instantaneously */
qtest_start("-drive if=none,id=drive0,file=/dev/null" qtest_start("-drive if=none,id=drive0,file=/dev/null,format=raw"
" -device virtio-scsi-pci" " -device virtio-scsi-pci"
" -device scsi-hd,drive=drive0,id=dev0"); " -device scsi-hd,drive=drive0,id=dev0");

View File

@ -291,7 +291,7 @@ static void test_media_insert(void)
/* Insert media in drive. DSKCHK should not be reset until a step pulse /* Insert media in drive. DSKCHK should not be reset until a step pulse
* is sent. */ * is sent. */
qmp_discard_response("{'execute':'change', 'arguments':{" qmp_discard_response("{'execute':'change', 'arguments':{"
" 'device':'floppy0', 'target': %s }}", " 'device':'floppy0', 'target': %s, 'arg': 'raw' }}",
test_image); test_image);
qmp_discard_response(""); /* ignore event qmp_discard_response(""); /* ignore event
(FIXME open -> open transition?!) */ (FIXME open -> open transition?!) */

View File

@ -208,7 +208,7 @@ static int setup_ide(int argc, char *argv[], int argv_sz,
{ {
char *s1, *s2, *s3; char *s1, *s2, *s3;
s1 = g_strdup_printf("-drive id=drive%d,if=%s", s1 = g_strdup_printf("-drive id=drive%d,if=%s,format=raw",
ide_idx, dev ? "none" : "ide"); ide_idx, dev ? "none" : "ide");
s2 = dev ? g_strdup("") : g_strdup_printf(",index=%d", ide_idx); s2 = dev ? g_strdup("") : g_strdup_printf(",index=%d", ide_idx);

View File

@ -342,8 +342,9 @@ static void test_i440fx_firmware(FirmwareTestFixture *fixture,
g_assert(fw_pathname != NULL); g_assert(fw_pathname != NULL);
/* Better hope the user didn't put metacharacters in TMPDIR and co. */ /* Better hope the user didn't put metacharacters in TMPDIR and co. */
cmdline = g_strdup_printf("-S %s %s", cmdline = g_strdup_printf("-S %s%s", fixture->is_bios
fixture->is_bios ? "-bios" : "-pflash", ? "-bios "
: "-drive if=pflash,format=raw,file=",
fw_pathname); fw_pathname);
g_test_message("qemu cmdline: %s", cmdline); g_test_message("qemu cmdline: %s", cmdline);
qtest_start(cmdline); qtest_start(cmdline);

View File

@ -385,7 +385,7 @@ static void test_bmdma_no_busmaster(void)
static void test_bmdma_setup(void) static void test_bmdma_setup(void)
{ {
ide_test_start( ide_test_start(
"-drive file=%s,if=ide,serial=%s,cache=writeback " "-drive file=%s,if=ide,serial=%s,cache=writeback,format=raw "
"-global ide-hd.ver=%s", "-global ide-hd.ver=%s",
tmp_path, "testdisk", "version"); tmp_path, "testdisk", "version");
} }
@ -414,7 +414,7 @@ static void test_identify(void)
int ret; int ret;
ide_test_start( ide_test_start(
"-drive file=%s,if=ide,serial=%s,cache=writeback " "-drive file=%s,if=ide,serial=%s,cache=writeback,format=raw "
"-global ide-hd.ver=%s", "-global ide-hd.ver=%s",
tmp_path, "testdisk", "version"); tmp_path, "testdisk", "version");
@ -458,7 +458,7 @@ static void test_flush(void)
uint8_t data; uint8_t data;
ide_test_start( ide_test_start(
"-drive file=blkdebug::%s,if=ide,cache=writeback", "-drive file=blkdebug::%s,if=ide,cache=writeback,format=raw",
tmp_path); tmp_path);
/* Delay the completion of the flush request until we explicitly do it */ /* Delay the completion of the flush request until we explicitly do it */
@ -526,7 +526,8 @@ static void test_retry_flush(void)
ide_test_start( ide_test_start(
"-vnc none " "-vnc none "
"-drive file=blkdebug:%s:%s,if=ide,cache=writeback,rerror=stop,werror=stop", "-drive file=blkdebug:%s:%s,if=ide,cache=writeback,format=raw,"
"rerror=stop,werror=stop",
debug_path, tmp_path); debug_path, tmp_path);
/* FLUSH CACHE command on device 0*/ /* FLUSH CACHE command on device 0*/

View File

@ -24,7 +24,7 @@ int main(int argc, char **argv)
g_test_init(&argc, &argv, NULL); g_test_init(&argc, &argv, NULL);
qtest_add_func("/nvme/nop", nop); qtest_add_func("/nvme/nop", nop);
qtest_start("-drive id=drv0,if=none,file=/dev/null " qtest_start("-drive id=drv0,if=none,file=/dev/null,format=raw "
"-device nvme,drive=drv0,serial=foo"); "-device nvme,drive=drv0,serial=foo");
ret = g_test_run(); ret = g_test_run();

View File

@ -43,25 +43,28 @@ _supported_proto file sheepdog nfs
_supported_os Linux _supported_os Linux
# No -f, use probing for the protocol driver
QEMU_IO_PROTO="$QEMU_IO_PROG -g --cache $CACHEMODE"
size=128M size=128M
_make_test_img $size _make_test_img $size
echo echo
echo "== reading at EOF ==" echo "== reading at EOF =="
$QEMU_IO -g -c "read -P 0 $size 512" "$TEST_IMG" | _filter_qemu_io $QEMU_IO_PROTO -c "read -P 0 $size 512" "$TEST_IMG" | _filter_qemu_io
echo echo
echo "== reading far past EOF ==" echo "== reading far past EOF =="
$QEMU_IO -g -c "read -P 0 256M 512" "$TEST_IMG" | _filter_qemu_io $QEMU_IO_PROTO -c "read -P 0 256M 512" "$TEST_IMG" | _filter_qemu_io
echo echo
echo "== writing at EOF ==" echo "== writing at EOF =="
$QEMU_IO -g -c "write -P 66 $size 512" "$TEST_IMG" | _filter_qemu_io $QEMU_IO_PROTO -c "write -P 66 $size 512" "$TEST_IMG" | _filter_qemu_io
$QEMU_IO -c "read -P 66 $size 512" "$TEST_IMG" | _filter_qemu_io $QEMU_IO -c "read -P 66 $size 512" "$TEST_IMG" | _filter_qemu_io
echo echo
echo "== writing far past EOF ==" echo "== writing far past EOF =="
$QEMU_IO -g -c "write -P 66 256M 512" "$TEST_IMG" | _filter_qemu_io $QEMU_IO_PROTO -c "write -P 66 256M 512" "$TEST_IMG" | _filter_qemu_io
$QEMU_IO -c "read -P 66 256M 512" "$TEST_IMG" | _filter_qemu_io $QEMU_IO -c "read -P 66 256M 512" "$TEST_IMG" | _filter_qemu_io
# success, all done # success, all done

View File

@ -14,6 +14,8 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 5; imm: off; once: off; write Event: l1_update; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
1 leaked clusters were found on the image. 1 leaked clusters were found on the image.
@ -21,6 +23,8 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 5; imm: off; once: off; write -b Event: l1_update; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
1 leaked clusters were found on the image. 1 leaked clusters were found on the image.
@ -38,6 +42,8 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 28; imm: off; once: off; write Event: l1_update; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
1 leaked clusters were found on the image. 1 leaked clusters were found on the image.
@ -45,6 +51,8 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_update; errno: 28; imm: off; once: off; write -b Event: l1_update; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
1 leaked clusters were found on the image. 1 leaked clusters were found on the image.
@ -70,7 +78,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 5; imm: off; once: off; write Event: l2_load; errno: 5; imm: off; once: off; write
wrote 131072/131072 bytes at offset 0 wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
read failed: Input/output error read failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -78,7 +90,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 5; imm: off; once: off; write -b Event: l2_load; errno: 5; imm: off; once: off; write -b
wrote 131072/131072 bytes at offset 0 wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
read failed: Input/output error read failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -102,7 +118,11 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 28; imm: off; once: off; write Event: l2_load; errno: 28; imm: off; once: off; write
wrote 131072/131072 bytes at offset 0 wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
read failed: No space left on device read failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -110,12 +130,17 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_load; errno: 28; imm: off; once: off; write -b Event: l2_load; errno: 28; imm: off; once: off; write -b
wrote 131072/131072 bytes at offset 0 wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
read failed: No space left on device read failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 5; imm: off; once: on; write Event: l2_update; errno: 5; imm: off; once: on; write
Failed to flush the L2 table cache: Input/output error
write failed: Input/output error write failed: Input/output error
127 leaked clusters were found on the image. 127 leaked clusters were found on the image.
@ -123,6 +148,7 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 5; imm: off; once: on; write -b Event: l2_update; errno: 5; imm: off; once: on; write -b
Failed to flush the L2 table cache: Input/output error
write failed: Input/output error write failed: Input/output error
127 leaked clusters were found on the image. 127 leaked clusters were found on the image.
@ -130,6 +156,8 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 5; imm: off; once: off; write Event: l2_update; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
127 leaked clusters were found on the image. 127 leaked clusters were found on the image.
@ -137,6 +165,8 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 5; imm: off; once: off; write -b Event: l2_update; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
127 leaked clusters were found on the image. 127 leaked clusters were found on the image.
@ -144,6 +174,7 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 28; imm: off; once: on; write Event: l2_update; errno: 28; imm: off; once: on; write
Failed to flush the L2 table cache: No space left on device
write failed: No space left on device write failed: No space left on device
127 leaked clusters were found on the image. 127 leaked clusters were found on the image.
@ -151,6 +182,7 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 28; imm: off; once: on; write -b Event: l2_update; errno: 28; imm: off; once: on; write -b
Failed to flush the L2 table cache: No space left on device
write failed: No space left on device write failed: No space left on device
127 leaked clusters were found on the image. 127 leaked clusters were found on the image.
@ -158,6 +190,8 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 28; imm: off; once: off; write Event: l2_update; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
127 leaked clusters were found on the image. 127 leaked clusters were found on the image.
@ -165,6 +199,8 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_update; errno: 28; imm: off; once: off; write -b Event: l2_update; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
127 leaked clusters were found on the image. 127 leaked clusters were found on the image.
@ -182,11 +218,15 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc.write; errno: 5; imm: off; once: off; write Event: l2_alloc.write; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc.write; errno: 5; imm: off; once: off; write -b Event: l2_alloc.write; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
1 leaked clusters were found on the image. 1 leaked clusters were found on the image.
@ -204,11 +244,15 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc.write; errno: 28; imm: off; once: off; write Event: l2_alloc.write; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l2_alloc.write; errno: 28; imm: off; once: off; write -b Event: l2_alloc.write; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
1 leaked clusters were found on the image. 1 leaked clusters were found on the image.
@ -226,11 +270,15 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 5; imm: off; once: off; write Event: write_aio; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 5; imm: off; once: off; write -b Event: write_aio; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -246,11 +294,15 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 28; imm: off; once: off; write Event: write_aio; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: write_aio; errno: 28; imm: off; once: off; write -b Event: write_aio; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -266,11 +318,15 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 5; imm: off; once: off; write Event: refblock_load; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 5; imm: off; once: off; write -b Event: refblock_load; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -286,51 +342,67 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 28; imm: off; once: off; write Event: refblock_load; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_load; errno: 28; imm: off; once: off; write -b Event: refblock_load; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: on; write Event: refblock_update_part; errno: 5; imm: off; once: on; write
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: on; write -b Event: refblock_update_part; errno: 5; imm: off; once: on; write -b
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: off; write Event: refblock_update_part; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 5; imm: off; once: off; write -b Event: refblock_update_part; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: on; write Event: refblock_update_part; errno: 28; imm: off; once: on; write
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: on; write -b Event: refblock_update_part; errno: 28; imm: off; once: on; write -b
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: off; write Event: refblock_update_part; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_update_part; errno: 28; imm: off; once: off; write -b Event: refblock_update_part; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -346,11 +418,15 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 5; imm: off; once: off; write Event: refblock_alloc; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 5; imm: off; once: off; write -b Event: refblock_alloc; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -366,11 +442,15 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 28; imm: off; once: off; write Event: refblock_alloc; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc; errno: 28; imm: off; once: off; write -b Event: refblock_alloc; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -386,11 +466,15 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 5; imm: off; once: off; write Event: cluster_alloc; errno: 5; imm: off; once: off; write
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 5; imm: off; once: off; write -b Event: cluster_alloc; errno: 5; imm: off; once: off; write -b
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -406,11 +490,15 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 28; imm: off; once: off; write Event: cluster_alloc; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: cluster_alloc; errno: 28; imm: off; once: off; write -b Event: cluster_alloc; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
@ -429,6 +517,8 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.hookup; errno: 28; imm: off; once: off; write Event: refblock_alloc.hookup; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
55 leaked clusters were found on the image. 55 leaked clusters were found on the image.
@ -436,6 +526,8 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.hookup; errno: 28; imm: off; once: off; write -b Event: refblock_alloc.hookup; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
251 leaked clusters were found on the image. 251 leaked clusters were found on the image.
@ -453,11 +545,15 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.write; errno: 28; imm: off; once: off; write Event: refblock_alloc.write; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.write; errno: 28; imm: off; once: off; write -b Event: refblock_alloc.write; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -473,6 +569,8 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.write_blocks; errno: 28; imm: off; once: off; write Event: refblock_alloc.write_blocks; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
11 leaked clusters were found on the image. 11 leaked clusters were found on the image.
@ -480,6 +578,8 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.write_blocks; errno: 28; imm: off; once: off; write -b Event: refblock_alloc.write_blocks; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
23 leaked clusters were found on the image. 23 leaked clusters were found on the image.
@ -497,6 +597,8 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.write_table; errno: 28; imm: off; once: off; write Event: refblock_alloc.write_table; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
11 leaked clusters were found on the image. 11 leaked clusters were found on the image.
@ -504,6 +606,8 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.write_table; errno: 28; imm: off; once: off; write -b Event: refblock_alloc.write_table; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
23 leaked clusters were found on the image. 23 leaked clusters were found on the image.
@ -521,6 +625,8 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.switch_table; errno: 28; imm: off; once: off; write Event: refblock_alloc.switch_table; errno: 28; imm: off; once: off; write
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
11 leaked clusters were found on the image. 11 leaked clusters were found on the image.
@ -528,6 +634,8 @@ This means waste of disk space, but no harm to data.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: refblock_alloc.switch_table; errno: 28; imm: off; once: off; write -b Event: refblock_alloc.switch_table; errno: 28; imm: off; once: off; write -b
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
23 leaked clusters were found on the image. 23 leaked clusters were found on the image.
@ -543,6 +651,8 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.alloc_table; errno: 5; imm: off; once: off Event: l1_grow.alloc_table; errno: 5; imm: off; once: off
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -553,6 +663,8 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.alloc_table; errno: 28; imm: off; once: off Event: l1_grow.alloc_table; errno: 28; imm: off; once: off
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -563,6 +675,8 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.write_table; errno: 5; imm: off; once: off Event: l1_grow.write_table; errno: 5; imm: off; once: off
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -573,6 +687,8 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.write_table; errno: 28; imm: off; once: off Event: l1_grow.write_table; errno: 28; imm: off; once: off
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
No errors were found on the image. No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
@ -583,6 +699,8 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.activate_table; errno: 5; imm: off; once: off Event: l1_grow.activate_table; errno: 5; imm: off; once: off
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
write failed: Input/output error write failed: Input/output error
96 leaked clusters were found on the image. 96 leaked clusters were found on the image.
@ -595,6 +713,8 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
Event: l1_grow.activate_table; errno: 28; imm: off; once: off Event: l1_grow.activate_table; errno: 28; imm: off; once: off
Failed to flush the L2 table cache: No space left on device
Failed to flush the refcount block cache: No space left on device
write failed: No space left on device write failed: No space left on device
96 leaked clusters were found on the image. 96 leaked clusters were found on the image.

View File

@ -34,7 +34,7 @@ class TestSingleDrive(iotests.QMPTestCase):
iotests.create_image(backing_img, TestSingleDrive.image_len) iotests.create_image(backing_img, TestSingleDrive.image_len)
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img) qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img) qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
qemu_io('-c', 'write -P 0x1 0 512', backing_img) qemu_io('-f', 'raw', '-c', 'write -P 0x1 0 512', backing_img)
self.vm = iotests.VM().add_drive("blkdebug::" + test_img) self.vm = iotests.VM().add_drive("blkdebug::" + test_img)
self.vm.launch() self.vm.launch()
@ -55,8 +55,8 @@ class TestSingleDrive(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.shutdown() self.vm.shutdown()
self.assertEqual(qemu_io('-c', 'map', backing_img), self.assertEqual(qemu_io('-f', 'raw', '-c', 'map', backing_img),
qemu_io('-c', 'map', test_img), qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
'image file map does not match backing file after streaming') 'image file map does not match backing file after streaming')
def test_stream_pause(self): def test_stream_pause(self):
@ -86,8 +86,8 @@ class TestSingleDrive(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.shutdown() self.vm.shutdown()
self.assertEqual(qemu_io('-c', 'map', backing_img), self.assertEqual(qemu_io('-f', 'raw', '-c', 'map', backing_img),
qemu_io('-c', 'map', test_img), qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
'image file map does not match backing file after streaming') 'image file map does not match backing file after streaming')
def test_stream_partial(self): def test_stream_partial(self):
@ -101,8 +101,8 @@ class TestSingleDrive(iotests.QMPTestCase):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
self.vm.shutdown() self.vm.shutdown()
self.assertEqual(qemu_io('-c', 'map', mid_img), self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', mid_img),
qemu_io('-c', 'map', test_img), qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
'image file map does not match backing file after streaming') 'image file map does not match backing file after streaming')
def test_device_not_found(self): def test_device_not_found(self):
@ -359,9 +359,9 @@ class TestStreamStop(iotests.QMPTestCase):
def setUp(self): def setUp(self):
qemu_img('create', backing_img, str(TestStreamStop.image_len)) qemu_img('create', backing_img, str(TestStreamStop.image_len))
qemu_io('-c', 'write -P 0x1 0 32M', backing_img) qemu_io('-f', 'raw', '-c', 'write -P 0x1 0 32M', backing_img)
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
qemu_io('-c', 'write -P 0x1 32M 32M', test_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x1 32M 32M', test_img)
self.vm = iotests.VM().add_drive("blkdebug::" + test_img) self.vm = iotests.VM().add_drive("blkdebug::" + test_img)
self.vm.launch() self.vm.launch()
@ -388,9 +388,9 @@ class TestSetSpeed(iotests.QMPTestCase):
def setUp(self): def setUp(self):
qemu_img('create', backing_img, str(TestSetSpeed.image_len)) qemu_img('create', backing_img, str(TestSetSpeed.image_len))
qemu_io('-c', 'write -P 0x1 0 32M', backing_img) qemu_io('-f', 'raw', '-c', 'write -P 0x1 0 32M', backing_img)
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img) qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, test_img)
qemu_io('-c', 'write -P 0x1 32M 32M', test_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x1 32M 32M', test_img)
self.vm = iotests.VM().add_drive('blkdebug::' + test_img) self.vm = iotests.VM().add_drive('blkdebug::' + test_img)
self.vm.launch() self.vm.launch()

View File

@ -76,8 +76,8 @@ class TestSingleDrive(ImageCommitTestCase):
iotests.create_image(backing_img, self.image_len) iotests.create_image(backing_img, self.image_len)
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img) qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img) qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
qemu_io('-c', 'write -P 0xab 0 524288', backing_img) qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', backing_img)
qemu_io('-c', 'write -P 0xef 524288 524288', mid_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img)
self.vm = iotests.VM().add_drive(test_img) self.vm = iotests.VM().add_drive(test_img)
self.vm.launch() self.vm.launch()
@ -89,8 +89,8 @@ class TestSingleDrive(ImageCommitTestCase):
def test_commit(self): def test_commit(self):
self.run_commit_test(mid_img, backing_img) self.run_commit_test(mid_img, backing_img)
self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', backing_img).find("verification failed")) self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed")) self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
def test_device_not_found(self): def test_device_not_found(self):
result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % mid_img) result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % mid_img)
@ -116,13 +116,13 @@ class TestSingleDrive(ImageCommitTestCase):
def test_top_is_active(self): def test_top_is_active(self):
self.run_commit_test(test_img, backing_img, need_ready=True) self.run_commit_test(test_img, backing_img, need_ready=True)
self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', backing_img).find("verification failed")) self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed")) self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
def test_top_is_default_active(self): def test_top_is_default_active(self):
self.run_default_commit_test() self.run_default_commit_test()
self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', backing_img).find("verification failed")) self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', backing_img).find("verification failed"))
self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed")) self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
def test_top_and_base_reversed(self): def test_top_and_base_reversed(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
@ -159,8 +159,8 @@ class TestRelativePaths(ImageCommitTestCase):
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.mid_img_abs, self.test_img) qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % self.mid_img_abs, self.test_img)
qemu_img('rebase', '-u', '-b', self.backing_img, self.mid_img_abs) qemu_img('rebase', '-u', '-b', self.backing_img, self.mid_img_abs)
qemu_img('rebase', '-u', '-b', self.mid_img, self.test_img) qemu_img('rebase', '-u', '-b', self.mid_img, self.test_img)
qemu_io('-c', 'write -P 0xab 0 524288', self.backing_img_abs) qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', self.backing_img_abs)
qemu_io('-c', 'write -P 0xef 524288 524288', self.mid_img_abs) qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', self.mid_img_abs)
self.vm = iotests.VM().add_drive(self.test_img) self.vm = iotests.VM().add_drive(self.test_img)
self.vm.launch() self.vm.launch()
@ -179,8 +179,8 @@ class TestRelativePaths(ImageCommitTestCase):
def test_commit(self): def test_commit(self):
self.run_commit_test(self.mid_img, self.backing_img) self.run_commit_test(self.mid_img, self.backing_img)
self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed")) self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed"))
self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed")) self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed"))
def test_device_not_found(self): def test_device_not_found(self):
result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % self.mid_img) result = self.vm.qmp('block-commit', device='nonexistent', top='%s' % self.mid_img)
@ -206,8 +206,8 @@ class TestRelativePaths(ImageCommitTestCase):
def test_top_is_active(self): def test_top_is_active(self):
self.run_commit_test(self.test_img, self.backing_img) self.run_commit_test(self.test_img, self.backing_img)
self.assertEqual(-1, qemu_io('-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed")) self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xab 0 524288', self.backing_img_abs).find("verification failed"))
self.assertEqual(-1, qemu_io('-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed")) self.assertEqual(-1, qemu_io('-f', 'raw', '-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed"))
def test_top_and_base_reversed(self): def test_top_and_base_reversed(self):
self.assert_no_active_block_jobs() self.assert_no_active_block_jobs()
@ -223,8 +223,8 @@ class TestSetSpeed(ImageCommitTestCase):
qemu_img('create', backing_img, str(TestSetSpeed.image_len)) qemu_img('create', backing_img, str(TestSetSpeed.image_len))
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img) qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % backing_img, mid_img)
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img) qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
qemu_io('-c', 'write -P 0x1 0 512', test_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x1 0 512', test_img)
qemu_io('-c', 'write -P 0xef 524288 524288', mid_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img)
self.vm = iotests.VM().add_drive(test_img) self.vm = iotests.VM().add_drive(test_img)
self.vm.launch() self.vm.launch()

View File

@ -64,7 +64,7 @@ _compare
_compare -q _compare -q
# Compare images with different size # Compare images with different size
$QEMU_IMG resize "$TEST_IMG" +512M $QEMU_IMG resize -f $IMGFMT "$TEST_IMG" +512M
_compare _compare
_compare -s _compare -s

View File

@ -50,6 +50,7 @@ Testing: -drive file=TEST_DIR/t.qcow2,driver=qcow2,backing.file.filename=TEST_DI
QEMU X.Y.Z monitor - type 'help' for more information QEMU X.Y.Z monitor - type 'help' for more information
(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo block (qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo block
ide0-hd0: TEST_DIR/t.qcow2 (qcow2) ide0-hd0: TEST_DIR/t.qcow2 (qcow2)
Cache mode: writeback
Backing file: TEST_DIR/t.qcow2.orig (chain depth: 1) Backing file: TEST_DIR/t.qcow2.orig (chain depth: 1)
(qemu) qququiquit (qemu) qququiquit

View File

@ -34,10 +34,10 @@ class TestSingleDrive(iotests.QMPTestCase):
def setUp(self): def setUp(self):
# Write data to the image so we can compare later # Write data to the image so we can compare later
qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleDrive.image_len)) qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleDrive.image_len))
qemu_io('-c', 'write -P0x5d 0 64k', test_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x5d 0 64k', test_img)
qemu_io('-c', 'write -P0xd5 1M 32k', test_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xd5 1M 32k', test_img)
qemu_io('-c', 'write -P0xdc 32M 124k', test_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 32M 124k', test_img)
qemu_io('-c', 'write -P0xdc 67043328 64k', test_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 67043328 64k', test_img)
self.vm = iotests.VM().add_drive(test_img) self.vm = iotests.VM().add_drive(test_img)
self.vm.launch() self.vm.launch()
@ -115,7 +115,7 @@ class TestSetSpeed(iotests.QMPTestCase):
def setUp(self): def setUp(self):
qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSetSpeed.image_len)) qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSetSpeed.image_len))
qemu_io('-c', 'write -P1 0 512', test_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P1 0 512', test_img)
self.vm = iotests.VM().add_drive(test_img) self.vm = iotests.VM().add_drive(test_img)
self.vm.launch() self.vm.launch()
@ -186,10 +186,10 @@ class TestSingleTransaction(iotests.QMPTestCase):
def setUp(self): def setUp(self):
qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleTransaction.image_len)) qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleTransaction.image_len))
qemu_io('-c', 'write -P0x5d 0 64k', test_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x5d 0 64k', test_img)
qemu_io('-c', 'write -P0xd5 1M 32k', test_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xd5 1M 32k', test_img)
qemu_io('-c', 'write -P0xdc 32M 124k', test_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 32M 124k', test_img)
qemu_io('-c', 'write -P0xdc 67043328 64k', test_img) qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 67043328 64k', test_img)
self.vm = iotests.VM().add_drive(test_img) self.vm = iotests.VM().add_drive(test_img)
self.vm.launch() self.vm.launch()

View File

@ -89,6 +89,9 @@ _supported_fmt qcow2
_supported_proto file _supported_proto file
_require_command QEMU_NBD _require_command QEMU_NBD
# Use -f raw instead of -f $IMGFMT for the NBD connection
QEMU_IO_NBD="$QEMU_IO -f raw --cache=$CACHEMODE"
echo echo
echo "== preparing image ==" echo "== preparing image =="
_make_test_img 64M _make_test_img 64M
@ -108,15 +111,15 @@ _export_nbd_snapshot sn1
echo echo
echo "== verifying the exported snapshot with patterns, method 1 ==" echo "== verifying the exported snapshot with patterns, method 1 =="
$QEMU_IO -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io $QEMU_IO_NBD -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
$QEMU_IO -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io $QEMU_IO_NBD -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
_export_nbd_snapshot1 sn1 _export_nbd_snapshot1 sn1
echo echo
echo "== verifying the exported snapshot with patterns, method 2 ==" echo "== verifying the exported snapshot with patterns, method 2 =="
$QEMU_IO -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io $QEMU_IO_NBD -c 'read -P 0xa 0x1000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
$QEMU_IO -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io $QEMU_IO_NBD -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
$QEMU_IMG convert "$TEST_IMG" -l sn1 -O qcow2 "$converted_image" $QEMU_IMG convert "$TEST_IMG" -l sn1 -O qcow2 "$converted_image"

View File

@ -106,8 +106,8 @@ _img_info
echo echo
echo "=== Converting to streamOptimized from image with small cluster size===" echo "=== Converting to streamOptimized from image with small cluster size==="
TEST_IMG="$TEST_IMG.qcow2" IMGFMT=qcow2 IMGOPTS="cluster_size=4096" _make_test_img 1G TEST_IMG="$TEST_IMG.qcow2" IMGFMT=qcow2 IMGOPTS="cluster_size=4096" _make_test_img 1G
$QEMU_IO -c "write -P 0xa 0 512" "$TEST_IMG.qcow2" | _filter_qemu_io $QEMU_IO -f qcow2 -c "write -P 0xa 0 512" "$TEST_IMG.qcow2" | _filter_qemu_io
$QEMU_IO -c "write -P 0xb 10240 512" "$TEST_IMG.qcow2" | _filter_qemu_io $QEMU_IO -f qcow2 -c "write -P 0xb 10240 512" "$TEST_IMG.qcow2" | _filter_qemu_io
$QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2" "$TEST_IMG" 2>&1 $QEMU_IMG convert -f qcow2 -O vmdk -o subformat=streamOptimized "$TEST_IMG.qcow2" "$TEST_IMG" 2>&1
echo echo

View File

@ -77,7 +77,7 @@ $QEMU_IO -c "$OPEN_RW" -c "write -P 0x2a 0 512" | _filter_qemu_io
$PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features $PYTHON qcow2.py "$TEST_IMG" dump-header | grep incompatible_features
# This information should be available through qemu-img info # This information should be available through qemu-img info
$QEMU_IMG info "$TEST_IMG" | _filter_testdir _img_info --format-specific
# Try to open the image R/W (which should fail) # Try to open the image R/W (which should fail)
$QEMU_IO -c "$OPEN_RW" -c "read 0 512" 2>&1 | _filter_qemu_io \ $QEMU_IO -c "$OPEN_RW" -c "read 0 512" 2>&1 | _filter_qemu_io \

View File

@ -11,10 +11,9 @@ incompatible_features 0x0
qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with active L1 table); further corruption events will be suppressed qcow2: Marking image as corrupt: Preventing invalid write on metadata (overlaps with active L1 table); further corruption events will be suppressed
write failed: Input/output error write failed: Input/output error
incompatible_features 0x2 incompatible_features 0x2
image: TEST_DIR/t.qcow2 image: TEST_DIR/t.IMGFMT
file format: qcow2 file format: IMGFMT
virtual size: 64M (67108864 bytes) virtual size: 64M (67108864 bytes)
disk size: 196K
cluster_size: 65536 cluster_size: 65536
Format specific information: Format specific information:
compat: 1.1 compat: 1.1

View File

@ -39,7 +39,7 @@ _supported_os Linux
function do_run_qemu() function do_run_qemu()
{ {
echo Testing: "$@" echo Testing: "$@"
$QEMU -nographic -qmp stdio -serial none "$@" $QEMU -nographic -qmp-pretty stdio -serial none "$@"
echo echo
} }

View File

@ -4,77 +4,767 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
=== -drive/-device and device_del === === -drive/-device and device_del ===
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virtio-blk-pci,drive=disk,id=virtio0 Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virtio-blk-pci,drive=disk,id=virtio0
QMP_VERSION {
{"return": {}} QMP_VERSION
{"return": [{"io-status": "ok", "device": "disk", "locked": false, "removable": false, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "type": "unknown"}, {"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]} }
{"return": {}} {
{"return": {}} "return": {
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}} }
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"device": "virtio0", "path": "/machine/peripheral/virtio0"}} }
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESET"} {
{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]} "return": [
{"return": {}} {
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"} "io-status": "ok",
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}} "device": "disk",
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}} "locked": false,
"removable": false,
"inserted": {
"iops_rd": 0,
"detect_zeroes": "off",
"image": {
"virtual-size": 134217728,
"filename": "TEST_DIR/t.qcow2",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"corrupt": false
}
},
"dirty-flag": false
},
"iops_wr": 0,
"ro": false,
"backing_file_depth": 0,
"drv": "qcow2",
"iops": 0,
"bps_wr": 0,
"encrypted": false,
"bps": 0,
"bps_rd": 0,
"cache": {
"no-flush": false,
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"encryption_key_missing": false
},
"type": "unknown"
},
{
"io-status": "ok",
"device": "ide1-cd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "floppy0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "sd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
}
]
}
{
"return": {
}
}
{
"return": {
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_DELETED",
"data": {
"path": "/machine/peripheral/virtio0/virtio-backend"
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_DELETED",
"data": {
"device": "virtio0",
"path": "/machine/peripheral/virtio0"
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "RESET"
}
{
"return": [
{
"io-status": "ok",
"device": "ide1-cd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "floppy0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "sd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
}
]
}
{
"return": {
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "SHUTDOWN"
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_TRAY_MOVED",
"data": {
"device": "ide1-cd0",
"tray-open": true
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_TRAY_MOVED",
"data": {
"device": "floppy0",
"tray-open": true
}
}
=== -drive/device_add and device_del === === -drive/device_add and device_del ===
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk
QMP_VERSION {
{"return": {}} QMP_VERSION
{"return": [{"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}, {"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]} }
{"return": {}} {
{"return": {}} "return": {
{"return": {}} }
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}} }
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"device": "virtio0", "path": "/machine/peripheral/virtio0"}} {
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESET"} "return": [
{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]} {
{"return": {}} "device": "disk",
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"} "locked": false,
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}} "removable": true,
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}} "inserted": {
"iops_rd": 0,
"detect_zeroes": "off",
"image": {
"virtual-size": 134217728,
"filename": "TEST_DIR/t.qcow2",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"corrupt": false
}
},
"dirty-flag": false
},
"iops_wr": 0,
"ro": false,
"backing_file_depth": 0,
"drv": "qcow2",
"iops": 0,
"bps_wr": 0,
"encrypted": false,
"bps": 0,
"bps_rd": 0,
"cache": {
"no-flush": false,
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"encryption_key_missing": false
},
"tray_open": false,
"type": "unknown"
},
{
"io-status": "ok",
"device": "ide1-cd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "floppy0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "sd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
}
]
}
{
"return": {
}
}
{
"return": {
}
}
{
"return": {
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_DELETED",
"data": {
"path": "/machine/peripheral/virtio0/virtio-backend"
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_DELETED",
"data": {
"device": "virtio0",
"path": "/machine/peripheral/virtio0"
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "RESET"
}
{
"return": [
{
"io-status": "ok",
"device": "ide1-cd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "floppy0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "sd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
}
]
}
{
"return": {
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "SHUTDOWN"
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_TRAY_MOVED",
"data": {
"device": "ide1-cd0",
"tray-open": true
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_TRAY_MOVED",
"data": {
"device": "floppy0",
"tray-open": true
}
}
=== drive_add/device_add and device_del === === drive_add/device_add and device_del ===
Testing: Testing:
QMP_VERSION {
{"return": {}} QMP_VERSION
{"return": "OK\r\n"} }
{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]} {
{"return": {}} "return": {
{"return": {}} }
{"return": {}} }
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}} {
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"device": "virtio0", "path": "/machine/peripheral/virtio0"}} "return": "OK\r\n"
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESET"} }
{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}]} {
{"return": {}} "return": [
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"} {
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}} "io-status": "ok",
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}} "device": "ide1-cd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "floppy0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "sd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "disk",
"locked": false,
"removable": true,
"inserted": {
"iops_rd": 0,
"detect_zeroes": "off",
"image": {
"virtual-size": 134217728,
"filename": "TEST_DIR/t.qcow2",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"corrupt": false
}
},
"dirty-flag": false
},
"iops_wr": 0,
"ro": false,
"backing_file_depth": 0,
"drv": "qcow2",
"iops": 0,
"bps_wr": 0,
"encrypted": false,
"bps": 0,
"bps_rd": 0,
"cache": {
"no-flush": false,
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"encryption_key_missing": false
},
"tray_open": false,
"type": "unknown"
}
]
}
{
"return": {
}
}
{
"return": {
}
}
{
"return": {
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_DELETED",
"data": {
"path": "/machine/peripheral/virtio0/virtio-backend"
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_DELETED",
"data": {
"device": "virtio0",
"path": "/machine/peripheral/virtio0"
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "RESET"
}
{
"return": [
{
"io-status": "ok",
"device": "ide1-cd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "floppy0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "sd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
}
]
}
{
"return": {
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "SHUTDOWN"
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_TRAY_MOVED",
"data": {
"device": "ide1-cd0",
"tray-open": true
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_TRAY_MOVED",
"data": {
"device": "floppy0",
"tray-open": true
}
}
=== blockdev_add/device_add and device_del === === blockdev_add/device_add and device_del ===
Testing: Testing:
QMP_VERSION {
{"return": {}} QMP_VERSION
{"return": {}} }
{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]} {
{"return": {}} "return": {
{"return": {}} }
{"return": {}} }
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"path": "/machine/peripheral/virtio0/virtio-backend"}} {
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_DELETED", "data": {"device": "virtio0", "path": "/machine/peripheral/virtio0"}} "return": {
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "RESET"} }
{"return": [{"io-status": "ok", "device": "ide1-cd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "floppy0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"device": "sd0", "locked": false, "removable": true, "tray_open": false, "type": "unknown"}, {"io-status": "ok", "device": "disk", "locked": false, "removable": true, "inserted": {"iops_rd": 0, "detect_zeroes": "off", "image": {"virtual-size": 134217728, "filename": "TEST_DIR/t.qcow2", "cluster-size": 65536, "format": "qcow2", "actual-size": SIZE, "format-specific": {"type": "qcow2", "data": {"compat": "1.1", "lazy-refcounts": false, "corrupt": false}}, "dirty-flag": false}, "iops_wr": 0, "ro": false, "backing_file_depth": 0, "drv": "qcow2", "iops": 0, "bps_wr": 0, "encrypted": false, "bps": 0, "bps_rd": 0, "file": "TEST_DIR/t.qcow2", "encryption_key_missing": false}, "tray_open": false, "type": "unknown"}]} }
{"return": {}} {
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"} "return": [
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}} {
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}} "io-status": "ok",
"device": "ide1-cd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "floppy0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "sd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "disk",
"locked": false,
"removable": true,
"inserted": {
"iops_rd": 0,
"detect_zeroes": "off",
"image": {
"virtual-size": 134217728,
"filename": "TEST_DIR/t.qcow2",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"corrupt": false
}
},
"dirty-flag": false
},
"iops_wr": 0,
"ro": false,
"backing_file_depth": 0,
"drv": "qcow2",
"iops": 0,
"bps_wr": 0,
"encrypted": false,
"bps": 0,
"bps_rd": 0,
"cache": {
"no-flush": false,
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"encryption_key_missing": false
},
"tray_open": false,
"type": "unknown"
}
]
}
{
"return": {
}
}
{
"return": {
}
}
{
"return": {
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_DELETED",
"data": {
"path": "/machine/peripheral/virtio0/virtio-backend"
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_DELETED",
"data": {
"device": "virtio0",
"path": "/machine/peripheral/virtio0"
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "RESET"
}
{
"return": [
{
"io-status": "ok",
"device": "ide1-cd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "floppy0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"device": "sd0",
"locked": false,
"removable": true,
"tray_open": false,
"type": "unknown"
},
{
"io-status": "ok",
"device": "disk",
"locked": false,
"removable": true,
"inserted": {
"iops_rd": 0,
"detect_zeroes": "off",
"image": {
"virtual-size": 134217728,
"filename": "TEST_DIR/t.qcow2",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"corrupt": false
}
},
"dirty-flag": false
},
"iops_wr": 0,
"ro": false,
"backing_file_depth": 0,
"drv": "qcow2",
"iops": 0,
"bps_wr": 0,
"encrypted": false,
"bps": 0,
"bps_rd": 0,
"cache": {
"no-flush": false,
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"encryption_key_missing": false
},
"tray_open": false,
"type": "unknown"
}
]
}
{
"return": {
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "SHUTDOWN"
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_TRAY_MOVED",
"data": {
"device": "ide1-cd0",
"tray-open": true
}
}
{
"timestamp": {
"seconds": TIMESTAMP,
"microseconds": TIMESTAMP
},
"event": "DEVICE_TRAY_MOVED",
"data": {
"device": "floppy0",
"tray-open": true
}
}
*** done *** done

View File

@ -63,12 +63,12 @@ echo
TEST_IMG="$TEST_IMG.base" IMGOPTS="" IMGFMT="raw" _make_test_img $IMG_SIZE |\ TEST_IMG="$TEST_IMG.base" IMGOPTS="" IMGFMT="raw" _make_test_img $IMG_SIZE |\
_filter_imgfmt _filter_imgfmt
_make_test_img $IMG_SIZE _make_test_img $IMG_SIZE
$QEMU_IO -c "open -o file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \ $QEMU_IO -c "open -o driver=raw,file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \
-c 'read 0 512' -c 'write -P 42 0x38000 512' -c 'read -P 42 0x38000 512' | _filter_qemu_io -c 'read 0 512' -c 'write -P 42 0x38000 512' -c 'read -P 42 0x38000 512' | _filter_qemu_io
$QEMU_IO -c 'write -P 42 0 512' "$TEST_IMG" | _filter_qemu_io $QEMU_IO -c 'write -P 42 0 512' "$TEST_IMG" | _filter_qemu_io
$QEMU_IO -c "open -o file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \ $QEMU_IO -c "open -o driver=raw,file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \
-c 'read -P 42 0 512' | _filter_qemu_io -c 'read -P 42 0 512' | _filter_qemu_io
echo echo
@ -78,12 +78,12 @@ echo
TEST_IMG="$TEST_IMG.base" IMGOPTS="" IMGFMT="raw" _make_test_img $IMG_SIZE |\ TEST_IMG="$TEST_IMG.base" IMGOPTS="" IMGFMT="raw" _make_test_img $IMG_SIZE |\
_filter_imgfmt _filter_imgfmt
_make_test_img $IMG_SIZE _make_test_img $IMG_SIZE
$QEMU_IO -c "open -o file.driver=blkverify,file.raw.filename=$TEST_IMG.base,file.test.driver=$IMGFMT,file.test.file.filename=$TEST_IMG" \ $QEMU_IO -c "open -o driver=raw,file.driver=blkverify,file.raw.filename=$TEST_IMG.base,file.test.driver=$IMGFMT,file.test.file.filename=$TEST_IMG" \
-c 'read 0 512' -c 'write -P 42 0x38000 512' -c 'read -P 42 0x38000 512' | _filter_qemu_io -c 'read 0 512' -c 'write -P 42 0x38000 512' -c 'read -P 42 0x38000 512' | _filter_qemu_io
$QEMU_IO -c 'write -P 42 0 512' "$TEST_IMG" | _filter_qemu_io $QEMU_IO -c 'write -P 42 0 512' "$TEST_IMG" | _filter_qemu_io
$QEMU_IO -c "open -o file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \ $QEMU_IO -c "open -o driver=raw,file.driver=blkverify,file.raw.filename=$TEST_IMG.base $TEST_IMG" \
-c 'read -P 42 0 512' | _filter_qemu_io -c 'read -P 42 0 512' | _filter_qemu_io
echo echo
@ -163,7 +163,7 @@ echo
echo "=== Testing blkverify on existing raw block device ===" echo "=== Testing blkverify on existing raw block device ==="
echo echo
run_qemu -drive "file=$TEST_IMG.base,if=none,id=drive0" <<EOF run_qemu -drive "file=$TEST_IMG.base,format=raw,if=none,id=drive0" <<EOF
{ "execute": "qmp_capabilities" } { "execute": "qmp_capabilities" }
{ "execute": "blockdev-add", { "execute": "blockdev-add",
"arguments": { "arguments": {

View File

@ -12,7 +12,7 @@ read 512/512 bytes at offset 229376
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 512/512 bytes at offset 0 wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
blkverify: read sector_num=0 nb_sectors=4 contents mismatch in sector 0 blkverify: read sector_num=0 nb_sectors=1 contents mismatch in sector 0
=== Testing blkverify through file blockref === === Testing blkverify through file blockref ===
@ -26,14 +26,18 @@ read 512/512 bytes at offset 229376
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 512/512 bytes at offset 0 wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
blkverify: read sector_num=0 nb_sectors=4 contents mismatch in sector 0 blkverify: read sector_num=0 nb_sectors=1 contents mismatch in sector 0
=== Testing blkdebug through filename === === Testing blkdebug through filename ===
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
read failed: Input/output error read failed: Input/output error
=== Testing blkdebug through file blockref === === Testing blkdebug through file blockref ===
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
read failed: Input/output error read failed: Input/output error
=== Testing blkdebug on existing block device === === Testing blkdebug on existing block device ===
@ -48,6 +52,8 @@ read failed: Input/output error
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
qemu-system-x86_64: Failed to flush the L2 table cache: Input/output error
qemu-system-x86_64: Failed to flush the refcount block cache: Input/output error
=== Testing blkverify on existing block device === === Testing blkverify on existing block device ===
@ -61,7 +67,7 @@ blkverify: read sector_num=0 nb_sectors=1 contents mismatch in sector 0
=== Testing blkverify on existing raw block device === === Testing blkverify on existing raw block device ===
Testing: -drive file=TEST_DIR/t.IMGFMT.base,if=none,id=drive0 Testing: -drive file=TEST_DIR/t.IMGFMT.base,format=raw,if=none,id=drive0
QMP_VERSION QMP_VERSION
{"return": {}} {"return": {}}
{"return": {}} {"return": {}}
@ -86,5 +92,7 @@ read failed: Input/output error
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN"}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "ide1-cd0", "tray-open": true}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "DEVICE_TRAY_MOVED", "data": {"device": "floppy0", "tray-open": true}}
qemu-system-x86_64: Failed to flush the L2 table cache: Input/output error
qemu-system-x86_64: Failed to flush the refcount block cache: Input/output error
*** done *** done

View File

@ -52,7 +52,7 @@ echo "== Some concurrent requests involving RMW =="
function test_io() function test_io()
{ {
echo "open -o file.align=4k blkdebug::$TEST_IMG" echo "open -o driver=$IMGFMT,file.align=4k blkdebug::$TEST_IMG"
# A simple RMW request # A simple RMW request
cat <<EOF cat <<EOF
aio_write -P 10 0x200 0x200 aio_write -P 10 0x200 0x200

View File

@ -78,6 +78,8 @@ poke_file "$TEST_IMG" "$offset_backing_file_offset" "\xff\xff\xff\xff\xff\xff\xf
poke_file "$TEST_IMG" "$offset_ext_magic" "\x12\x34\x56\x78" poke_file "$TEST_IMG" "$offset_ext_magic" "\x12\x34\x56\x78"
poke_file "$TEST_IMG" "$offset_ext_size" "\x7f\xff\xff\xff" poke_file "$TEST_IMG" "$offset_ext_size" "\x7f\xff\xff\xff"
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir { $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
poke_file "$TEST_IMG" "$offset_backing_file_offset" "\x00\x00\x00\x00\x00\x00\x00\x$(printf %x $offset_ext_size)"
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
poke_file "$TEST_IMG" "$offset_backing_file_offset" "\x00\x00\x00\x00\x00\x00\x00\x00" poke_file "$TEST_IMG" "$offset_backing_file_offset" "\x00\x00\x00\x00\x00\x00\x00\x00"
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir { $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir

View File

@ -13,6 +13,8 @@ qemu-io: can't open device TEST_DIR/t.qcow2: Invalid backing file offset
no file open, try 'help open' no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large
no file open, try 'help open' no file open, try 'help open'
qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large
no file open, try 'help open'
== Huge refcount table size == == Huge refcount table size ==
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864

View File

@ -59,9 +59,13 @@ function run_qemu()
test_quorum=$($QEMU_IMG --help|grep quorum) test_quorum=$($QEMU_IMG --help|grep quorum)
[ "$test_quorum" = "" ] && _supported_fmt quorum [ "$test_quorum" = "" ] && _supported_fmt quorum
quorum="file.driver=quorum,file.children.0.file.filename=$TEST_DIR/1.raw" quorum="driver=raw,file.driver=quorum,file.vote-threshold=2"
quorum="$quorum,file.children.0.file.filename=$TEST_DIR/1.raw"
quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw" quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw"
quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw,file.vote-threshold=2" quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw"
quorum="$quorum,file.children.0.driver=raw"
quorum="$quorum,file.children.1.driver=raw"
quorum="$quorum,file.children.2.driver=raw"
echo echo
echo "== creating quorum files ==" echo "== creating quorum files =="

View File

@ -55,5 +55,5 @@ wrote 10485760/10485760 bytes at offset 0
10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== checking that quorum is broken == == checking that quorum is broken ==
qemu-io: can't open: Could not read image for determining its format: Input/output error read failed: Input/output error
*** done *** done

View File

@ -60,11 +60,11 @@ _img_info
# Multiple -o should be merged # Multiple -o should be merged
run_qemu_img create -f $IMGFMT -o cluster_size=4k -o lazy_refcounts=on "$TEST_IMG" $size run_qemu_img create -f $IMGFMT -o cluster_size=4k -o lazy_refcounts=on "$TEST_IMG" $size
run_qemu_img info "$TEST_IMG" _img_info --format-specific
# If the same -o key is specified more than once, the last one wins # If the same -o key is specified more than once, the last one wins
run_qemu_img create -f $IMGFMT -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k "$TEST_IMG" $size run_qemu_img create -f $IMGFMT -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k "$TEST_IMG" $size
run_qemu_img info "$TEST_IMG" _img_info --format-specific
run_qemu_img create -f $IMGFMT -o cluster_size=4k,cluster_size=8k "$TEST_IMG" $size run_qemu_img create -f $IMGFMT -o cluster_size=4k,cluster_size=8k "$TEST_IMG" $size
_img_info _img_info
@ -114,11 +114,11 @@ TEST_IMG="${TEST_IMG}.base" _img_info
# Multiple -o should be merged # Multiple -o should be merged
run_qemu_img convert -O $IMGFMT -o cluster_size=4k -o lazy_refcounts=on "$TEST_IMG" "$TEST_IMG".base run_qemu_img convert -O $IMGFMT -o cluster_size=4k -o lazy_refcounts=on "$TEST_IMG" "$TEST_IMG".base
run_qemu_img info "$TEST_IMG".base TEST_IMG="${TEST_IMG}.base" _img_info --format-specific
# If the same -o key is specified more than once, the last one wins # If the same -o key is specified more than once, the last one wins
run_qemu_img convert -O $IMGFMT -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k "$TEST_IMG" "$TEST_IMG".base run_qemu_img convert -O $IMGFMT -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k "$TEST_IMG" "$TEST_IMG".base
run_qemu_img info "$TEST_IMG".base TEST_IMG="${TEST_IMG}.base" _img_info --format-specific
run_qemu_img convert -O $IMGFMT -o cluster_size=4k,cluster_size=8k "$TEST_IMG" "$TEST_IMG".base run_qemu_img convert -O $IMGFMT -o cluster_size=4k,cluster_size=8k "$TEST_IMG" "$TEST_IMG".base
TEST_IMG="${TEST_IMG}.base" _img_info TEST_IMG="${TEST_IMG}.base" _img_info
@ -157,15 +157,15 @@ echo === amend: Options specified more than once ===
# Last -f should win # Last -f should win
run_qemu_img amend -f foo -f $IMGFMT -o lazy_refcounts=on "$TEST_IMG" run_qemu_img amend -f foo -f $IMGFMT -o lazy_refcounts=on "$TEST_IMG"
run_qemu_img info "$TEST_IMG" _img_info --format-specific
# Multiple -o should be merged # Multiple -o should be merged
run_qemu_img amend -f $IMGFMT -o size=130M -o lazy_refcounts=off "$TEST_IMG" run_qemu_img amend -f $IMGFMT -o size=130M -o lazy_refcounts=off "$TEST_IMG"
run_qemu_img info "$TEST_IMG" _img_info --format-specific
# If the same -o key is specified more than once, the last one wins # If the same -o key is specified more than once, the last one wins
run_qemu_img amend -f $IMGFMT -o size=8M -o lazy_refcounts=on -o size=132M "$TEST_IMG" run_qemu_img amend -f $IMGFMT -o size=8M -o lazy_refcounts=on -o size=132M "$TEST_IMG"
run_qemu_img info "$TEST_IMG" _img_info --format-specific
run_qemu_img amend -f $IMGFMT -o size=4M,size=148M "$TEST_IMG" run_qemu_img amend -f $IMGFMT -o size=4M,size=148M "$TEST_IMG"
_img_info _img_info

View File

@ -11,12 +11,9 @@ cluster_size: 65536
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 128M Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 128M
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=4096 lazy_refcounts=on Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=4096 lazy_refcounts=on
image: TEST_DIR/t.IMGFMT
Testing: info TEST_DIR/t.qcow2 file format: IMGFMT
image: TEST_DIR/t.qcow2
file format: qcow2
virtual size: 128M (134217728 bytes) virtual size: 128M (134217728 bytes)
disk size: 16K
cluster_size: 4096 cluster_size: 4096
Format specific information: Format specific information:
compat: 1.1 compat: 1.1
@ -25,12 +22,9 @@ Format specific information:
Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 128M Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 128M
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=8192 lazy_refcounts=on Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=8192 lazy_refcounts=on
image: TEST_DIR/t.IMGFMT
Testing: info TEST_DIR/t.qcow2 file format: IMGFMT
image: TEST_DIR/t.qcow2
file format: qcow2
virtual size: 128M (134217728 bytes) virtual size: 128M (134217728 bytes)
disk size: 28K
cluster_size: 8192 cluster_size: 8192
Format specific information: Format specific information:
compat: 1.1 compat: 1.1
@ -189,12 +183,9 @@ virtual size: 128M (134217728 bytes)
cluster_size: 65536 cluster_size: 65536
Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
image: TEST_DIR/t.IMGFMT.base
Testing: info TEST_DIR/t.qcow2.base file format: IMGFMT
image: TEST_DIR/t.qcow2.base
file format: qcow2
virtual size: 128M (134217728 bytes) virtual size: 128M (134217728 bytes)
disk size: 16K
cluster_size: 4096 cluster_size: 4096
Format specific information: Format specific information:
compat: 1.1 compat: 1.1
@ -202,12 +193,9 @@ Format specific information:
corrupt: false corrupt: false
Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base
image: TEST_DIR/t.IMGFMT.base
Testing: info TEST_DIR/t.qcow2.base file format: IMGFMT
image: TEST_DIR/t.qcow2.base
file format: qcow2
virtual size: 128M (134217728 bytes) virtual size: 128M (134217728 bytes)
disk size: 28K
cluster_size: 8192 cluster_size: 8192
Format specific information: Format specific information:
compat: 1.1 compat: 1.1
@ -351,12 +339,9 @@ size Virtual disk size
=== amend: Options specified more than once === === amend: Options specified more than once ===
Testing: amend -f foo -f qcow2 -o lazy_refcounts=on TEST_DIR/t.qcow2 Testing: amend -f foo -f qcow2 -o lazy_refcounts=on TEST_DIR/t.qcow2
image: TEST_DIR/t.IMGFMT
Testing: info TEST_DIR/t.qcow2 file format: IMGFMT
image: TEST_DIR/t.qcow2
file format: qcow2
virtual size: 128M (134217728 bytes) virtual size: 128M (134217728 bytes)
disk size: 196K
cluster_size: 65536 cluster_size: 65536
Format specific information: Format specific information:
compat: 1.1 compat: 1.1
@ -364,12 +349,9 @@ Format specific information:
corrupt: false corrupt: false
Testing: amend -f qcow2 -o size=130M -o lazy_refcounts=off TEST_DIR/t.qcow2 Testing: amend -f qcow2 -o size=130M -o lazy_refcounts=off TEST_DIR/t.qcow2
image: TEST_DIR/t.IMGFMT
Testing: info TEST_DIR/t.qcow2 file format: IMGFMT
image: TEST_DIR/t.qcow2
file format: qcow2
virtual size: 130M (136314880 bytes) virtual size: 130M (136314880 bytes)
disk size: 196K
cluster_size: 65536 cluster_size: 65536
Format specific information: Format specific information:
compat: 1.1 compat: 1.1
@ -377,12 +359,9 @@ Format specific information:
corrupt: false corrupt: false
Testing: amend -f qcow2 -o size=8M -o lazy_refcounts=on -o size=132M TEST_DIR/t.qcow2 Testing: amend -f qcow2 -o size=8M -o lazy_refcounts=on -o size=132M TEST_DIR/t.qcow2
image: TEST_DIR/t.IMGFMT
Testing: info TEST_DIR/t.qcow2 file format: IMGFMT
image: TEST_DIR/t.qcow2
file format: qcow2
virtual size: 132M (138412032 bytes) virtual size: 132M (138412032 bytes)
disk size: 196K
cluster_size: 65536 cluster_size: 65536
Format specific information: Format specific information:
compat: 1.1 compat: 1.1

View File

@ -65,7 +65,8 @@ $QEMU_IO -c 'write -P 42 0 512' -c 'write -P 23 512 512' \
$QEMU_IMG convert -f raw -O $IMGFMT "$TEST_IMG.base" "$TEST_IMG" $QEMU_IMG convert -f raw -O $IMGFMT "$TEST_IMG.base" "$TEST_IMG"
$QEMU_IO -c 'read -P 42 0 512' -c 'read -P 23 512 512' \ $QEMU_IO_PROG --cache $CACHEMODE \
-c 'read -P 42 0 512' -c 'read -P 23 512 512' \
-c 'read -P 66 1024 512' "json:{ -c 'read -P 66 1024 512' "json:{
\"driver\": \"$IMGFMT\", \"driver\": \"$IMGFMT\",
\"file\": { \"file\": {
@ -91,7 +92,8 @@ $QEMU_IO -c 'write -P 42 0x38000 512' "$TEST_IMG" | _filter_qemu_io
# The "image.filename" part tests whether "a": { "b": "c" } and "a.b": "c" do # The "image.filename" part tests whether "a": { "b": "c" } and "a.b": "c" do
# the same (which they should). # the same (which they should).
$QEMU_IO -c 'read -P 42 0x38000 512' "json:{ $QEMU_IO_PROG --cache $CACHEMODE \
-c 'read -P 42 0x38000 512' "json:{
\"driver\": \"$IMGFMT\", \"driver\": \"$IMGFMT\",
\"file\": { \"file\": {
\"driver\": \"blkdebug\", \"driver\": \"blkdebug\",

View File

@ -24,6 +24,8 @@ read 512/512 bytes at offset 0
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 512/512 bytes at offset 229376 wrote 512/512 bytes at offset 229376
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Failed to flush the L2 table cache: Input/output error
Failed to flush the refcount block cache: Input/output error
read failed: Input/output error read failed: Input/output error
=== Testing qemu-img info output === === Testing qemu-img info output ===

View File

@ -44,7 +44,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow qcow2 qed vdi vhdx vmdk vpc _supported_fmt qcow qcow2 qed vdi vhdx vmdk vpc
_supported_proto file _supported_proto file
_supported_os Linux _supported_os Linux
_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
"subformat=twoGbMaxExtentSparse"
function do_run_qemu() function do_run_qemu()
{ {
@ -107,8 +108,21 @@ echo
# generate a JSON object here as well # generate a JSON object here as well
test_qemu "file.driver=blkverify,file.raw.filename=$TEST_IMG.compare,file.test.file.driver=blkdebug,file.test.file.image.filename=$TEST_IMG,file.test.file.inject-error.0.event=l1_update" test_qemu "file.driver=blkverify,file.raw.filename=$TEST_IMG.compare,file.test.file.driver=blkdebug,file.test.file.image.filename=$TEST_IMG,file.test.file.inject-error.0.event=l1_update"
echo
echo '=== Testing plain filename for blkdebug ==='
echo
rm -f "$TEST_IMG.compare" touch "$TEST_DIR/blkdebug.conf"
test_qemu "file.driver=blkdebug,file.config=$TEST_DIR/blkdebug.conf,file.image.filename=$TEST_IMG"
echo
echo '=== Testing plain filename for blkdebug without configuration file ==='
echo
test_qemu "file.driver=blkdebug,file.image.filename=$TEST_IMG"
rm -f "$TEST_IMG.compare" "$TEST_DIR/blkdebug.conf"
# success, all done # success, all done
echo "*** done" echo "*** done"

View File

@ -12,9 +12,17 @@ blkverify:TEST_DIR/t.IMGFMT.compare:TEST_DIR/t.IMGFMT
=== Testing JSON filename for blkdebug === === Testing JSON filename for blkdebug ===
json:{"driver": "IMGFMT", "file": {"inject-error": [{"immediately": false, "once": false, "state": 0, "sector": -1, "event": "l1_update", "errno": 5}], "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug"}} json:{"driver": "IMGFMT", "file": {"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "l1_update"}}
=== Testing indirectly enforced JSON filename === === Testing indirectly enforced JSON filename ===
json:{"driver": "raw", "file": {"test": {"driver": "IMGFMT", "file": {"inject-error": [{"immediately": false, "once": false, "state": 0, "sector": -1, "event": "l1_update", "errno": 5}], "image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug"}}, "driver": "blkverify", "raw": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}} json:{"driver": "raw", "file": {"test": {"driver": "IMGFMT", "file": {"image": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}, "driver": "blkdebug", "inject-error.0.event": "l1_update"}}, "driver": "blkverify", "raw": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT.compare"}}}
=== Testing plain filename for blkdebug ===
blkdebug:TEST_DIR/blkdebug.conf:TEST_DIR/t.IMGFMT
=== Testing plain filename for blkdebug without configuration file ===
blkdebug::TEST_DIR/t.IMGFMT
*** done *** done

132
tests/qemu-iotests/109 Executable file
View File

@ -0,0 +1,132 @@
#!/bin/bash
#
# Test writing image headers of other formats into raw images
#
# Copyright (C) 2014 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# creator
owner=kwolf@redhat.com
seq="$(basename $0)"
echo "QA output created by $seq"
here="$PWD"
tmp=/tmp/$$
status=1 # failure is the default!
_cleanup()
{
rm -f $TEST_IMG.src
_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 raw
_supported_proto file
_supported_os Linux
qemu_comm_method=qmp
function run_qemu()
{
local raw_img="$1"
local source_img="$2"
local qmp_format="$3"
local qmp_event="$4"
_launch_qemu -drive file="${source_img}",format=raw,cache=${CACHEMODE},id=src
_send_qemu_cmd $QEMU_HANDLE "{ 'execute': 'qmp_capabilities' }" "return"
_send_qemu_cmd $QEMU_HANDLE \
"{'execute':'drive-mirror', 'arguments':{
'device': 'src', 'target': '$raw_img', $qmp_format
'mode': 'existing', 'sync': 'full'}}" \
"return"
_send_qemu_cmd $QEMU_HANDLE '' "$qmp_event"
_send_qemu_cmd $QEMU_HANDLE '{"execute":"query-block-jobs"}' "return"
_cleanup_qemu
}
for fmt in qcow qcow2 qed vdi vmdk vpc; do
echo
echo "=== Writing a $fmt header into raw ==="
echo
_make_test_img 64M
TEST_IMG="$TEST_IMG.src" IMGFMT=$fmt _make_test_img 64M
# This first test should fail: The image format was probed, we may not
# write an image header at the start of the image
run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR"
$QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io
# When raw was explicitly specified, the same must succeed
run_qemu "$TEST_IMG" "$TEST_IMG.src" "'format': 'raw'," "BLOCK_JOB_READY"
$QEMU_IMG compare -f raw -F raw "$TEST_IMG" "$TEST_IMG.src"
done
for sample_img in empty.bochs iotest-dirtylog-10G-4M.vhdx parallels-v1 \
simple-pattern.cloop; do
echo
echo "=== Copying sample image $sample_img into raw ==="
echo
# Can't use _use_sample_img because that isn't designed to be used multiple
# times and it overwrites $TEST_IMG (both breaks cleanup)
_make_test_img 64M
bzcat "$SAMPLE_IMG_DIR/$sample_img.bz2" > "$TEST_IMG.src"
run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_ERROR"
$QEMU_IO -c 'read -P 0 0 64k' "$TEST_IMG" | _filter_qemu_io
run_qemu "$TEST_IMG" "$TEST_IMG.src" "'format': 'raw'," "BLOCK_JOB_READY"
# qemu-img compare can't handle unaligned file sizes
$QEMU_IMG resize -f raw "$TEST_IMG.src" +0
$QEMU_IMG compare -f raw -F raw "$TEST_IMG" "$TEST_IMG.src"
done
echo
echo "=== Write legitimate MBR into raw ==="
echo
for sample_img in grub_mbr.raw; do
_make_test_img 64M
bzcat "$SAMPLE_IMG_DIR/$sample_img.bz2" > "$TEST_IMG.src"
run_qemu "$TEST_IMG" "$TEST_IMG.src" "" "BLOCK_JOB_READY"
$QEMU_IMG compare -f raw -F raw "$TEST_IMG" "$TEST_IMG.src"
run_qemu "$TEST_IMG" "$TEST_IMG.src" "'format': 'raw'," "BLOCK_JOB_READY"
$QEMU_IMG compare -f raw -F raw "$TEST_IMG" "$TEST_IMG.src"
done
# success, all done
echo '*** done'
rm -f $seq.full
status=0

231
tests/qemu-iotests/109.out Normal file
View File

@ -0,0 +1,231 @@
QA output created by 109
=== Writing a qcow header into raw ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
{"return": {}}
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
Warning: Image size mismatch!
Images are identical.
=== Writing a qcow2 header into raw ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
{"return": {}}
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 197120, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 197120, "offset": 197120, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
Warning: Image size mismatch!
Images are identical.
=== Writing a qed header into raw ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
{"return": {}}
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
Warning: Image size mismatch!
Images are identical.
=== Writing a vdi header into raw ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
{"return": {}}
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
Warning: Image size mismatch!
Images are identical.
=== Writing a vmdk header into raw ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
{"return": {}}
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 65536, "offset": 65536, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
Warning: Image size mismatch!
Images are identical.
=== Writing a vpc header into raw ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Formatting 'TEST_DIR/t.raw.src', fmt=IMGFMT size=67108864
{"return": {}}
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
Warning: Image size mismatch!
Images are identical.
=== Copying sample image empty.bochs into raw ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
{"return": {}}
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
Image resized.
Warning: Image size mismatch!
Images are identical.
=== Copying sample image iotest-dirtylog-10G-4M.vhdx into raw ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
{"return": {}}
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 31457280, "offset": 31457280, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
Image resized.
Warning: Image size mismatch!
Images are identical.
=== Copying sample image parallels-v1 into raw ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
{"return": {}}
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
Image resized.
Warning: Image size mismatch!
Images are identical.
=== Copying sample image simple-pattern.cloop into raw ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
{"return": {}}
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2048, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2048, "offset": 2048, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
Image resized.
Warning: Image size mismatch!
Images are identical.
=== Write legitimate MBR into raw ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
{"return": {}}
WARNING: Image format was not specified for 'TEST_DIR/t.raw' and probing guessed raw.
Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
Warning: Image size mismatch!
Images are identical.
{"return": {}}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
Warning: Image size mismatch!
Images are identical.
*** done

76
tests/qemu-iotests/113 Executable file
View File

@ -0,0 +1,76 @@
#!/bin/bash
#
# Test case for accessing creation options on image formats and
# protocols not supporting image creation
#
# Copyright (C) 2014 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=mreitz@redhat.com
seq="$(basename $0)"
echo "QA output created by $seq"
here="$PWD"
tmp=/tmp/$$
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
# We can only test one format here because we need its sample file
_supported_fmt bochs
_supported_proto nbd
_supported_os Linux
echo
echo '=== Unsupported image creation in qemu-img create ==='
echo
$QEMU_IMG create -f $IMGFMT nbd://example.com 2>&1 64M | _filter_imgfmt
echo
echo '=== Unsupported image creation in qemu-img convert ==='
echo
# We could use any input image format here, but this is a bochs test, so just
# use the bochs image
_use_sample_img empty.bochs.bz2
$QEMU_IMG convert -f $IMGFMT -O $IMGFMT "$TEST_IMG" nbd://example.com 2>&1 \
| _filter_imgfmt
echo
echo '=== Unsupported format in qemu-img amend ==='
echo
# The protocol does not matter here
_use_sample_img empty.bochs.bz2
$QEMU_IMG amend -f $IMGFMT -o foo=bar "$TEST_IMG" 2>&1 | _filter_imgfmt
# success, all done
echo
echo '*** done'
rm -f $seq.full
status=0

View File

@ -0,0 +1,15 @@
QA output created by 113
=== Unsupported image creation in qemu-img create ===
qemu-img: nbd://example.com: Format driver 'IMGFMT' does not support image creation
=== Unsupported image creation in qemu-img convert ===
qemu-img: Format driver 'IMGFMT' does not support image creation
=== Unsupported format in qemu-img amend ===
qemu-img: Format driver 'IMGFMT' does not support any options to amend
*** done

61
tests/qemu-iotests/114 Executable file
View File

@ -0,0 +1,61 @@
#!/bin/bash
#
# Test invalid backing file format in qcow2 images
#
# Copyright (C) 2014 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# creator
owner=kwolf@redhat.com
seq="$(basename $0)"
echo "QA output created by $seq"
here="$PWD"
tmp=/tmp/$$
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
_supported_fmt qcow2
_supported_proto generic
_supported_os Linux
TEST_IMG="$TEST_IMG.base" _make_test_img 64M
_make_test_img -b "$TEST_IMG.base" 64M
# Set an invalid backing file format
$PYTHON qcow2.py "$TEST_IMG" add-header-ext 0xE2792ACA "foo"
_img_info
# Try opening the image. Should fail (and not probe) in the first case, but
# overriding the backing file format should be possible.
$QEMU_IO -c "open $TEST_IMG" -c "read 0 4k" 2>&1 | _filter_qemu_io | _filter_testdir
$QEMU_IO -c "open -o backing.driver=$IMGFMT $TEST_IMG" -c "read 0 4k" | _filter_qemu_io
# success, all done
echo '*** done'
rm -f $seq.full
status=0

View File

@ -0,0 +1,13 @@
QA output created by 114
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file='TEST_DIR/t.IMGFMT.base'
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64M (67108864 bytes)
cluster_size: 65536
backing file: TEST_DIR/t.IMGFMT.base
backing file format: foo
qemu-io: can't open device TEST_DIR/t.qcow2: Could not open backing file: Unknown driver 'foo'
read 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
*** done

View File

@ -289,10 +289,10 @@ testlist options
if [ ! -z "$DISPLAY" ] if [ ! -z "$DISPLAY" ]
then then
which xdiff >/dev/null 2>&1 && diff=xdiff command -v xdiff >/dev/null 2>&1 && diff=xdiff
which gdiff >/dev/null 2>&1 && diff=gdiff command -v gdiff >/dev/null 2>&1 && diff=gdiff
which tkdiff >/dev/null 2>&1 && diff=tkdiff command -v tkdiff >/dev/null 2>&1 && diff=tkdiff
which xxdiff >/dev/null 2>&1 && diff=xxdiff command -v xxdiff >/dev/null 2>&1 && diff=xxdiff
fi fi
;; ;;
@ -391,7 +391,7 @@ BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
done done
# Set qemu-io cache mode with $CACHEMODE we have # Set qemu-io cache mode with $CACHEMODE we have
QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE" QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT --cache $CACHEMODE"
# Set default options for qemu-img create -o if they were not specified # Set default options for qemu-img create -o if they were not specified
_set_default_imgopts _set_default_imgopts

View File

@ -47,7 +47,7 @@ export PWD=`pwd`
# $1 = prog to look for, $2* = default pathnames if not found in $PATH # $1 = prog to look for, $2* = default pathnames if not found in $PATH
set_prog_path() set_prog_path()
{ {
p=`which $1 2> /dev/null` p=`command -v $1 2> /dev/null`
if [ -n "$p" -a -x "$p" ]; then if [ -n "$p" -a -x "$p" ]; then
echo $p echo $p
return 0 return 0

View File

@ -167,7 +167,9 @@ _filter_qmp()
{ {
_filter_win32 | \ _filter_win32 | \
sed -e 's#\("\(micro\)\?seconds": \)[0-9]\+#\1 TIMESTAMP#g' \ sed -e 's#\("\(micro\)\?seconds": \)[0-9]\+#\1 TIMESTAMP#g' \
-e 's#^{"QMP":.*}$#QMP_VERSION#' -e 's#^{"QMP":.*}$#QMP_VERSION#' \
-e '/^ "QMP": {\s*$/, /^ }\s*$/ c\' \
-e ' QMP_VERSION'
} }
# replace driver-specific options in the "Formatting..." line # replace driver-specific options in the "Formatting..." line

View File

@ -153,8 +153,9 @@ function _launch_qemu()
mkfifo "${fifo_out}" mkfifo "${fifo_out}"
mkfifo "${fifo_in}" mkfifo "${fifo_in}"
"${QEMU}" -nographic -serial none ${comm} -machine accel=qtest "${@}" 2>&1 \ "${QEMU}" -nographic -serial none ${comm} -machine accel=qtest "${@}" \
>"${fifo_out}" \ >"${fifo_out}" \
2>&1 \
<"${fifo_in}" & <"${fifo_in}" &
QEMU_PID[${_QEMU_HANDLE}]=$! QEMU_PID[${_QEMU_HANDLE}]=$!

View File

@ -175,7 +175,9 @@ _cleanup_test_img()
case "$IMGPROTO" in case "$IMGPROTO" in
nbd) nbd)
if [ -n "$QEMU_NBD_PID" ]; then
kill $QEMU_NBD_PID kill $QEMU_NBD_PID
fi
rm -f "$TEST_IMG_FILE" rm -f "$TEST_IMG_FILE"
;; ;;
file) file)
@ -213,6 +215,13 @@ _check_test_img()
_img_info() _img_info()
{ {
if [[ "$1" == "--format-specific" ]]; then
local format_specific=1
shift
else
local format_specific=0
fi
discard=0 discard=0
regex_json_spec_start='^ *"format-specific": \{' regex_json_spec_start='^ *"format-specific": \{'
$QEMU_IMG info "$@" "$TEST_IMG" 2>&1 | \ $QEMU_IMG info "$@" "$TEST_IMG" 2>&1 | \
@ -222,7 +231,9 @@ _img_info()
-e "/^disk size:/ D" \ -e "/^disk size:/ D" \
-e "/actual-size/ D" | \ -e "/actual-size/ D" | \
while IFS='' read line; do while IFS='' read line; do
if [[ $line == "Format specific information:" ]]; then if [[ $format_specific == 1 ]]; then
discard=0
elif [[ $line == "Format specific information:" ]]; then
discard=1 discard=1
elif [[ $line =~ $regex_json_spec_start ]]; then elif [[ $line =~ $regex_json_spec_start ]]; then
discard=2 discard=2

View File

@ -111,4 +111,7 @@
105 rw auto quick 105 rw auto quick
107 rw auto quick 107 rw auto quick
108 rw auto quick 108 rw auto quick
109 rw auto
111 rw auto quick 111 rw auto quick
113 rw auto quick
114 rw auto quick

View File

@ -7,6 +7,10 @@ import string
class QcowHeaderExtension: class QcowHeaderExtension:
def __init__(self, magic, length, data): def __init__(self, magic, length, data):
if length % 8 != 0:
padding = 8 - (length % 8)
data += "\0" * padding
self.magic = magic self.magic = magic
self.length = length self.length = length
self.data = data self.data = data

Binary file not shown.

View File

@ -87,7 +87,7 @@ int main(int argc, char **argv)
qtest_add_func("/uhci/pci/hotplug/usb-storage", test_usb_storage_hotplug); qtest_add_func("/uhci/pci/hotplug/usb-storage", test_usb_storage_hotplug);
qtest_start("-device piix3-usb-uhci,id=uhci,addr=1d.0" qtest_start("-device piix3-usb-uhci,id=uhci,addr=1d.0"
" -drive id=drive0,if=none,file=/dev/null" " -drive id=drive0,if=none,file=/dev/null,format=raw"
" -device usb-tablet,bus=uhci.0,port=1"); " -device usb-tablet,bus=uhci.0,port=1");
ret = g_test_run(); ret = g_test_run();
qtest_end(); qtest_end();

View File

@ -91,7 +91,7 @@ int main(int argc, char **argv)
qtest_add_func("/xhci/pci/hotplug/usb-uas", test_usb_uas_hotplug); qtest_add_func("/xhci/pci/hotplug/usb-uas", test_usb_uas_hotplug);
qtest_start("-device nec-usb-xhci,id=xhci" qtest_start("-device nec-usb-xhci,id=xhci"
" -drive id=drive0,if=none,file=/dev/null"); " -drive id=drive0,if=none,file=/dev/null,format=raw");
ret = g_test_run(); ret = g_test_run();
qtest_end(); qtest_end();

View File

@ -68,8 +68,8 @@ static QPCIBus *test_start(void)
g_assert_cmpint(ret, ==, 0); g_assert_cmpint(ret, ==, 0);
close(fd); close(fd);
cmdline = g_strdup_printf("-drive if=none,id=drive0,file=%s " cmdline = g_strdup_printf("-drive if=none,id=drive0,file=%s,format=raw "
"-drive if=none,id=drive1,file=/dev/null " "-drive if=none,id=drive1,file=/dev/null,format=raw "
"-device virtio-blk-pci,id=drv0,drive=drive0," "-device virtio-blk-pci,id=drv0,drive=drive0,"
"addr=%x.%x", "addr=%x.%x",
tmp_path, PCI_SLOT, PCI_FN); tmp_path, PCI_SLOT, PCI_FN);

View File

@ -52,8 +52,8 @@ int main(int argc, char **argv)
qtest_add_func("/virtio/scsi/pci/nop", pci_nop); qtest_add_func("/virtio/scsi/pci/nop", pci_nop);
qtest_add_func("/virtio/scsi/pci/hotplug", hotplug); qtest_add_func("/virtio/scsi/pci/hotplug", hotplug);
qtest_start("-drive id=drv0,if=none,file=/dev/null " qtest_start("-drive id=drv0,if=none,file=/dev/null,format=raw "
"-drive id=drv1,if=none,file=/dev/null " "-drive id=drv1,if=none,file=/dev/null,format=raw "
"-device virtio-scsi-pci,id=vscsi0 " "-device virtio-scsi-pci,id=vscsi0 "
"-device scsi-hd,bus=vscsi0.0,drive=drv0"); "-device scsi-hd,bus=vscsi0.0,drive=drv0");
ret = g_test_run(); ret = g_test_run();

15
vl.c
View File

@ -2284,7 +2284,7 @@ static int mon_init_func(QemuOpts *opts, void *opaque)
return 0; return 0;
} }
static void monitor_parse(const char *optarg, const char *mode) static void monitor_parse(const char *optarg, const char *mode, bool pretty)
{ {
static int monitor_device_index = 0; static int monitor_device_index = 0;
QemuOpts *opts; QemuOpts *opts;
@ -2314,6 +2314,7 @@ static void monitor_parse(const char *optarg, const char *mode)
} }
qemu_opt_set(opts, "mode", mode); qemu_opt_set(opts, "mode", mode);
qemu_opt_set(opts, "chardev", label); qemu_opt_set(opts, "chardev", label);
qemu_opt_set_bool(opts, "pretty", pretty);
if (def) if (def)
qemu_opt_set(opts, "default", "on"); qemu_opt_set(opts, "default", "on");
monitor_device_index++; monitor_device_index++;
@ -3292,11 +3293,15 @@ int main(int argc, char **argv, char **envp)
case QEMU_OPTION_monitor: case QEMU_OPTION_monitor:
default_monitor = 0; default_monitor = 0;
if (strncmp(optarg, "none", 4)) { if (strncmp(optarg, "none", 4)) {
monitor_parse(optarg, "readline"); monitor_parse(optarg, "readline", false);
} }
break; break;
case QEMU_OPTION_qmp: case QEMU_OPTION_qmp:
monitor_parse(optarg, "control"); monitor_parse(optarg, "control", false);
default_monitor = 0;
break;
case QEMU_OPTION_qmp_pretty:
monitor_parse(optarg, "control", true);
default_monitor = 0; default_monitor = 0;
break; break;
case QEMU_OPTION_mon: case QEMU_OPTION_mon:
@ -3994,7 +3999,7 @@ int main(int argc, char **argv, char **envp)
add_device_config(DEV_SCLP, "stdio"); add_device_config(DEV_SCLP, "stdio");
} }
if (default_monitor) if (default_monitor)
monitor_parse("stdio", "readline"); monitor_parse("stdio", "readline", false);
} }
} else { } else {
if (default_serial) if (default_serial)
@ -4002,7 +4007,7 @@ int main(int argc, char **argv, char **envp)
if (default_parallel) if (default_parallel)
add_device_config(DEV_PARALLEL, "vc:80Cx24C"); add_device_config(DEV_PARALLEL, "vc:80Cx24C");
if (default_monitor) if (default_monitor)
monitor_parse("vc:80Cx24C", "readline"); monitor_parse("vc:80Cx24C", "readline", false);
if (default_virtcon) if (default_virtcon)
add_device_config(DEV_VIRTCON, "vc:80Cx24C"); add_device_config(DEV_VIRTCON, "vc:80Cx24C");
if (default_sclp) { if (default_sclp) {