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:
commit
7c3843332d
@ -73,7 +73,7 @@ void aio_set_fd_handler(AioContext *ctx,
|
||||
} else {
|
||||
if (node == NULL) {
|
||||
/* Alloc and insert if it's not already there */
|
||||
node = g_malloc0(sizeof(AioHandler));
|
||||
node = g_new0(AioHandler, 1);
|
||||
node->pfd.fd = fd;
|
||||
QLIST_INSERT_HEAD(&ctx->aio_handlers, node, node);
|
||||
|
||||
|
@ -67,7 +67,7 @@ void aio_set_fd_handler(AioContext *ctx,
|
||||
|
||||
if (node == NULL) {
|
||||
/* Alloc and insert if it's not already there */
|
||||
node = g_malloc0(sizeof(AioHandler));
|
||||
node = g_new0(AioHandler, 1);
|
||||
node->pfd.fd = fd;
|
||||
QLIST_INSERT_HEAD(&ctx->aio_handlers, node, node);
|
||||
}
|
||||
@ -129,7 +129,7 @@ void aio_set_event_notifier(AioContext *ctx,
|
||||
} else {
|
||||
if (node == NULL) {
|
||||
/* Alloc and insert if it's not already there */
|
||||
node = g_malloc0(sizeof(AioHandler));
|
||||
node = g_new0(AioHandler, 1);
|
||||
node->e = e;
|
||||
node->pfd.fd = (uintptr_t)event_notifier_get_handle(e);
|
||||
node->pfd.events = G_IO_IN;
|
||||
|
2
async.c
2
async.c
@ -44,7 +44,7 @@ struct QEMUBH {
|
||||
QEMUBH *aio_bh_new(AioContext *ctx, QEMUBHFunc *cb, void *opaque)
|
||||
{
|
||||
QEMUBH *bh;
|
||||
bh = g_malloc0(sizeof(QEMUBH));
|
||||
bh = g_new0(QEMUBH, 1);
|
||||
bh->ctx = ctx;
|
||||
bh->cb = cb;
|
||||
bh->opaque = opaque;
|
||||
|
100
block.c
100
block.c
@ -629,7 +629,7 @@ BlockDriver *bdrv_find_protocol(const char *filename,
|
||||
}
|
||||
|
||||
if (!path_has_protocol(filename) || !allow_protocol_prefix) {
|
||||
return bdrv_find_format("file");
|
||||
return &bdrv_file;
|
||||
}
|
||||
|
||||
p = strchr(filename, ':');
|
||||
@ -648,22 +648,49 @@ BlockDriver *bdrv_find_protocol(const char *filename,
|
||||
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,
|
||||
BlockDriver **pdrv, Error **errp)
|
||||
{
|
||||
int score, score_max;
|
||||
BlockDriver *drv1, *drv;
|
||||
uint8_t buf[2048];
|
||||
BlockDriver *drv;
|
||||
uint8_t buf[BLOCK_PROBE_BUF_SIZE];
|
||||
int ret = 0;
|
||||
|
||||
/* Return the raw BlockDriver * to scsi-generic devices or empty drives */
|
||||
if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) {
|
||||
drv = bdrv_find_format("raw");
|
||||
if (!drv) {
|
||||
error_setg(errp, "Could not find raw image format");
|
||||
ret = -ENOENT;
|
||||
}
|
||||
*pdrv = drv;
|
||||
*pdrv = &bdrv_raw;
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -675,17 +702,7 @@ static int find_image_format(BlockDriverState *bs, const char *filename,
|
||||
return ret;
|
||||
}
|
||||
|
||||
score_max = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
drv = bdrv_probe_all(buf, ret, filename);
|
||||
if (!drv) {
|
||||
error_setg(errp, "Could not determine image format: No compatible "
|
||||
"driver found");
|
||||
@ -1180,7 +1197,6 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
|
||||
{
|
||||
char *backing_filename = g_malloc0(PATH_MAX);
|
||||
int ret = 0;
|
||||
BlockDriver *back_drv = NULL;
|
||||
BlockDriverState *backing_hd;
|
||||
Error *local_err = NULL;
|
||||
|
||||
@ -1213,14 +1229,14 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)
|
||||
|
||||
backing_hd = bdrv_new();
|
||||
|
||||
if (bs->backing_format[0] != '\0') {
|
||||
back_drv = bdrv_find_format(bs->backing_format);
|
||||
if (bs->backing_format[0] != '\0' && !qdict_haskey(options, "driver")) {
|
||||
qdict_put(options, "driver", qstring_from_str(bs->backing_format));
|
||||
}
|
||||
|
||||
assert(bs->backing_hd == NULL);
|
||||
ret = bdrv_open(&backing_hd,
|
||||
*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) {
|
||||
bdrv_unref(backing_hd);
|
||||
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. */
|
||||
char *tmp_filename = g_malloc0(PATH_MAX + 1);
|
||||
int64_t total_size;
|
||||
BlockDriver *bdrv_qcow2;
|
||||
QemuOpts *opts = NULL;
|
||||
QDict *snapshot_options;
|
||||
BlockDriverState *bs_snapshot;
|
||||
@ -1319,11 +1334,10 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
|
||||
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);
|
||||
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);
|
||||
if (ret < 0) {
|
||||
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();
|
||||
|
||||
ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options,
|
||||
flags, bdrv_qcow2, &local_err);
|
||||
flags, &bdrv_qcow2, &local_err);
|
||||
if (ret < 0) {
|
||||
error_propagate(errp, local_err);
|
||||
goto out;
|
||||
@ -1467,6 +1481,7 @@ int bdrv_open(BlockDriverState **pbs, const char *filename,
|
||||
}
|
||||
|
||||
/* Image format probing */
|
||||
bs->probed = !drv;
|
||||
if (!drv && file) {
|
||||
ret = find_image_format(file, filename, &drv, &local_err);
|
||||
if (ret < 0) {
|
||||
@ -3801,6 +3816,14 @@ bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base)
|
||||
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)
|
||||
{
|
||||
if (!bs) {
|
||||
@ -3809,6 +3832,11 @@ BlockDriverState *bdrv_next(BlockDriverState *bs)
|
||||
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() */
|
||||
const char *bdrv_get_device_name(const BlockDriverState *bs)
|
||||
{
|
||||
@ -5541,6 +5569,18 @@ void bdrv_img_create(const char *filename, const char *fmt,
|
||||
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, proto_drv->create_opts);
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "block/accounting.h"
|
||||
#include "block/block_int.h"
|
||||
#include "qemu/timer.h"
|
||||
|
||||
void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
|
||||
int64_t bytes, enum BlockAcctType type)
|
||||
@ -31,7 +32,7 @@ void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
|
||||
assert(type < BLOCK_MAX_IOTYPE);
|
||||
|
||||
cookie->bytes = bytes;
|
||||
cookie->start_time_ns = get_clock();
|
||||
cookie->start_time_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
|
||||
cookie->type = type;
|
||||
}
|
||||
|
||||
@ -41,7 +42,8 @@ void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie)
|
||||
|
||||
stats->nr_bytes[cookie->type] += cookie->bytes;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -721,91 +721,48 @@ static int64_t blkdebug_getlength(BlockDriverState *bs)
|
||||
|
||||
static void blkdebug_refresh_filename(BlockDriverState *bs)
|
||||
{
|
||||
BDRVBlkdebugState *s = bs->opaque;
|
||||
struct BlkdebugRule *rule;
|
||||
QDict *opts;
|
||||
QList *inject_error_list = NULL, *set_state_list = NULL;
|
||||
QList *suspend_list = NULL;
|
||||
int event;
|
||||
const QDictEntry *e;
|
||||
bool force_json = false;
|
||||
|
||||
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
|
||||
* is impossible */
|
||||
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();
|
||||
qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("blkdebug")));
|
||||
|
||||
QINCREF(bs->file->full_open_options);
|
||||
qdict_put_obj(opts, "image", QOBJECT(bs->file->full_open_options));
|
||||
|
||||
for (event = 0; event < BLKDBG_EVENT_MAX; event++) {
|
||||
QLIST_FOREACH(rule, &s->rules[event], next) {
|
||||
if (rule->action == ACTION_INJECT_ERROR) {
|
||||
QDict *inject_error = qdict_new();
|
||||
|
||||
qdict_put_obj(inject_error, "event", QOBJECT(qstring_from_str(
|
||||
BlkdebugEvent_lookup[rule->event])));
|
||||
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();
|
||||
for (e = qdict_first(bs->options); e; e = qdict_next(bs->options, e)) {
|
||||
if (strcmp(qdict_entry_key(e), "x-image") &&
|
||||
strcmp(qdict_entry_key(e), "image") &&
|
||||
strncmp(qdict_entry_key(e), "image.", strlen("image.")))
|
||||
{
|
||||
qobject_incref(qdict_entry_value(e));
|
||||
qdict_put_obj(opts, qdict_entry_key(e), qdict_entry_value(e));
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void blk_invalidate_cache(BlockBackend *blk, Error **errp)
|
||||
{
|
||||
bdrv_invalidate_cache(blk->bs, errp);
|
||||
}
|
||||
|
||||
int blk_is_inserted(BlockBackend *blk)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
bdrv_io_plug(blk->bs);
|
||||
|
15
block/nfs.c
15
block/nfs.c
@ -409,6 +409,19 @@ out:
|
||||
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)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -470,6 +483,8 @@ static BlockDriver bdrv_nfs = {
|
||||
|
||||
.instance_size = sizeof(NFSClient),
|
||||
.bdrv_needs_filename = true,
|
||||
.create_opts = &nfs_create_opts,
|
||||
|
||||
.bdrv_has_zero_init = nfs_has_zero_init,
|
||||
.bdrv_get_allocated_file_size = nfs_get_allocated_file_size,
|
||||
.bdrv_truncate = nfs_file_truncate,
|
||||
|
32
block/qapi.c
32
block/qapi.c
@ -40,6 +40,13 @@ BlockDeviceInfo *bdrv_block_device_info(BlockDriverState *bs)
|
||||
info->encrypted = bs->encrypted;
|
||||
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]) {
|
||||
info->has_node_name = true;
|
||||
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);
|
||||
}
|
||||
|
||||
static BlockStats *bdrv_query_stats(const BlockDriverState *bs)
|
||||
static BlockStats *bdrv_query_stats(const BlockDriverState *bs,
|
||||
bool query_backing)
|
||||
{
|
||||
BlockStats *s;
|
||||
|
||||
@ -311,6 +319,11 @@ static BlockStats *bdrv_query_stats(const BlockDriverState *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->rd_bytes = bs->stats.nr_bytes[BLOCK_ACCT_READ];
|
||||
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) {
|
||||
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->backing = bdrv_query_stats(bs->backing_hd);
|
||||
s->backing = bdrv_query_stats(bs->backing_hd, query_backing);
|
||||
}
|
||||
|
||||
return s;
|
||||
@ -361,17 +374,22 @@ BlockInfoList *qmp_query_block(Error **errp)
|
||||
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;
|
||||
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));
|
||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||
|
||||
aio_context_acquire(ctx);
|
||||
info->value = bdrv_query_stats(bs);
|
||||
info->value = bdrv_query_stats(bs, !query_nodes);
|
||||
aio_context_release(ctx);
|
||||
|
||||
*p_next = info;
|
||||
|
@ -1263,7 +1263,7 @@ int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
|
||||
|
||||
again:
|
||||
start = offset;
|
||||
remaining = *num << BDRV_SECTOR_BITS;
|
||||
remaining = (uint64_t)*num << BDRV_SECTOR_BITS;
|
||||
cluster_offset = 0;
|
||||
*host_offset = 0;
|
||||
cur_bytes = 0;
|
||||
|
@ -117,7 +117,7 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
|
||||
#ifdef DEBUG_EXT
|
||||
printf("ext.magic = 0x%x\n", ext.magic);
|
||||
#endif
|
||||
if (ext.len > end_offset - offset) {
|
||||
if (offset > end_offset || ext.len > end_offset - offset) {
|
||||
error_setg(errp, "Header extension too large");
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -1428,11 +1428,24 @@ static void qcow2_close(BlockDriverState *bs)
|
||||
s->l1_table = NULL;
|
||||
|
||||
if (!(bs->open_flags & BDRV_O_INCOMING)) {
|
||||
qcow2_cache_flush(bs, s->l2_table_cache);
|
||||
qcow2_cache_flush(bs, s->refcount_block_cache);
|
||||
int ret1, ret2;
|
||||
|
||||
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_cache_destroy(bs, s->l2_table_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
|
||||
* table)
|
||||
*/
|
||||
BlockDriver* drv = bdrv_find_format("qcow2");
|
||||
assert(drv != 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) {
|
||||
error_propagate(errp, local_err);
|
||||
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 */
|
||||
ret = bdrv_open(&bs, filename, NULL, NULL,
|
||||
BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_BACKING,
|
||||
drv, &local_err);
|
||||
&bdrv_qcow2, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
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
|
||||
sector based I/Os */
|
||||
cluster_offset = bdrv_getlength(bs->file);
|
||||
bdrv_truncate(bs->file, cluster_offset);
|
||||
return 0;
|
||||
return bdrv_truncate(bs->file, cluster_offset);
|
||||
}
|
||||
|
||||
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",
|
||||
.instance_size = sizeof(BDRVQcowState),
|
||||
.bdrv_probe = qcow2_probe,
|
||||
|
@ -446,6 +446,7 @@ static int raw_open_common(BlockDriverState *bs, QDict *options,
|
||||
}
|
||||
|
||||
if (fstat(s->fd, &st) < 0) {
|
||||
ret = -errno;
|
||||
error_setg_errno(errp, errno, "Could not stat file");
|
||||
goto fail;
|
||||
}
|
||||
@ -1684,7 +1685,7 @@ static QemuOptsList raw_create_opts = {
|
||||
}
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_file = {
|
||||
BlockDriver bdrv_file = {
|
||||
.format_name = "file",
|
||||
.protocol_name = "file",
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
@ -1922,7 +1923,7 @@ static int fd_open(BlockDriverState *bs)
|
||||
return 0;
|
||||
last_media_present = (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);
|
||||
s->fd = -1;
|
||||
#ifdef DEBUG_FLOPPY
|
||||
@ -1931,7 +1932,7 @@ static int fd_open(BlockDriverState *bs)
|
||||
}
|
||||
if (s->fd < 0) {
|
||||
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
|
||||
printf("No floppy (open delayed)\n");
|
||||
#endif
|
||||
@ -1939,7 +1940,7 @@ static int fd_open(BlockDriverState *bs)
|
||||
}
|
||||
s->fd = qemu_open(bs->filename, s->open_flags & ~O_NONBLOCK);
|
||||
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;
|
||||
if (last_media_present)
|
||||
s->fd_media_changed = 1;
|
||||
@ -1954,7 +1955,7 @@ static int fd_open(BlockDriverState *bs)
|
||||
}
|
||||
if (!last_media_present)
|
||||
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;
|
||||
return 0;
|
||||
}
|
||||
|
@ -540,7 +540,7 @@ static QemuOptsList raw_create_opts = {
|
||||
}
|
||||
};
|
||||
|
||||
static BlockDriver bdrv_file = {
|
||||
BlockDriver bdrv_file = {
|
||||
.format_name = "file",
|
||||
.protocol_name = "file",
|
||||
.instance_size = sizeof(BDRVRawState),
|
||||
|
@ -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,
|
||||
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);
|
||||
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,
|
||||
@ -158,6 +208,18 @@ static int raw_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
Error **errp)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -173,7 +235,7 @@ static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static BlockDriver bdrv_raw = {
|
||||
BlockDriver bdrv_raw = {
|
||||
.format_name = "raw",
|
||||
.bdrv_probe = &raw_probe,
|
||||
.bdrv_reopen_prepare = &raw_reopen_prepare,
|
||||
|
@ -852,11 +852,6 @@ static QemuOptsList vdi_create_opts = {
|
||||
.def_value_str = "off"
|
||||
},
|
||||
#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. */
|
||||
{ /* end of list */ }
|
||||
}
|
||||
|
29
block/vmdk.c
29
block/vmdk.c
@ -28,6 +28,7 @@
|
||||
#include "qemu/module.h"
|
||||
#include "migration/migration.h"
|
||||
#include <zlib.h>
|
||||
#include <glib.h>
|
||||
|
||||
#define VMDK3_MAGIC (('C' << 24) | ('O' << 16) | ('W' << 8) | 'D')
|
||||
#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;
|
||||
}
|
||||
|
||||
size = MIN(size, 1 << 20); /* avoid unbounded allocation */
|
||||
buf = g_malloc0(size + 1);
|
||||
if (size < 4) {
|
||||
/* 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);
|
||||
if (ret < 0) {
|
||||
@ -565,6 +574,7 @@ static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
|
||||
g_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
buf[ret] = 0;
|
||||
|
||||
return buf;
|
||||
}
|
||||
@ -635,6 +645,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
||||
bs->file->total_sectors * 512 - 1536,
|
||||
&footer, sizeof(footer));
|
||||
if (ret < 0) {
|
||||
error_setg_errno(errp, -ret, "Failed to read footer");
|
||||
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.type) != MARKER_END_OF_STREAM)
|
||||
{
|
||||
error_setg(errp, "Invalid footer");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -676,6 +688,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
||||
l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gt)
|
||||
* le64_to_cpu(header.granularity);
|
||||
if (l1_entry_sectors == 0) {
|
||||
error_setg(errp, "L1 entry size is invalid");
|
||||
return -EINVAL;
|
||||
}
|
||||
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;
|
||||
|
||||
while (*p) {
|
||||
/* parse extent line:
|
||||
/* parse extent line in one of below formats:
|
||||
*
|
||||
* RW [size in sectors] FLAT "file-name.vmdk" OFFSET
|
||||
* or
|
||||
* 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;
|
||||
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,
|
||||
Error **errp)
|
||||
{
|
||||
char *buf = NULL;
|
||||
char *buf;
|
||||
int ret;
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
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
|
||||
* opened */
|
||||
if (!s->cid_updated) {
|
||||
ret = vmdk_write_cid(bs, time(NULL));
|
||||
ret = vmdk_write_cid(bs, g_random_int());
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
@ -1922,7 +1937,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||
}
|
||||
/* generate descriptor file */
|
||||
desc = g_strdup_printf(desc_template,
|
||||
(uint32_t)time(NULL),
|
||||
g_random_int(),
|
||||
parent_cid,
|
||||
fmt,
|
||||
parent_desc_line,
|
||||
|
@ -893,11 +893,6 @@ static QemuOptsList vpc_create_opts = {
|
||||
"Type of virtual hard disk format. Supported formats are "
|
||||
"{dynamic (default) | fixed} "
|
||||
},
|
||||
{
|
||||
.name = BLOCK_OPT_NOCOW,
|
||||
.type = QEMU_OPT_BOOL,
|
||||
.help = "Turn off copy-on-write (valid only on btrfs)"
|
||||
},
|
||||
{ /* end of list */ }
|
||||
}
|
||||
};
|
||||
|
@ -2917,6 +2917,12 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp)
|
||||
}
|
||||
|
||||
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);
|
||||
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, s->sector_count * 512);
|
||||
qemu_opt_set(opts, BLOCK_OPT_BACKING_FILE, "fat:");
|
||||
|
@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
#include "sysemu/blockdev.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "hw/block/block.h"
|
||||
#include "monitor/monitor.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,
|
||||
Error **errp)
|
||||
{
|
||||
BlockDriverState *bs;
|
||||
BlockBackend *blk;
|
||||
NBDExport *exp;
|
||||
NBDCloseNotifier *n;
|
||||
|
||||
@ -87,12 +88,12 @@ void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
|
||||
return;
|
||||
}
|
||||
|
||||
bs = bdrv_find(device);
|
||||
if (!bs) {
|
||||
blk = blk_by_name(device);
|
||||
if (!blk) {
|
||||
error_set(errp, QERR_DEVICE_NOT_FOUND, device);
|
||||
return;
|
||||
}
|
||||
if (!bdrv_is_inserted(bs)) {
|
||||
if (!blk_is_inserted(blk)) {
|
||||
error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
|
||||
return;
|
||||
}
|
||||
@ -100,18 +101,18 @@ void qmp_nbd_server_add(const char *device, bool has_writable, bool writable,
|
||||
if (!has_writable) {
|
||||
writable = false;
|
||||
}
|
||||
if (bdrv_is_read_only(bs)) {
|
||||
if (blk_is_read_only(blk)) {
|
||||
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);
|
||||
|
||||
n = g_new0(NBDCloseNotifier, 1);
|
||||
n->n.notify = nbd_close_notifier;
|
||||
n->exp = exp;
|
||||
bdrv_add_close_notifier(bs, &n->n);
|
||||
blk_add_close_notifier(blk, &n->n);
|
||||
QTAILQ_INSERT_TAIL(&close_notifiers, n, next);
|
||||
}
|
||||
|
||||
|
149
blockdev.c
149
blockdev.c
@ -1105,6 +1105,7 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
|
||||
Error **errp)
|
||||
{
|
||||
BlockDriverState *bs = bdrv_find(device);
|
||||
AioContext *aio_context;
|
||||
QEMUSnapshotInfo sn;
|
||||
Error *local_err = NULL;
|
||||
SnapshotInfo *info = NULL;
|
||||
@ -1128,25 +1129,34 @@ SnapshotInfo *qmp_blockdev_snapshot_delete_internal_sync(const char *device,
|
||||
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);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return NULL;
|
||||
goto out_aio_context;
|
||||
}
|
||||
if (!ret) {
|
||||
error_setg(errp,
|
||||
"Snapshot with id '%s' and name '%s' does not exist on "
|
||||
"device '%s'",
|
||||
STR_OR_NULL(id), STR_OR_NULL(name), device);
|
||||
return NULL;
|
||||
goto out_aio_context;
|
||||
}
|
||||
|
||||
bdrv_snapshot_delete(bs, id, name, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return NULL;
|
||||
goto out_aio_context;
|
||||
}
|
||||
|
||||
aio_context_release(aio_context);
|
||||
|
||||
info = g_new0(SnapshotInfo, 1);
|
||||
info->id = g_strdup(sn.id_str);
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
@ -1193,6 +1207,7 @@ struct BlkTransactionState {
|
||||
typedef struct InternalSnapshotState {
|
||||
BlkTransactionState common;
|
||||
BlockDriverState *bs;
|
||||
AioContext *aio_context;
|
||||
QEMUSnapshotInfo sn;
|
||||
} InternalSnapshotState;
|
||||
|
||||
@ -1226,11 +1241,19 @@ static void internal_snapshot_prepare(BlkTransactionState *common,
|
||||
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)) {
|
||||
error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
|
||||
return;
|
||||
}
|
||||
|
||||
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bdrv_is_read_only(bs)) {
|
||||
error_set(errp, QERR_DEVICE_IS_READ_ONLY, device);
|
||||
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 */
|
||||
typedef struct ExternalSnapshotState {
|
||||
BlkTransactionState common;
|
||||
BlockDriverState *old_bs;
|
||||
BlockDriverState *new_bs;
|
||||
AioContext *aio_context;
|
||||
} ExternalSnapshotState;
|
||||
|
||||
static void external_snapshot_prepare(BlkTransactionState *common,
|
||||
@ -1374,6 +1408,10 @@ static void external_snapshot_prepare(BlkTransactionState *common,
|
||||
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)) {
|
||||
error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
|
||||
return;
|
||||
@ -1432,6 +1470,8 @@ static void external_snapshot_commit(BlkTransactionState *common)
|
||||
ExternalSnapshotState *state =
|
||||
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 */
|
||||
bdrv_append(state->new_bs, state->old_bs);
|
||||
/* 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 */
|
||||
bdrv_reopen(state->new_bs, state->new_bs->open_flags & ~BDRV_O_RDWR,
|
||||
NULL);
|
||||
|
||||
aio_context_release(state->aio_context);
|
||||
}
|
||||
|
||||
static void external_snapshot_abort(BlkTransactionState *common)
|
||||
@ -1448,23 +1490,38 @@ static void external_snapshot_abort(BlkTransactionState *common)
|
||||
if (state->new_bs) {
|
||||
bdrv_unref(state->new_bs);
|
||||
}
|
||||
if (state->aio_context) {
|
||||
aio_context_release(state->aio_context);
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct DriveBackupState {
|
||||
BlkTransactionState common;
|
||||
BlockDriverState *bs;
|
||||
AioContext *aio_context;
|
||||
BlockJob *job;
|
||||
} DriveBackupState;
|
||||
|
||||
static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
|
||||
{
|
||||
DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
|
||||
BlockDriverState *bs;
|
||||
DriveBackup *backup;
|
||||
Error *local_err = NULL;
|
||||
|
||||
assert(common->action->kind == TRANSACTION_ACTION_KIND_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,
|
||||
backup->has_format, backup->format,
|
||||
backup->sync,
|
||||
@ -1475,12 +1532,10 @@ static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
state->bs = NULL;
|
||||
state->job = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
state->bs = bdrv_find(backup->device);
|
||||
state->bs = bs;
|
||||
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)
|
||||
{
|
||||
error_setg(errp, "Transaction aborted using Abort action");
|
||||
@ -1516,6 +1580,7 @@ static const BdrvActionOps actions[] = {
|
||||
.instance_size = sizeof(DriveBackupState),
|
||||
.prepare = drive_backup_prepare,
|
||||
.abort = drive_backup_abort,
|
||||
.clean = drive_backup_clean,
|
||||
},
|
||||
[TRANSACTION_ACTION_KIND_ABORT] = {
|
||||
.instance_size = sizeof(BlkTransactionState),
|
||||
@ -1526,13 +1591,13 @@ static const BdrvActionOps actions[] = {
|
||||
.instance_size = sizeof(InternalSnapshotState),
|
||||
.prepare = internal_snapshot_prepare,
|
||||
.abort = internal_snapshot_abort,
|
||||
.clean = internal_snapshot_clean,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
* 'Atomic' group snapshots. The snapshots are taken as a set, and if any fail
|
||||
* then we do not pivot any of the devices in the group, and abandon the
|
||||
* snapshots
|
||||
* 'Atomic' group operations. The operations are performed as a set, and if
|
||||
* any fail then we roll back all operations in the group.
|
||||
*/
|
||||
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_INIT(&snap_bdrv_states);
|
||||
|
||||
/* drain all i/o before any snapshots */
|
||||
/* drain all i/o before any operations */
|
||||
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) {
|
||||
TransactionAction *dev_info = NULL;
|
||||
const BdrvActionOps *ops;
|
||||
@ -1581,10 +1646,7 @@ void qmp_transaction(TransactionActionList *dev_list, Error **errp)
|
||||
goto exit;
|
||||
|
||||
delete_and_fail:
|
||||
/*
|
||||
* failure, and it is all-or-none; abandon each new bs, and keep using
|
||||
* the original bs for all images
|
||||
*/
|
||||
/* failure, and it is all-or-none; roll back all operations */
|
||||
QSIMPLEQ_FOREACH(state, &snap_bdrv_states, entry) {
|
||||
if (state->ops->abort) {
|
||||
state->ops->abort(state);
|
||||
@ -1603,14 +1665,18 @@ exit:
|
||||
static void eject_device(BlockBackend *blk, int force, Error **errp)
|
||||
{
|
||||
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)) {
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
if (!blk_dev_has_removable_media(blk)) {
|
||||
error_setg(errp, "Device '%s' is not removable",
|
||||
bdrv_get_device_name(bs));
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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) {
|
||||
error_setg(errp, "Device '%s' is locked",
|
||||
bdrv_get_device_name(bs));
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
bdrv_close(bs);
|
||||
|
||||
out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
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;
|
||||
BlockDriverState *bs;
|
||||
AioContext *aio_context;
|
||||
int err;
|
||||
|
||||
bs = bdrv_lookup_bs(has_device ? device : NULL,
|
||||
@ -1654,16 +1724,23 @@ void qmp_block_passwd(bool has_device, const char *device,
|
||||
return;
|
||||
}
|
||||
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
err = bdrv_set_key(bs, password);
|
||||
if (err == -EINVAL) {
|
||||
error_set(errp, QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs));
|
||||
return;
|
||||
goto out;
|
||||
} else if (err < 0) {
|
||||
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,
|
||||
int bdrv_flags, BlockDriver *drv,
|
||||
const char *password, Error **errp)
|
||||
@ -1696,6 +1773,7 @@ void qmp_change_blockdev(const char *device, const char *filename,
|
||||
{
|
||||
BlockBackend *blk;
|
||||
BlockDriverState *bs;
|
||||
AioContext *aio_context;
|
||||
BlockDriver *drv = NULL;
|
||||
int bdrv_flags;
|
||||
Error *err = NULL;
|
||||
@ -1707,24 +1785,30 @@ void qmp_change_blockdev(const char *device, const char *filename,
|
||||
}
|
||||
bs = blk_bs(blk);
|
||||
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
if (format) {
|
||||
drv = bdrv_find_whitelisted_format(format, bs->read_only);
|
||||
if (!drv) {
|
||||
error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
eject_device(blk, 0, &err);
|
||||
if (err) {
|
||||
error_propagate(errp, err);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR;
|
||||
bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0;
|
||||
|
||||
qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, drv, NULL, errp);
|
||||
|
||||
out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
/* throttling disk I/O limits */
|
||||
@ -2548,6 +2632,7 @@ void qmp_change_backing_file(const char *device,
|
||||
Error **errp)
|
||||
{
|
||||
BlockDriverState *bs = NULL;
|
||||
AioContext *aio_context;
|
||||
BlockDriverState *image_bs = NULL;
|
||||
Error *local_err = NULL;
|
||||
bool ro;
|
||||
@ -2561,34 +2646,37 @@ void qmp_change_backing_file(const char *device,
|
||||
return;
|
||||
}
|
||||
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
image_bs = bdrv_lookup_bs(NULL, image_node_name, &local_err);
|
||||
if (local_err) {
|
||||
error_propagate(errp, local_err);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!image_bs) {
|
||||
error_setg(errp, "image file not found");
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (bdrv_find_base(image_bs) == image_bs) {
|
||||
error_setg(errp, "not allowing backing file change on an image "
|
||||
"without a backing file");
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* even though we are not necessarily operating on bs, we need it to
|
||||
* determine if block ops are currently prohibited on the chain */
|
||||
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_CHANGE, errp)) {
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* final sanity check */
|
||||
if (!bdrv_chain_contains(bs, image_bs)) {
|
||||
error_setg(errp, "'%s' and image file are not in the same chain",
|
||||
device);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* 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);
|
||||
if (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 */
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
|
||||
|
157
hmp.c
157
hmp.c
@ -290,70 +290,74 @@ void hmp_info_cpus(Monitor *mon, const QDict *qdict)
|
||||
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;
|
||||
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 (device && strcmp(device, info->value->device)) {
|
||||
continue;
|
||||
if (info) {
|
||||
monitor_printf(mon, "%s", info->device);
|
||||
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) {
|
||||
monitor_printf(mon, "\n");
|
||||
}
|
||||
|
||||
monitor_printf(mon, "%s", info->value->device);
|
||||
if (info->value->has_inserted) {
|
||||
if (inserted) {
|
||||
monitor_printf(mon, ": %s (%s%s%s)\n",
|
||||
info->value->inserted->file,
|
||||
info->value->inserted->drv,
|
||||
info->value->inserted->ro ? ", read-only" : "",
|
||||
info->value->inserted->encrypted ? ", encrypted" : "");
|
||||
inserted->file,
|
||||
inserted->drv,
|
||||
inserted->ro ? ", read-only" : "",
|
||||
inserted->encrypted ? ", encrypted" : "");
|
||||
} else {
|
||||
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",
|
||||
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",
|
||||
info->value->locked ? "" : "not ",
|
||||
info->value->tray_open ? "open" : "closed");
|
||||
info->locked ? "" : "not ",
|
||||
info->tray_open ? "open" : "closed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!info->value->has_inserted) {
|
||||
continue;
|
||||
if (!inserted) {
|
||||
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,
|
||||
" Backing file: %s "
|
||||
"(chain depth: %" PRId64 ")\n",
|
||||
info->value->inserted->backing_file,
|
||||
info->value->inserted->backing_file_depth);
|
||||
inserted->backing_file,
|
||||
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",
|
||||
BlockdevDetectZeroesOptions_lookup[info->value->inserted->detect_zeroes]);
|
||||
BlockdevDetectZeroesOptions_lookup[inserted->detect_zeroes]);
|
||||
}
|
||||
|
||||
if (info->value->inserted->bps
|
||||
|| info->value->inserted->bps_rd
|
||||
|| info->value->inserted->bps_wr
|
||||
|| info->value->inserted->iops
|
||||
|| info->value->inserted->iops_rd
|
||||
|| info->value->inserted->iops_wr)
|
||||
if (inserted->bps || inserted->bps_rd || inserted->bps_wr ||
|
||||
inserted->iops || inserted->iops_rd || inserted->iops_wr)
|
||||
{
|
||||
monitor_printf(mon, " I/O throttling: bps=%" 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_wr_max=%" PRId64
|
||||
" iops_size=%" PRId64 "\n",
|
||||
info->value->inserted->bps,
|
||||
info->value->inserted->bps_rd,
|
||||
info->value->inserted->bps_wr,
|
||||
info->value->inserted->bps_max,
|
||||
info->value->inserted->bps_rd_max,
|
||||
info->value->inserted->bps_wr_max,
|
||||
info->value->inserted->iops,
|
||||
info->value->inserted->iops_rd,
|
||||
info->value->inserted->iops_wr,
|
||||
info->value->inserted->iops_max,
|
||||
info->value->inserted->iops_rd_max,
|
||||
info->value->inserted->iops_wr_max,
|
||||
info->value->inserted->iops_size);
|
||||
inserted->bps,
|
||||
inserted->bps_rd,
|
||||
inserted->bps_wr,
|
||||
inserted->bps_max,
|
||||
inserted->bps_rd_max,
|
||||
inserted->bps_wr_max,
|
||||
inserted->iops,
|
||||
inserted->iops_rd,
|
||||
inserted->iops_wr,
|
||||
inserted->iops_max,
|
||||
inserted->iops_rd_max,
|
||||
inserted->iops_wr_max,
|
||||
inserted->iops_size);
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
monitor_printf(mon, "\nImages:\n");
|
||||
image_info = info->value->inserted->image;
|
||||
image_info = inserted->image;
|
||||
while (1) {
|
||||
bdrv_image_info_dump((fprintf_function)monitor_printf,
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
if (!stats->value->has_device) {
|
||||
|
@ -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_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_CHANGE, 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_STREAM, s->blocker);
|
||||
blk_op_unblock(conf->conf.blk, BLOCK_OP_TYPE_REPLACE, s->blocker);
|
||||
|
@ -811,6 +811,7 @@ static int nvme_init(PCIDevice *pci_dev)
|
||||
NVME_CAP_SET_AMS(n->bar.cap, 1);
|
||||
NVME_CAP_SET_TO(n->bar.cap, 0xf);
|
||||
NVME_CAP_SET_CSS(n->bar.cap, 1);
|
||||
NVME_CAP_SET_MPSMAX(n->bar.cap, 4);
|
||||
|
||||
n->bar.vs = 0x00010001;
|
||||
n->bar.intmc = n->bar.intms = 0;
|
||||
|
@ -688,7 +688,7 @@ typedef struct NvmeCtrl {
|
||||
NvmeBar bar;
|
||||
BlockConf conf;
|
||||
|
||||
uint16_t page_size;
|
||||
uint32_t page_size;
|
||||
uint16_t page_bits;
|
||||
uint16_t max_prp_ents;
|
||||
uint16_t cqe_size;
|
||||
|
@ -34,15 +34,15 @@
|
||||
#include <hw/ide/pci.h>
|
||||
#include <hw/ide/ahci.h>
|
||||
|
||||
/* #define DEBUG_AHCI */
|
||||
#define DEBUG_AHCI 0
|
||||
|
||||
#ifdef DEBUG_AHCI
|
||||
#define DPRINTF(port, fmt, ...) \
|
||||
do { fprintf(stderr, "ahci: %s: [%d] ", __FUNCTION__, port); \
|
||||
fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
|
||||
#else
|
||||
#define DPRINTF(port, fmt, ...) do {} while(0)
|
||||
#endif
|
||||
do { \
|
||||
if (DEBUG_AHCI) { \
|
||||
fprintf(stderr, "ahci: %s: [%d] ", __func__, port); \
|
||||
fprintf(stderr, fmt, ## __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static void check_cmd(AHCIState *s, int port);
|
||||
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)
|
||||
{
|
||||
#ifdef DEBUG_AHCI
|
||||
#if DEBUG_AHCI
|
||||
int i;
|
||||
|
||||
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];
|
||||
ide_state = &ad->port.ifs[0];
|
||||
|
||||
sdb_fis->type = 0xA1;
|
||||
sdb_fis->type = SATA_FIS_TYPE_SDB;
|
||||
/* Interrupt pending & Notification bit */
|
||||
sdb_fis->flags = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
|
||||
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[0] = 0x5f;
|
||||
pio_fis[0] = SATA_FIS_TYPE_PIO_SETUP;
|
||||
pio_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
|
||||
pio_fis[2] = s->status;
|
||||
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[0] = 0x34;
|
||||
d2h_fis[0] = SATA_FIS_TYPE_REGISTER_D2H;
|
||||
d2h_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0);
|
||||
d2h_fis[2] = s->status;
|
||||
d2h_fis[3] = s->error;
|
||||
@ -1154,9 +1154,7 @@ out:
|
||||
static void ahci_start_dma(IDEDMA *dma, IDEState *s,
|
||||
BlockCompletionFunc *dma_cb)
|
||||
{
|
||||
#ifdef DEBUG_AHCI
|
||||
AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma);
|
||||
#endif
|
||||
DPRINTF(ad->port_no, "\n");
|
||||
s->io_buffer_offset = 0;
|
||||
dma_cb(s, 0);
|
||||
|
@ -157,6 +157,9 @@
|
||||
|
||||
#define SATA_FIS_TYPE_REGISTER_H2D 0x27
|
||||
#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_PRDT_LEN 16
|
||||
|
@ -163,6 +163,11 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
|
||||
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);
|
||||
if (kind != IDE_CD) {
|
||||
blkconf_geometry(&dev->conf, &dev->chs_trans, 65536, 16, 255, &err);
|
||||
|
@ -374,6 +374,7 @@ BlockDriverState *bdrv_lookup_bs(const char *device,
|
||||
const char *node_name,
|
||||
Error **errp);
|
||||
bool bdrv_chain_contains(BlockDriverState *top, BlockDriverState *base);
|
||||
BlockDriverState *bdrv_next_node(BlockDriverState *bs);
|
||||
BlockDriverState *bdrv_next(BlockDriverState *bs);
|
||||
int bdrv_is_encrypted(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);
|
||||
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
|
||||
void *opaque);
|
||||
const char *bdrv_get_node_name(const BlockDriverState *bs);
|
||||
const char *bdrv_get_device_name(const BlockDriverState *bs);
|
||||
int bdrv_get_flags(BlockDriverState *bs);
|
||||
int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
|
||||
|
@ -57,6 +57,8 @@
|
||||
#define BLOCK_OPT_REDUNDANCY "redundancy"
|
||||
#define BLOCK_OPT_NOCOW "nocow"
|
||||
|
||||
#define BLOCK_PROBE_BUF_SIZE 512
|
||||
|
||||
typedef struct BdrvTrackedRequest {
|
||||
BlockDriverState *bs;
|
||||
int64_t offset;
|
||||
@ -324,6 +326,7 @@ struct BlockDriverState {
|
||||
int sg; /* if true, the device is a /dev/sg* */
|
||||
int copy_on_read; /* if true, copy read backing sectors into image
|
||||
note this is a reference count */
|
||||
bool probed;
|
||||
|
||||
BlockDriver *drv; /* NULL means no media */
|
||||
void *opaque;
|
||||
@ -411,7 +414,17 @@ struct BlockDriverState {
|
||||
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);
|
||||
BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
|
||||
const char *filename);
|
||||
|
||||
void bdrv_set_io_limits(BlockDriverState *bs,
|
||||
ThrottleConfig *cfg);
|
||||
|
@ -85,14 +85,13 @@ int nbd_disconnect(int fd);
|
||||
typedef struct NBDExport NBDExport;
|
||||
typedef struct NBDClient NBDClient;
|
||||
|
||||
NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
|
||||
off_t size, uint32_t nbdflags,
|
||||
void (*close)(NBDExport *));
|
||||
NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
|
||||
uint32_t nbdflags, void (*close)(NBDExport *));
|
||||
void nbd_export_close(NBDExport *exp);
|
||||
void nbd_export_get(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);
|
||||
void nbd_export_set_name(NBDExport *exp, const char *name);
|
||||
|
@ -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);
|
||||
BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
|
||||
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_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_enable_write_cache(BlockBackend *blk);
|
||||
void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
|
||||
void blk_invalidate_cache(BlockBackend *blk, Error **errp);
|
||||
int blk_is_inserted(BlockBackend *blk);
|
||||
void blk_lock_medium(BlockBackend *blk, bool locked);
|
||||
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);
|
||||
AioContext *blk_get_aio_context(BlockBackend *blk);
|
||||
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_unplug(BlockBackend *blk);
|
||||
BlockAcctStats *blk_get_stats(BlockBackend *blk);
|
||||
|
@ -2628,10 +2628,10 @@ static mon_cmd_t info_cmds[] = {
|
||||
},
|
||||
{
|
||||
.name = "block",
|
||||
.args_type = "verbose:-v,device:B?",
|
||||
.params = "[-v] [device]",
|
||||
.args_type = "nodes:-n,verbose:-v,device:B?",
|
||||
.params = "[-n] [-v] [device]",
|
||||
.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,
|
||||
},
|
||||
{
|
||||
@ -4695,7 +4695,7 @@ static void monitor_find_completion_by_table(Monitor *mon,
|
||||
}
|
||||
}
|
||||
str = args[nb_args - 1];
|
||||
if (*ptype == '-' && ptype[1] != '\0') {
|
||||
while (*ptype == '-' && ptype[1] != '\0') {
|
||||
ptype = next_arg_type(ptype);
|
||||
}
|
||||
switch(*ptype) {
|
||||
|
63
nbd.c
63
nbd.c
@ -17,8 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "block/nbd.h"
|
||||
#include "block/block.h"
|
||||
#include "block/block_int.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
|
||||
#include "block/coroutine.h"
|
||||
|
||||
@ -101,7 +100,7 @@ struct NBDExport {
|
||||
int refcount;
|
||||
void (*close)(NBDExport *exp);
|
||||
|
||||
BlockDriverState *bs;
|
||||
BlockBackend *blk;
|
||||
char *name;
|
||||
off_t dev_offset;
|
||||
off_t size;
|
||||
@ -929,7 +928,7 @@ static void nbd_request_put(NBDRequest *req)
|
||||
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;
|
||||
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;
|
||||
NBDClient *client;
|
||||
@ -957,27 +956,26 @@ static void bs_aio_detach(void *opaque)
|
||||
exp->ctx = NULL;
|
||||
}
|
||||
|
||||
NBDExport *nbd_export_new(BlockDriverState *bs, off_t dev_offset,
|
||||
off_t size, uint32_t nbdflags,
|
||||
void (*close)(NBDExport *))
|
||||
NBDExport *nbd_export_new(BlockBackend *blk, off_t dev_offset, off_t size,
|
||||
uint32_t nbdflags, void (*close)(NBDExport *))
|
||||
{
|
||||
NBDExport *exp = g_malloc0(sizeof(NBDExport));
|
||||
exp->refcount = 1;
|
||||
QTAILQ_INIT(&exp->clients);
|
||||
exp->bs = bs;
|
||||
exp->blk = blk;
|
||||
exp->dev_offset = dev_offset;
|
||||
exp->nbdflags = nbdflags;
|
||||
exp->size = size == -1 ? bdrv_getlength(bs) : size;
|
||||
exp->size = size == -1 ? blk_getlength(blk) : size;
|
||||
exp->close = close;
|
||||
exp->ctx = bdrv_get_aio_context(bs);
|
||||
bdrv_ref(bs);
|
||||
bdrv_add_aio_context_notifier(bs, bs_aio_attached, bs_aio_detach, exp);
|
||||
exp->ctx = blk_get_aio_context(blk);
|
||||
blk_ref(blk);
|
||||
blk_add_aio_context_notifier(blk, blk_aio_attached, blk_aio_detach, exp);
|
||||
/*
|
||||
* NBD exports are used for non-shared storage migration. Make sure
|
||||
* that BDRV_O_INCOMING is cleared and the image is ready for write
|
||||
* access since the export could be available before migration handover.
|
||||
*/
|
||||
bdrv_invalidate_cache(bs, NULL);
|
||||
blk_invalidate_cache(blk, NULL);
|
||||
return exp;
|
||||
}
|
||||
|
||||
@ -1024,11 +1022,11 @@ void nbd_export_close(NBDExport *exp)
|
||||
}
|
||||
nbd_export_set_name(exp, NULL);
|
||||
nbd_export_put(exp);
|
||||
if (exp->bs) {
|
||||
bdrv_remove_aio_context_notifier(exp->bs, bs_aio_attached,
|
||||
bs_aio_detach, exp);
|
||||
bdrv_unref(exp->bs);
|
||||
exp->bs = NULL;
|
||||
if (exp->blk) {
|
||||
blk_remove_aio_context_notifier(exp->blk, blk_aio_attached,
|
||||
blk_aio_detach, exp);
|
||||
blk_unref(exp->blk);
|
||||
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)
|
||||
@ -1137,7 +1135,7 @@ static ssize_t nbd_co_receive_request(NBDRequest *req, struct nbd_request *reque
|
||||
|
||||
command = request->type & NBD_CMD_MASK_COMMAND;
|
||||
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) {
|
||||
TRACE("Reading %u byte(s)", request->len);
|
||||
@ -1203,7 +1201,7 @@ static void nbd_trip(void *opaque)
|
||||
TRACE("Request type is READ");
|
||||
|
||||
if (request.type & NBD_CMD_FLAG_FUA) {
|
||||
ret = bdrv_co_flush(exp->bs);
|
||||
ret = blk_co_flush(exp->blk);
|
||||
if (ret < 0) {
|
||||
LOG("flush failed");
|
||||
reply.error = -ret;
|
||||
@ -1211,8 +1209,9 @@ static void nbd_trip(void *opaque)
|
||||
}
|
||||
}
|
||||
|
||||
ret = bdrv_read(exp->bs, (request.from + exp->dev_offset) / 512,
|
||||
req->data, request.len / 512);
|
||||
ret = blk_read(exp->blk,
|
||||
(request.from + exp->dev_offset) / BDRV_SECTOR_SIZE,
|
||||
req->data, request.len / BDRV_SECTOR_SIZE);
|
||||
if (ret < 0) {
|
||||
LOG("reading from file failed");
|
||||
reply.error = -ret;
|
||||
@ -1234,8 +1233,9 @@ static void nbd_trip(void *opaque)
|
||||
|
||||
TRACE("Writing to device");
|
||||
|
||||
ret = bdrv_write(exp->bs, (request.from + exp->dev_offset) / 512,
|
||||
req->data, request.len / 512);
|
||||
ret = blk_write(exp->blk,
|
||||
(request.from + exp->dev_offset) / BDRV_SECTOR_SIZE,
|
||||
req->data, request.len / BDRV_SECTOR_SIZE);
|
||||
if (ret < 0) {
|
||||
LOG("writing to file failed");
|
||||
reply.error = -ret;
|
||||
@ -1243,7 +1243,7 @@ static void nbd_trip(void *opaque)
|
||||
}
|
||||
|
||||
if (request.type & NBD_CMD_FLAG_FUA) {
|
||||
ret = bdrv_co_flush(exp->bs);
|
||||
ret = blk_co_flush(exp->blk);
|
||||
if (ret < 0) {
|
||||
LOG("flush failed");
|
||||
reply.error = -ret;
|
||||
@ -1262,7 +1262,7 @@ static void nbd_trip(void *opaque)
|
||||
case NBD_CMD_FLUSH:
|
||||
TRACE("Request type is FLUSH");
|
||||
|
||||
ret = bdrv_co_flush(exp->bs);
|
||||
ret = blk_co_flush(exp->blk);
|
||||
if (ret < 0) {
|
||||
LOG("flush failed");
|
||||
reply.error = -ret;
|
||||
@ -1273,8 +1273,9 @@ static void nbd_trip(void *opaque)
|
||||
break;
|
||||
case NBD_CMD_TRIM:
|
||||
TRACE("Request type is TRIM");
|
||||
ret = bdrv_co_discard(exp->bs, (request.from + exp->dev_offset) / 512,
|
||||
request.len / 512);
|
||||
ret = blk_co_discard(exp->blk, (request.from + exp->dev_offset)
|
||||
/ BDRV_SECTOR_SIZE,
|
||||
request.len / BDRV_SECTOR_SIZE);
|
||||
if (ret < 0) {
|
||||
LOG("discard failed");
|
||||
reply.error = -ret;
|
||||
|
@ -182,6 +182,22 @@
|
||||
'*total-clusters': 'int', '*allocated-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:
|
||||
#
|
||||
@ -239,6 +255,8 @@
|
||||
#
|
||||
# @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
|
||||
#
|
||||
##
|
||||
@ -253,7 +271,7 @@
|
||||
'*bps_max': 'int', '*bps_rd_max': 'int',
|
||||
'*bps_wr_max': 'int', '*iops_max': 'int',
|
||||
'*iops_rd_max': 'int', '*iops_wr_max': 'int',
|
||||
'*iops_size': 'int' } }
|
||||
'*iops_size': 'int', 'cache': 'BlockdevCacheInfo' } }
|
||||
|
||||
##
|
||||
# @BlockDeviceIoStatus:
|
||||
@ -405,6 +423,8 @@
|
||||
# @device: #optional If the stats are for a virtual block device, the name
|
||||
# corresponding to the virtual block device.
|
||||
#
|
||||
# @device: #optional The node name of the device. (Since 2.3)
|
||||
#
|
||||
# @stats: A @BlockDeviceStats for the device.
|
||||
#
|
||||
# @parent: #optional This describes the file block device if it has one.
|
||||
@ -415,7 +435,8 @@
|
||||
# Since: 0.14.0
|
||||
##
|
||||
{ 'type': 'BlockStats',
|
||||
'data': {'*device': 'str', 'stats': 'BlockDeviceStats',
|
||||
'data': {'*device': 'str', '*node-name': 'str',
|
||||
'stats': 'BlockDeviceStats',
|
||||
'*parent': 'BlockStats',
|
||||
'*backing': 'BlockStats'} }
|
||||
|
||||
@ -424,11 +445,20 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# Since: 0.14.0
|
||||
##
|
||||
{ 'command': 'query-blockstats', 'returns': ['BlockStats'] }
|
||||
{ 'command': 'query-blockstats',
|
||||
'data': { '*query-nodes': 'bool' },
|
||||
'returns': ['BlockStats'] }
|
||||
|
||||
##
|
||||
# @BlockdevOnError:
|
||||
|
21
qemu-img.c
21
qemu-img.c
@ -1531,6 +1531,20 @@ static int img_convert(int argc, char **argv)
|
||||
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, proto_drv->create_opts);
|
||||
|
||||
@ -2972,6 +2986,13 @@ static int img_amend(int argc, char **argv)
|
||||
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);
|
||||
opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
|
||||
if (options && qemu_opts_do_parse(opts, options, NULL)) {
|
||||
|
28
qemu-io.c
28
qemu-io.c
@ -51,7 +51,8 @@ static const cmdinfo_t close_cmd = {
|
||||
.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;
|
||||
|
||||
@ -68,7 +69,7 @@ static int openfile(char *name, int flags, int growable, QDict *opts)
|
||||
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,
|
||||
name ? " device " : "", name ?: "",
|
||||
error_get_pretty(local_err));
|
||||
@ -169,9 +170,9 @@ static int open_f(BlockDriverState *bs, int argc, char **argv)
|
||||
qemu_opts_reset(&empty_opts);
|
||||
|
||||
if (optind == argc - 1) {
|
||||
return openfile(argv[optind], flags, growable, opts);
|
||||
return openfile(argv[optind], NULL, flags, growable, opts);
|
||||
} else if (optind == argc) {
|
||||
return openfile(NULL, flags, growable, opts);
|
||||
return openfile(NULL, NULL, flags, growable, opts);
|
||||
} else {
|
||||
QDECREF(opts);
|
||||
return qemuio_command_usage(&open_cmd);
|
||||
@ -196,11 +197,12 @@ static const cmdinfo_t quit_cmd = {
|
||||
static void usage(const char *name)
|
||||
{
|
||||
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"
|
||||
"\n"
|
||||
" -c, --cmd STRING execute command with its arguments\n"
|
||||
" from the given string\n"
|
||||
" -f, --format FMT specifies the block driver to use\n"
|
||||
" -r, --read-only export read-only\n"
|
||||
" -s, --snapshot use snapshot file\n"
|
||||
" -n, --nocache disable host cache\n"
|
||||
@ -364,12 +366,13 @@ int main(int argc, char **argv)
|
||||
{
|
||||
int readonly = 0;
|
||||
int growable = 0;
|
||||
const char *sopt = "hVc:d:rsnmgkt:T:";
|
||||
const char *sopt = "hVc:d:f:rsnmgkt:T:";
|
||||
const struct option lopt[] = {
|
||||
{ "help", 0, NULL, 'h' },
|
||||
{ "version", 0, NULL, 'V' },
|
||||
{ "offset", 1, NULL, 'o' },
|
||||
{ "cmd", 1, NULL, 'c' },
|
||||
{ "format", 1, NULL, 'f' },
|
||||
{ "read-only", 0, NULL, 'r' },
|
||||
{ "snapshot", 0, NULL, 's' },
|
||||
{ "nocache", 0, NULL, 'n' },
|
||||
@ -384,6 +387,7 @@ int main(int argc, char **argv)
|
||||
int c;
|
||||
int opt_index = 0;
|
||||
int flags = BDRV_O_UNMAP;
|
||||
BlockDriver *drv = NULL;
|
||||
Error *local_error = NULL;
|
||||
|
||||
#ifdef CONFIG_POSIX
|
||||
@ -393,6 +397,8 @@ int main(int argc, char **argv)
|
||||
progname = basename(argv[0]);
|
||||
qemu_init_exec_dir(argv[0]);
|
||||
|
||||
bdrv_init();
|
||||
|
||||
while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
|
||||
switch (c) {
|
||||
case 's':
|
||||
@ -407,6 +413,13 @@ int main(int argc, char **argv)
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
drv = bdrv_find_format(optarg);
|
||||
if (!drv) {
|
||||
error_report("Invalid format '%s'", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'c':
|
||||
add_user_command(optarg);
|
||||
break;
|
||||
@ -455,7 +468,6 @@ int main(int argc, char **argv)
|
||||
error_free(local_error);
|
||||
exit(1);
|
||||
}
|
||||
bdrv_init();
|
||||
|
||||
/* initialize commands */
|
||||
qemuio_add_command(&quit_cmd);
|
||||
@ -477,7 +489,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if ((argc - optind) == 1) {
|
||||
openfile(argv[optind], flags, growable, NULL);
|
||||
openfile(argv[optind], drv, flags, growable, NULL);
|
||||
}
|
||||
command_loop();
|
||||
|
||||
|
12
qemu-nbd.c
12
qemu-nbd.c
@ -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;
|
||||
}
|
||||
|
||||
static int find_partition(BlockDriverState *bs, int partition,
|
||||
static int find_partition(BlockBackend *blk, int partition,
|
||||
off_t *offset, off_t *size)
|
||||
{
|
||||
struct partition_record mbr[4];
|
||||
@ -155,7 +155,7 @@ static int find_partition(BlockDriverState *bs, int partition,
|
||||
int ext_partnum = 4;
|
||||
int ret;
|
||||
|
||||
if ((ret = bdrv_read(bs, 0, data, 1)) < 0) {
|
||||
if ((ret = blk_read(blk, 0, data, 1)) < 0) {
|
||||
errno = -ret;
|
||||
err(EXIT_FAILURE, "error while reading");
|
||||
}
|
||||
@ -175,7 +175,7 @@ static int find_partition(BlockDriverState *bs, int partition,
|
||||
uint8_t data1[512];
|
||||
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;
|
||||
err(EXIT_FAILURE, "error while reading");
|
||||
}
|
||||
@ -720,17 +720,17 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
bs->detect_zeroes = detect_zeroes;
|
||||
fd_size = bdrv_getlength(bs);
|
||||
fd_size = blk_getlength(blk);
|
||||
|
||||
if (partition != -1) {
|
||||
ret = find_partition(bs, partition, &dev_offset, &fd_size);
|
||||
ret = find_partition(blk, partition, &dev_offset, &fd_size);
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
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) {
|
||||
fd = unix_socket_incoming(sockpath);
|
||||
|
@ -2790,6 +2790,14 @@ STEXI
|
||||
@findex -qmp
|
||||
Like -monitor but opens in 'control' mode.
|
||||
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, \
|
||||
"-mon [chardev=]name[,mode=readline|control][,default]\n", QEMU_ARCH_ALL)
|
||||
|
@ -2347,7 +2347,7 @@ EQMP
|
||||
|
||||
{
|
||||
.name = "query-blockstats",
|
||||
.args_type = "",
|
||||
.args_type = "query-nodes:b?",
|
||||
.mhandler.cmd_new = qmp_marshal_input_query_blockstats,
|
||||
},
|
||||
|
||||
|
@ -86,8 +86,9 @@ static void to_json_dict_iter(const char *key, QObject *obj, void *opaque)
|
||||
QString *qkey;
|
||||
int j;
|
||||
|
||||
if (s->count)
|
||||
qstring_append(s->str, ", ");
|
||||
if (s->count) {
|
||||
qstring_append(s->str, s->pretty ? "," : ", ");
|
||||
}
|
||||
|
||||
if (s->pretty) {
|
||||
qstring_append(s->str, "\n");
|
||||
@ -109,8 +110,9 @@ static void to_json_list_iter(QObject *obj, void *opaque)
|
||||
ToJsonIterState *s = opaque;
|
||||
int j;
|
||||
|
||||
if (s->count)
|
||||
qstring_append(s->str, ", ");
|
||||
if (s->count) {
|
||||
qstring_append(s->str, s->pretty ? "," : ", ");
|
||||
}
|
||||
|
||||
if (s->pretty) {
|
||||
qstring_append(s->str, "\n");
|
||||
|
@ -487,7 +487,8 @@ static void qtest_shutdown(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 "
|
||||
"-device ide-hd,drive=drive0 "
|
||||
"-global ide-hd.ver=%s",
|
||||
|
@ -716,7 +716,7 @@ static void test_acpi_one(const char *params, test_data *data)
|
||||
int i;
|
||||
|
||||
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 ",
|
||||
params ? params : "", disk);
|
||||
|
||||
|
@ -103,7 +103,7 @@ static void test_after_failed_device_add(void)
|
||||
static void test_drive_del_device_del(void)
|
||||
{
|
||||
/* 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 scsi-hd,drive=drive0,id=dev0");
|
||||
|
||||
|
@ -291,7 +291,7 @@ static void test_media_insert(void)
|
||||
/* Insert media in drive. DSKCHK should not be reset until a step pulse
|
||||
* is sent. */
|
||||
qmp_discard_response("{'execute':'change', 'arguments':{"
|
||||
" 'device':'floppy0', 'target': %s }}",
|
||||
" 'device':'floppy0', 'target': %s, 'arg': 'raw' }}",
|
||||
test_image);
|
||||
qmp_discard_response(""); /* ignore event
|
||||
(FIXME open -> open transition?!) */
|
||||
|
@ -208,7 +208,7 @@ static int setup_ide(int argc, char *argv[], int argv_sz,
|
||||
{
|
||||
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");
|
||||
s2 = dev ? g_strdup("") : g_strdup_printf(",index=%d", ide_idx);
|
||||
|
||||
|
@ -342,8 +342,9 @@ static void test_i440fx_firmware(FirmwareTestFixture *fixture,
|
||||
g_assert(fw_pathname != NULL);
|
||||
|
||||
/* Better hope the user didn't put metacharacters in TMPDIR and co. */
|
||||
cmdline = g_strdup_printf("-S %s %s",
|
||||
fixture->is_bios ? "-bios" : "-pflash",
|
||||
cmdline = g_strdup_printf("-S %s%s", fixture->is_bios
|
||||
? "-bios "
|
||||
: "-drive if=pflash,format=raw,file=",
|
||||
fw_pathname);
|
||||
g_test_message("qemu cmdline: %s", cmdline);
|
||||
qtest_start(cmdline);
|
||||
|
@ -385,7 +385,7 @@ static void test_bmdma_no_busmaster(void)
|
||||
static void test_bmdma_setup(void)
|
||||
{
|
||||
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",
|
||||
tmp_path, "testdisk", "version");
|
||||
}
|
||||
@ -414,7 +414,7 @@ static void test_identify(void)
|
||||
int ret;
|
||||
|
||||
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",
|
||||
tmp_path, "testdisk", "version");
|
||||
|
||||
@ -458,7 +458,7 @@ static void test_flush(void)
|
||||
uint8_t data;
|
||||
|
||||
ide_test_start(
|
||||
"-drive file=blkdebug::%s,if=ide,cache=writeback",
|
||||
"-drive file=blkdebug::%s,if=ide,cache=writeback,format=raw",
|
||||
tmp_path);
|
||||
|
||||
/* 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(
|
||||
"-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);
|
||||
|
||||
/* FLUSH CACHE command on device 0*/
|
||||
|
@ -24,7 +24,7 @@ int main(int argc, char **argv)
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
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");
|
||||
ret = g_test_run();
|
||||
|
||||
|
@ -43,25 +43,28 @@ _supported_proto file sheepdog nfs
|
||||
_supported_os Linux
|
||||
|
||||
|
||||
# No -f, use probing for the protocol driver
|
||||
QEMU_IO_PROTO="$QEMU_IO_PROG -g --cache $CACHEMODE"
|
||||
|
||||
size=128M
|
||||
_make_test_img $size
|
||||
|
||||
echo
|
||||
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 "== 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 "== 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
|
||||
|
||||
echo
|
||||
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
|
||||
|
||||
# success, all done
|
||||
|
@ -14,6 +14,8 @@ No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
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
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
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
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
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
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
wrote 131072/131072 bytes at offset 0
|
||||
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
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
|
||||
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
|
||||
No errors were found on the image.
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
96 leaked clusters were found on the image.
|
||||
|
@ -34,7 +34,7 @@ class TestSingleDrive(iotests.QMPTestCase):
|
||||
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' % 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.launch()
|
||||
|
||||
@ -55,8 +55,8 @@ class TestSingleDrive(iotests.QMPTestCase):
|
||||
self.assert_no_active_block_jobs()
|
||||
self.vm.shutdown()
|
||||
|
||||
self.assertEqual(qemu_io('-c', 'map', backing_img),
|
||||
qemu_io('-c', 'map', test_img),
|
||||
self.assertEqual(qemu_io('-f', 'raw', '-c', 'map', backing_img),
|
||||
qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
|
||||
'image file map does not match backing file after streaming')
|
||||
|
||||
def test_stream_pause(self):
|
||||
@ -86,8 +86,8 @@ class TestSingleDrive(iotests.QMPTestCase):
|
||||
self.assert_no_active_block_jobs()
|
||||
self.vm.shutdown()
|
||||
|
||||
self.assertEqual(qemu_io('-c', 'map', backing_img),
|
||||
qemu_io('-c', 'map', test_img),
|
||||
self.assertEqual(qemu_io('-f', 'raw', '-c', 'map', backing_img),
|
||||
qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
|
||||
'image file map does not match backing file after streaming')
|
||||
|
||||
def test_stream_partial(self):
|
||||
@ -101,8 +101,8 @@ class TestSingleDrive(iotests.QMPTestCase):
|
||||
self.assert_no_active_block_jobs()
|
||||
self.vm.shutdown()
|
||||
|
||||
self.assertEqual(qemu_io('-c', 'map', mid_img),
|
||||
qemu_io('-c', 'map', test_img),
|
||||
self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', mid_img),
|
||||
qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
|
||||
'image file map does not match backing file after streaming')
|
||||
|
||||
def test_device_not_found(self):
|
||||
@ -359,9 +359,9 @@ class TestStreamStop(iotests.QMPTestCase):
|
||||
|
||||
def setUp(self):
|
||||
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_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.launch()
|
||||
|
||||
@ -388,9 +388,9 @@ class TestSetSpeed(iotests.QMPTestCase):
|
||||
|
||||
def setUp(self):
|
||||
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_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.launch()
|
||||
|
||||
|
@ -76,8 +76,8 @@ class TestSingleDrive(ImageCommitTestCase):
|
||||
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' % mid_img, test_img)
|
||||
qemu_io('-c', 'write -P 0xab 0 524288', backing_img)
|
||||
qemu_io('-c', 'write -P 0xef 524288 524288', mid_img)
|
||||
qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', backing_img)
|
||||
qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img)
|
||||
self.vm = iotests.VM().add_drive(test_img)
|
||||
self.vm.launch()
|
||||
|
||||
@ -89,8 +89,8 @@ class TestSingleDrive(ImageCommitTestCase):
|
||||
|
||||
def test_commit(self):
|
||||
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('-c', 'read -P 0xef 524288 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('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
|
||||
|
||||
def test_device_not_found(self):
|
||||
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):
|
||||
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('-c', 'read -P 0xef 524288 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('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
|
||||
|
||||
def test_top_is_default_active(self):
|
||||
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('-c', 'read -P 0xef 524288 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('-f', 'raw', '-c', 'read -P 0xef 524288 524288', backing_img).find("verification failed"))
|
||||
|
||||
def test_top_and_base_reversed(self):
|
||||
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('rebase', '-u', '-b', self.backing_img, self.mid_img_abs)
|
||||
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('-c', 'write -P 0xef 524288 524288', self.mid_img_abs)
|
||||
qemu_io('-f', 'raw', '-c', 'write -P 0xab 0 524288', self.backing_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.launch()
|
||||
|
||||
@ -179,8 +179,8 @@ class TestRelativePaths(ImageCommitTestCase):
|
||||
|
||||
def test_commit(self):
|
||||
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('-c', 'read -P 0xef 524288 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('-f', 'raw', '-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed"))
|
||||
|
||||
def test_device_not_found(self):
|
||||
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):
|
||||
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('-c', 'read -P 0xef 524288 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('-f', 'raw', '-c', 'read -P 0xef 524288 524288', self.backing_img_abs).find("verification failed"))
|
||||
|
||||
def test_top_and_base_reversed(self):
|
||||
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', '-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_io('-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 0x1 0 512', test_img)
|
||||
qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0xef 524288 524288', mid_img)
|
||||
self.vm = iotests.VM().add_drive(test_img)
|
||||
self.vm.launch()
|
||||
|
||||
|
@ -64,7 +64,7 @@ _compare
|
||||
_compare -q
|
||||
|
||||
# Compare images with different size
|
||||
$QEMU_IMG resize "$TEST_IMG" +512M
|
||||
$QEMU_IMG resize -f $IMGFMT "$TEST_IMG" +512M
|
||||
_compare
|
||||
_compare -s
|
||||
|
||||
|
@ -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) i[K[Din[K[D[Dinf[K[D[D[Dinfo[K[D[D[D[Dinfo [K[D[D[D[D[Dinfo b[K[D[D[D[D[D[Dinfo bl[K[D[D[D[D[D[D[Dinfo blo[K[D[D[D[D[D[D[D[Dinfo bloc[K[D[D[D[D[D[D[D[D[Dinfo block[K
|
||||
ide0-hd0: TEST_DIR/t.qcow2 (qcow2)
|
||||
Cache mode: writeback
|
||||
Backing file: TEST_DIR/t.qcow2.orig (chain depth: 1)
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
|
@ -34,10 +34,10 @@ class TestSingleDrive(iotests.QMPTestCase):
|
||||
def setUp(self):
|
||||
# Write data to the image so we can compare later
|
||||
qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleDrive.image_len))
|
||||
qemu_io('-c', 'write -P0x5d 0 64k', test_img)
|
||||
qemu_io('-c', 'write -P0xd5 1M 32k', test_img)
|
||||
qemu_io('-c', 'write -P0xdc 32M 124k', test_img)
|
||||
qemu_io('-c', 'write -P0xdc 67043328 64k', test_img)
|
||||
qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x5d 0 64k', test_img)
|
||||
qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xd5 1M 32k', test_img)
|
||||
qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 32M 124k', test_img)
|
||||
qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 67043328 64k', test_img)
|
||||
|
||||
self.vm = iotests.VM().add_drive(test_img)
|
||||
self.vm.launch()
|
||||
@ -115,7 +115,7 @@ class TestSetSpeed(iotests.QMPTestCase):
|
||||
|
||||
def setUp(self):
|
||||
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.launch()
|
||||
|
||||
@ -186,10 +186,10 @@ class TestSingleTransaction(iotests.QMPTestCase):
|
||||
|
||||
def setUp(self):
|
||||
qemu_img('create', '-f', iotests.imgfmt, test_img, str(TestSingleTransaction.image_len))
|
||||
qemu_io('-c', 'write -P0x5d 0 64k', test_img)
|
||||
qemu_io('-c', 'write -P0xd5 1M 32k', test_img)
|
||||
qemu_io('-c', 'write -P0xdc 32M 124k', test_img)
|
||||
qemu_io('-c', 'write -P0xdc 67043328 64k', test_img)
|
||||
qemu_io('-f', iotests.imgfmt, '-c', 'write -P0x5d 0 64k', test_img)
|
||||
qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xd5 1M 32k', test_img)
|
||||
qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 32M 124k', test_img)
|
||||
qemu_io('-f', iotests.imgfmt, '-c', 'write -P0xdc 67043328 64k', test_img)
|
||||
|
||||
self.vm = iotests.VM().add_drive(test_img)
|
||||
self.vm.launch()
|
||||
|
@ -89,6 +89,9 @@ _supported_fmt qcow2
|
||||
_supported_proto file
|
||||
_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 "== preparing image =="
|
||||
_make_test_img 64M
|
||||
@ -108,15 +111,15 @@ _export_nbd_snapshot sn1
|
||||
|
||||
echo
|
||||
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 -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
|
||||
$QEMU_IO_NBD -c 'read -P 0xa 0x1000 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
|
||||
|
||||
echo
|
||||
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 -c 'read -P 0xb 0x2000 0x1000' "$nbd_snapshot_img" | _filter_qemu_io
|
||||
$QEMU_IO_NBD -c 'read -P 0xa 0x1000 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"
|
||||
|
||||
|
@ -106,8 +106,8 @@ _img_info
|
||||
echo
|
||||
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
|
||||
$QEMU_IO -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 0xa 0 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
|
||||
|
||||
echo
|
||||
|
@ -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
|
||||
|
||||
# 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)
|
||||
$QEMU_IO -c "$OPEN_RW" -c "read 0 512" 2>&1 | _filter_qemu_io \
|
||||
|
@ -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
|
||||
write failed: Input/output error
|
||||
incompatible_features 0x2
|
||||
image: TEST_DIR/t.qcow2
|
||||
file format: qcow2
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
file format: IMGFMT
|
||||
virtual size: 64M (67108864 bytes)
|
||||
disk size: 196K
|
||||
cluster_size: 65536
|
||||
Format specific information:
|
||||
compat: 1.1
|
||||
|
@ -39,7 +39,7 @@ _supported_os Linux
|
||||
function do_run_qemu()
|
||||
{
|
||||
echo Testing: "$@"
|
||||
$QEMU -nographic -qmp stdio -serial none "$@"
|
||||
$QEMU -nographic -qmp-pretty stdio -serial none "$@"
|
||||
echo
|
||||
}
|
||||
|
||||
|
@ -4,77 +4,767 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
|
||||
=== -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
|
||||
QMP_VERSION
|
||||
{"return": {}}
|
||||
{"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": {}}
|
||||
{"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}}
|
||||
{
|
||||
QMP_VERSION
|
||||
}
|
||||
{
|
||||
"return": {
|
||||
}
|
||||
}
|
||||
{
|
||||
"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,
|
||||
"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 ===
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk
|
||||
QMP_VERSION
|
||||
{"return": {}}
|
||||
{"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": {}}
|
||||
{"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}}
|
||||
{
|
||||
QMP_VERSION
|
||||
}
|
||||
{
|
||||
"return": {
|
||||
}
|
||||
}
|
||||
{
|
||||
"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,
|
||||
"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 ===
|
||||
|
||||
Testing:
|
||||
QMP_VERSION
|
||||
{"return": {}}
|
||||
{"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": {}}
|
||||
{"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}}
|
||||
{
|
||||
QMP_VERSION
|
||||
}
|
||||
{
|
||||
"return": {
|
||||
}
|
||||
}
|
||||
{
|
||||
"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,
|
||||
"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 ===
|
||||
|
||||
Testing:
|
||||
QMP_VERSION
|
||||
{"return": {}}
|
||||
{"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": {}}
|
||||
{"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, "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}}
|
||||
{
|
||||
QMP_VERSION
|
||||
}
|
||||
{
|
||||
"return": {
|
||||
}
|
||||
}
|
||||
{
|
||||
"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,
|
||||
"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
|
||||
|
@ -63,12 +63,12 @@ echo
|
||||
TEST_IMG="$TEST_IMG.base" IMGOPTS="" IMGFMT="raw" _make_test_img $IMG_SIZE |\
|
||||
_filter_imgfmt
|
||||
_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
|
||||
|
||||
$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
|
||||
|
||||
echo
|
||||
@ -78,12 +78,12 @@ echo
|
||||
TEST_IMG="$TEST_IMG.base" IMGOPTS="" IMGFMT="raw" _make_test_img $IMG_SIZE |\
|
||||
_filter_imgfmt
|
||||
_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
|
||||
|
||||
$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
|
||||
|
||||
echo
|
||||
@ -163,7 +163,7 @@ echo
|
||||
echo "=== Testing blkverify on existing raw block device ==="
|
||||
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": "blockdev-add",
|
||||
"arguments": {
|
||||
|
@ -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)
|
||||
wrote 512/512 bytes at offset 0
|
||||
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 ===
|
||||
|
||||
@ -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)
|
||||
wrote 512/512 bytes at offset 0
|
||||
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 ===
|
||||
|
||||
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
|
||||
|
||||
=== 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
|
||||
|
||||
=== 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": "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}}
|
||||
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 ===
|
||||
@ -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: -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
|
||||
{"return": {}}
|
||||
{"return": {}}
|
||||
@ -86,5 +92,7 @@ read failed: Input/output error
|
||||
{"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}}
|
||||
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
|
||||
|
@ -52,7 +52,7 @@ echo "== Some concurrent requests involving RMW =="
|
||||
|
||||
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
|
||||
cat <<EOF
|
||||
aio_write -P 10 0x200 0x200
|
||||
|
@ -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_size" "\x7f\xff\xff\xff"
|
||||
{ $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"
|
||||
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
|
||||
|
@ -13,6 +13,8 @@ qemu-io: can't open device TEST_DIR/t.qcow2: Invalid backing file offset
|
||||
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'
|
||||
qemu-io: can't open device TEST_DIR/t.qcow2: Header extension too large
|
||||
no file open, try 'help open'
|
||||
|
||||
== Huge refcount table size ==
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
|
@ -59,9 +59,13 @@ function run_qemu()
|
||||
test_quorum=$($QEMU_IMG --help|grep 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.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 "== creating quorum files =="
|
||||
|
@ -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)
|
||||
|
||||
== 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
|
||||
|
@ -60,11 +60,11 @@ _img_info
|
||||
|
||||
# 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 info "$TEST_IMG"
|
||||
_img_info --format-specific
|
||||
|
||||
# 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 info "$TEST_IMG"
|
||||
_img_info --format-specific
|
||||
run_qemu_img create -f $IMGFMT -o cluster_size=4k,cluster_size=8k "$TEST_IMG" $size
|
||||
_img_info
|
||||
|
||||
@ -114,11 +114,11 @@ TEST_IMG="${TEST_IMG}.base" _img_info
|
||||
|
||||
# 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 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
|
||||
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
|
||||
TEST_IMG="${TEST_IMG}.base" _img_info
|
||||
|
||||
@ -157,15 +157,15 @@ echo === amend: Options specified more than once ===
|
||||
|
||||
# Last -f should win
|
||||
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
|
||||
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
|
||||
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"
|
||||
_img_info
|
||||
|
||||
|
@ -11,12 +11,9 @@ cluster_size: 65536
|
||||
|
||||
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
|
||||
|
||||
Testing: info TEST_DIR/t.qcow2
|
||||
image: TEST_DIR/t.qcow2
|
||||
file format: qcow2
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
file format: IMGFMT
|
||||
virtual size: 128M (134217728 bytes)
|
||||
disk size: 16K
|
||||
cluster_size: 4096
|
||||
Format specific information:
|
||||
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
|
||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 encryption=off cluster_size=8192 lazy_refcounts=on
|
||||
|
||||
Testing: info TEST_DIR/t.qcow2
|
||||
image: TEST_DIR/t.qcow2
|
||||
file format: qcow2
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
file format: IMGFMT
|
||||
virtual size: 128M (134217728 bytes)
|
||||
disk size: 28K
|
||||
cluster_size: 8192
|
||||
Format specific information:
|
||||
compat: 1.1
|
||||
@ -189,12 +183,9 @@ virtual size: 128M (134217728 bytes)
|
||||
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: info TEST_DIR/t.qcow2.base
|
||||
image: TEST_DIR/t.qcow2.base
|
||||
file format: qcow2
|
||||
image: TEST_DIR/t.IMGFMT.base
|
||||
file format: IMGFMT
|
||||
virtual size: 128M (134217728 bytes)
|
||||
disk size: 16K
|
||||
cluster_size: 4096
|
||||
Format specific information:
|
||||
compat: 1.1
|
||||
@ -202,12 +193,9 @@ Format specific information:
|
||||
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: info TEST_DIR/t.qcow2.base
|
||||
image: TEST_DIR/t.qcow2.base
|
||||
file format: qcow2
|
||||
image: TEST_DIR/t.IMGFMT.base
|
||||
file format: IMGFMT
|
||||
virtual size: 128M (134217728 bytes)
|
||||
disk size: 28K
|
||||
cluster_size: 8192
|
||||
Format specific information:
|
||||
compat: 1.1
|
||||
@ -351,12 +339,9 @@ size Virtual disk size
|
||||
=== amend: Options specified more than once ===
|
||||
|
||||
Testing: amend -f foo -f qcow2 -o lazy_refcounts=on TEST_DIR/t.qcow2
|
||||
|
||||
Testing: info TEST_DIR/t.qcow2
|
||||
image: TEST_DIR/t.qcow2
|
||||
file format: qcow2
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
file format: IMGFMT
|
||||
virtual size: 128M (134217728 bytes)
|
||||
disk size: 196K
|
||||
cluster_size: 65536
|
||||
Format specific information:
|
||||
compat: 1.1
|
||||
@ -364,12 +349,9 @@ Format specific information:
|
||||
corrupt: false
|
||||
|
||||
Testing: amend -f qcow2 -o size=130M -o lazy_refcounts=off TEST_DIR/t.qcow2
|
||||
|
||||
Testing: info TEST_DIR/t.qcow2
|
||||
image: TEST_DIR/t.qcow2
|
||||
file format: qcow2
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
file format: IMGFMT
|
||||
virtual size: 130M (136314880 bytes)
|
||||
disk size: 196K
|
||||
cluster_size: 65536
|
||||
Format specific information:
|
||||
compat: 1.1
|
||||
@ -377,12 +359,9 @@ Format specific information:
|
||||
corrupt: false
|
||||
|
||||
Testing: amend -f qcow2 -o size=8M -o lazy_refcounts=on -o size=132M TEST_DIR/t.qcow2
|
||||
|
||||
Testing: info TEST_DIR/t.qcow2
|
||||
image: TEST_DIR/t.qcow2
|
||||
file format: qcow2
|
||||
image: TEST_DIR/t.IMGFMT
|
||||
file format: IMGFMT
|
||||
virtual size: 132M (138412032 bytes)
|
||||
disk size: 196K
|
||||
cluster_size: 65536
|
||||
Format specific information:
|
||||
compat: 1.1
|
||||
|
@ -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_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:{
|
||||
\"driver\": \"$IMGFMT\",
|
||||
\"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 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\",
|
||||
\"file\": {
|
||||
\"driver\": \"blkdebug\",
|
||||
|
@ -24,6 +24,8 @@ read 512/512 bytes at offset 0
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
wrote 512/512 bytes at offset 229376
|
||||
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
|
||||
|
||||
=== Testing qemu-img info output ===
|
||||
|
@ -44,7 +44,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||
_supported_fmt qcow qcow2 qed vdi vhdx vmdk vpc
|
||||
_supported_proto file
|
||||
_supported_os Linux
|
||||
|
||||
_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat" \
|
||||
"subformat=twoGbMaxExtentSparse"
|
||||
|
||||
function do_run_qemu()
|
||||
{
|
||||
@ -107,8 +108,21 @@ echo
|
||||
# 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"
|
||||
|
||||
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
|
||||
echo "*** done"
|
||||
|
@ -12,9 +12,17 @@ blkverify:TEST_DIR/t.IMGFMT.compare:TEST_DIR/t.IMGFMT
|
||||
|
||||
=== 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 ===
|
||||
|
||||
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
|
||||
|
132
tests/qemu-iotests/109
Executable file
132
tests/qemu-iotests/109
Executable 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
231
tests/qemu-iotests/109.out
Normal 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
76
tests/qemu-iotests/113
Executable 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
|
15
tests/qemu-iotests/113.out
Normal file
15
tests/qemu-iotests/113.out
Normal 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
61
tests/qemu-iotests/114
Executable 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
|
13
tests/qemu-iotests/114.out
Normal file
13
tests/qemu-iotests/114.out
Normal 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
|
@ -289,10 +289,10 @@ testlist options
|
||||
|
||||
if [ ! -z "$DISPLAY" ]
|
||||
then
|
||||
which xdiff >/dev/null 2>&1 && diff=xdiff
|
||||
which gdiff >/dev/null 2>&1 && diff=gdiff
|
||||
which tkdiff >/dev/null 2>&1 && diff=tkdiff
|
||||
which xxdiff >/dev/null 2>&1 && diff=xxdiff
|
||||
command -v xdiff >/dev/null 2>&1 && diff=xdiff
|
||||
command -v gdiff >/dev/null 2>&1 && diff=gdiff
|
||||
command -v tkdiff >/dev/null 2>&1 && diff=tkdiff
|
||||
command -v xxdiff >/dev/null 2>&1 && diff=xxdiff
|
||||
fi
|
||||
;;
|
||||
|
||||
@ -391,7 +391,7 @@ BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
|
||||
done
|
||||
|
||||
# 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_imgopts
|
||||
|
@ -47,7 +47,7 @@ export PWD=`pwd`
|
||||
# $1 = prog to look for, $2* = default pathnames if not found in $PATH
|
||||
set_prog_path()
|
||||
{
|
||||
p=`which $1 2> /dev/null`
|
||||
p=`command -v $1 2> /dev/null`
|
||||
if [ -n "$p" -a -x "$p" ]; then
|
||||
echo $p
|
||||
return 0
|
||||
|
@ -167,7 +167,9 @@ _filter_qmp()
|
||||
{
|
||||
_filter_win32 | \
|
||||
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
|
||||
|
@ -153,8 +153,9 @@ function _launch_qemu()
|
||||
mkfifo "${fifo_out}"
|
||||
mkfifo "${fifo_in}"
|
||||
|
||||
"${QEMU}" -nographic -serial none ${comm} -machine accel=qtest "${@}" 2>&1 \
|
||||
"${QEMU}" -nographic -serial none ${comm} -machine accel=qtest "${@}" \
|
||||
>"${fifo_out}" \
|
||||
2>&1 \
|
||||
<"${fifo_in}" &
|
||||
QEMU_PID[${_QEMU_HANDLE}]=$!
|
||||
|
||||
|
@ -175,7 +175,9 @@ _cleanup_test_img()
|
||||
case "$IMGPROTO" in
|
||||
|
||||
nbd)
|
||||
if [ -n "$QEMU_NBD_PID" ]; then
|
||||
kill $QEMU_NBD_PID
|
||||
fi
|
||||
rm -f "$TEST_IMG_FILE"
|
||||
;;
|
||||
file)
|
||||
@ -213,6 +215,13 @@ _check_test_img()
|
||||
|
||||
_img_info()
|
||||
{
|
||||
if [[ "$1" == "--format-specific" ]]; then
|
||||
local format_specific=1
|
||||
shift
|
||||
else
|
||||
local format_specific=0
|
||||
fi
|
||||
|
||||
discard=0
|
||||
regex_json_spec_start='^ *"format-specific": \{'
|
||||
$QEMU_IMG info "$@" "$TEST_IMG" 2>&1 | \
|
||||
@ -222,7 +231,9 @@ _img_info()
|
||||
-e "/^disk size:/ D" \
|
||||
-e "/actual-size/ D" | \
|
||||
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
|
||||
elif [[ $line =~ $regex_json_spec_start ]]; then
|
||||
discard=2
|
||||
|
@ -111,4 +111,7 @@
|
||||
105 rw auto quick
|
||||
107 rw auto quick
|
||||
108 rw auto quick
|
||||
109 rw auto
|
||||
111 rw auto quick
|
||||
113 rw auto quick
|
||||
114 rw auto quick
|
||||
|
@ -7,6 +7,10 @@ import string
|
||||
class QcowHeaderExtension:
|
||||
|
||||
def __init__(self, magic, length, data):
|
||||
if length % 8 != 0:
|
||||
padding = 8 - (length % 8)
|
||||
data += "\0" * padding
|
||||
|
||||
self.magic = magic
|
||||
self.length = length
|
||||
self.data = data
|
||||
|
BIN
tests/qemu-iotests/sample_images/grub_mbr.raw.bz2
Normal file
BIN
tests/qemu-iotests/sample_images/grub_mbr.raw.bz2
Normal file
Binary file not shown.
@ -87,7 +87,7 @@ int main(int argc, char **argv)
|
||||
qtest_add_func("/uhci/pci/hotplug/usb-storage", test_usb_storage_hotplug);
|
||||
|
||||
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");
|
||||
ret = g_test_run();
|
||||
qtest_end();
|
||||
|
@ -91,7 +91,7 @@ int main(int argc, char **argv)
|
||||
qtest_add_func("/xhci/pci/hotplug/usb-uas", test_usb_uas_hotplug);
|
||||
|
||||
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();
|
||||
qtest_end();
|
||||
|
||||
|
@ -68,8 +68,8 @@ static QPCIBus *test_start(void)
|
||||
g_assert_cmpint(ret, ==, 0);
|
||||
close(fd);
|
||||
|
||||
cmdline = g_strdup_printf("-drive if=none,id=drive0,file=%s "
|
||||
"-drive if=none,id=drive1,file=/dev/null "
|
||||
cmdline = g_strdup_printf("-drive if=none,id=drive0,file=%s,format=raw "
|
||||
"-drive if=none,id=drive1,file=/dev/null,format=raw "
|
||||
"-device virtio-blk-pci,id=drv0,drive=drive0,"
|
||||
"addr=%x.%x",
|
||||
tmp_path, PCI_SLOT, PCI_FN);
|
||||
|
@ -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/hotplug", hotplug);
|
||||
|
||||
qtest_start("-drive id=drv0,if=none,file=/dev/null "
|
||||
"-drive id=drv1,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,format=raw "
|
||||
"-device virtio-scsi-pci,id=vscsi0 "
|
||||
"-device scsi-hd,bus=vscsi0.0,drive=drv0");
|
||||
ret = g_test_run();
|
||||
|
15
vl.c
15
vl.c
@ -2284,7 +2284,7 @@ static int mon_init_func(QemuOpts *opts, void *opaque)
|
||||
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;
|
||||
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, "chardev", label);
|
||||
qemu_opt_set_bool(opts, "pretty", pretty);
|
||||
if (def)
|
||||
qemu_opt_set(opts, "default", "on");
|
||||
monitor_device_index++;
|
||||
@ -3292,11 +3293,15 @@ int main(int argc, char **argv, char **envp)
|
||||
case QEMU_OPTION_monitor:
|
||||
default_monitor = 0;
|
||||
if (strncmp(optarg, "none", 4)) {
|
||||
monitor_parse(optarg, "readline");
|
||||
monitor_parse(optarg, "readline", false);
|
||||
}
|
||||
break;
|
||||
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;
|
||||
break;
|
||||
case QEMU_OPTION_mon:
|
||||
@ -3994,7 +3999,7 @@ int main(int argc, char **argv, char **envp)
|
||||
add_device_config(DEV_SCLP, "stdio");
|
||||
}
|
||||
if (default_monitor)
|
||||
monitor_parse("stdio", "readline");
|
||||
monitor_parse("stdio", "readline", false);
|
||||
}
|
||||
} else {
|
||||
if (default_serial)
|
||||
@ -4002,7 +4007,7 @@ int main(int argc, char **argv, char **envp)
|
||||
if (default_parallel)
|
||||
add_device_config(DEV_PARALLEL, "vc:80Cx24C");
|
||||
if (default_monitor)
|
||||
monitor_parse("vc:80Cx24C", "readline");
|
||||
monitor_parse("vc:80Cx24C", "readline", false);
|
||||
if (default_virtcon)
|
||||
add_device_config(DEV_VIRTCON, "vc:80Cx24C");
|
||||
if (default_sclp) {
|
||||
|
Loading…
Reference in New Issue
Block a user