diff options
Diffstat (limited to 'qemu/block/blkdebug.c')
-rw-r--r-- | qemu/block/blkdebug.c | 150 |
1 files changed, 52 insertions, 98 deletions
diff --git a/qemu/block/blkdebug.c b/qemu/block/blkdebug.c index bc247f46f..20d25bda6 100644 --- a/qemu/block/blkdebug.c +++ b/qemu/block/blkdebug.c @@ -22,7 +22,9 @@ * THE SOFTWARE. */ -#include "qemu-common.h" +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/cutils.h" #include "qemu/config-file.h" #include "block/block_int.h" #include "qemu/module.h" @@ -30,12 +32,13 @@ #include "qapi/qmp/qdict.h" #include "qapi/qmp/qint.h" #include "qapi/qmp/qstring.h" +#include "sysemu/qtest.h" typedef struct BDRVBlkdebugState { int state; int new_state; - QLIST_HEAD(, BlkdebugRule) rules[BLKDBG_EVENT_MAX]; + QLIST_HEAD(, BlkdebugRule) rules[BLKDBG__MAX]; QSIMPLEQ_HEAD(, BlkdebugRule) active_rules; QLIST_HEAD(, BlkdebugSuspendedReq) suspended_reqs; } BDRVBlkdebugState; @@ -63,7 +66,7 @@ enum { }; typedef struct BlkdebugRule { - BlkDebugEvent event; + BlkdebugEvent event; int action; int state; union { @@ -142,69 +145,12 @@ static QemuOptsList *config_groups[] = { NULL }; -static const char *event_names[BLKDBG_EVENT_MAX] = { - [BLKDBG_L1_UPDATE] = "l1_update", - [BLKDBG_L1_GROW_ALLOC_TABLE] = "l1_grow.alloc_table", - [BLKDBG_L1_GROW_WRITE_TABLE] = "l1_grow.write_table", - [BLKDBG_L1_GROW_ACTIVATE_TABLE] = "l1_grow.activate_table", - - [BLKDBG_L2_LOAD] = "l2_load", - [BLKDBG_L2_UPDATE] = "l2_update", - [BLKDBG_L2_UPDATE_COMPRESSED] = "l2_update_compressed", - [BLKDBG_L2_ALLOC_COW_READ] = "l2_alloc.cow_read", - [BLKDBG_L2_ALLOC_WRITE] = "l2_alloc.write", - - [BLKDBG_READ_AIO] = "read_aio", - [BLKDBG_READ_BACKING_AIO] = "read_backing_aio", - [BLKDBG_READ_COMPRESSED] = "read_compressed", - - [BLKDBG_WRITE_AIO] = "write_aio", - [BLKDBG_WRITE_COMPRESSED] = "write_compressed", - - [BLKDBG_VMSTATE_LOAD] = "vmstate_load", - [BLKDBG_VMSTATE_SAVE] = "vmstate_save", - - [BLKDBG_COW_READ] = "cow_read", - [BLKDBG_COW_WRITE] = "cow_write", - - [BLKDBG_REFTABLE_LOAD] = "reftable_load", - [BLKDBG_REFTABLE_GROW] = "reftable_grow", - [BLKDBG_REFTABLE_UPDATE] = "reftable_update", - - [BLKDBG_REFBLOCK_LOAD] = "refblock_load", - [BLKDBG_REFBLOCK_UPDATE] = "refblock_update", - [BLKDBG_REFBLOCK_UPDATE_PART] = "refblock_update_part", - [BLKDBG_REFBLOCK_ALLOC] = "refblock_alloc", - [BLKDBG_REFBLOCK_ALLOC_HOOKUP] = "refblock_alloc.hookup", - [BLKDBG_REFBLOCK_ALLOC_WRITE] = "refblock_alloc.write", - [BLKDBG_REFBLOCK_ALLOC_WRITE_BLOCKS] = "refblock_alloc.write_blocks", - [BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE] = "refblock_alloc.write_table", - [BLKDBG_REFBLOCK_ALLOC_SWITCH_TABLE] = "refblock_alloc.switch_table", - - [BLKDBG_CLUSTER_ALLOC] = "cluster_alloc", - [BLKDBG_CLUSTER_ALLOC_BYTES] = "cluster_alloc_bytes", - [BLKDBG_CLUSTER_FREE] = "cluster_free", - - [BLKDBG_FLUSH_TO_OS] = "flush_to_os", - [BLKDBG_FLUSH_TO_DISK] = "flush_to_disk", - - [BLKDBG_PWRITEV_RMW_HEAD] = "pwritev_rmw.head", - [BLKDBG_PWRITEV_RMW_AFTER_HEAD] = "pwritev_rmw.after_head", - [BLKDBG_PWRITEV_RMW_TAIL] = "pwritev_rmw.tail", - [BLKDBG_PWRITEV_RMW_AFTER_TAIL] = "pwritev_rmw.after_tail", - [BLKDBG_PWRITEV] = "pwritev", - [BLKDBG_PWRITEV_ZERO] = "pwritev_zero", - [BLKDBG_PWRITEV_DONE] = "pwritev_done", - - [BLKDBG_EMPTY_IMAGE_PREPARE] = "empty_image_prepare", -}; - -static int get_event_by_name(const char *name, BlkDebugEvent *event) +static int get_event_by_name(const char *name, BlkdebugEvent *event) { int i; - for (i = 0; i < BLKDBG_EVENT_MAX; i++) { - if (!strcmp(event_names[i], name)) { + for (i = 0; i < BLKDBG__MAX; i++) { + if (!strcmp(BlkdebugEvent_lookup[i], name)) { *event = i; return 0; } @@ -223,7 +169,7 @@ static int add_rule(void *opaque, QemuOpts *opts, Error **errp) struct add_rule_data *d = opaque; BDRVBlkdebugState *s = d->s; const char* event_name; - BlkDebugEvent event; + BlkdebugEvent event; struct BlkdebugRule *rule; /* Find the right event for the rule */ @@ -426,11 +372,11 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags, /* Set initial state */ s->state = 1; - /* Open the backing file */ - assert(bs->file == NULL); - ret = bdrv_open_image(&bs->file, qemu_opt_get(opts, "x-image"), options, "image", - bs, &child_file, false, &local_err); - if (ret < 0) { + /* Open the image file */ + bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image", + bs, &child_file, false, &local_err); + if (local_err) { + ret = -EINVAL; error_propagate(errp, local_err); goto out; } @@ -449,7 +395,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags, goto out; fail_unref: - bdrv_unref(bs->file); + bdrv_unref_child(bs, bs->file); out: qemu_opts_del(opts); return ret; @@ -510,7 +456,8 @@ static BlockAIOCB *blkdebug_aio_readv(BlockDriverState *bs, return inject_error(bs, cb, opaque, rule); } - return bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors, cb, opaque); + return bdrv_aio_readv(bs->file->bs, sector_num, qiov, nb_sectors, + cb, opaque); } static BlockAIOCB *blkdebug_aio_writev(BlockDriverState *bs, @@ -532,7 +479,8 @@ static BlockAIOCB *blkdebug_aio_writev(BlockDriverState *bs, return inject_error(bs, cb, opaque, rule); } - return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque); + return bdrv_aio_writev(bs->file->bs, sector_num, qiov, nb_sectors, + cb, opaque); } static BlockAIOCB *blkdebug_aio_flush(BlockDriverState *bs, @@ -551,7 +499,7 @@ static BlockAIOCB *blkdebug_aio_flush(BlockDriverState *bs, return inject_error(bs, cb, opaque, rule); } - return bdrv_aio_flush(bs->file, cb, opaque); + return bdrv_aio_flush(bs->file->bs, cb, opaque); } @@ -561,7 +509,7 @@ static void blkdebug_close(BlockDriverState *bs) BlkdebugRule *rule, *next; int i; - for (i = 0; i < BLKDBG_EVENT_MAX; i++) { + for (i = 0; i < BLKDBG__MAX; i++) { QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) { remove_rule(rule); } @@ -581,9 +529,13 @@ static void suspend_request(BlockDriverState *bs, BlkdebugRule *rule) remove_rule(rule); QLIST_INSERT_HEAD(&s->suspended_reqs, &r, next); - printf("blkdebug: Suspended request '%s'\n", r.tag); + if (!qtest_enabled()) { + printf("blkdebug: Suspended request '%s'\n", r.tag); + } qemu_coroutine_yield(); - printf("blkdebug: Resuming request '%s'\n", r.tag); + if (!qtest_enabled()) { + printf("blkdebug: Resuming request '%s'\n", r.tag); + } QLIST_REMOVE(&r, next); g_free(r.tag); @@ -620,13 +572,13 @@ static bool process_rule(BlockDriverState *bs, struct BlkdebugRule *rule, return injected; } -static void blkdebug_debug_event(BlockDriverState *bs, BlkDebugEvent event) +static void blkdebug_debug_event(BlockDriverState *bs, BlkdebugEvent event) { BDRVBlkdebugState *s = bs->opaque; struct BlkdebugRule *rule, *next; bool injected; - assert((int)event >= 0 && event < BLKDBG_EVENT_MAX); + assert((int)event >= 0 && event < BLKDBG__MAX); injected = false; s->new_state = s->state; @@ -641,7 +593,7 @@ static int blkdebug_debug_breakpoint(BlockDriverState *bs, const char *event, { BDRVBlkdebugState *s = bs->opaque; struct BlkdebugRule *rule; - BlkDebugEvent blkdebug_event; + BlkdebugEvent blkdebug_event; if (get_event_by_name(event, &blkdebug_event) < 0) { return -ENOENT; @@ -683,7 +635,7 @@ static int blkdebug_debug_remove_breakpoint(BlockDriverState *bs, BlkdebugRule *rule, *next; int i, ret = -ENOENT; - for (i = 0; i < BLKDBG_EVENT_MAX; i++) { + for (i = 0; i < BLKDBG__MAX; i++) { QLIST_FOREACH_SAFE(rule, &s->rules[i], next, next) { if (rule->action == ACTION_SUSPEND && !strcmp(rule->options.suspend.tag, tag)) { @@ -716,55 +668,50 @@ static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag) static int64_t blkdebug_getlength(BlockDriverState *bs) { - return bdrv_getlength(bs->file); + return bdrv_getlength(bs->file->bs); } static int blkdebug_truncate(BlockDriverState *bs, int64_t offset) { - return bdrv_truncate(bs->file, offset); + return bdrv_truncate(bs->file->bs, offset); } -static void blkdebug_refresh_filename(BlockDriverState *bs) +static void blkdebug_refresh_filename(BlockDriverState *bs, QDict *options) { QDict *opts; const QDictEntry *e; bool force_json = false; - for (e = qdict_first(bs->options); e; e = qdict_next(bs->options, e)) { + for (e = qdict_first(options); e; e = qdict_next(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."))) + strcmp(qdict_entry_key(e), "x-image")) { force_json = true; break; } } - if (force_json && !bs->file->full_open_options) { + if (force_json && !bs->file->bs->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]) { + if (!force_json && bs->file->bs->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); + qdict_get_try_str(options, "config") ?: "", + bs->file->bs->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)); + QINCREF(bs->file->bs->full_open_options); + qdict_put_obj(opts, "image", QOBJECT(bs->file->bs->full_open_options)); - 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."))) - { + for (e = qdict_first(options); e; e = qdict_next(options, e)) { + if (strcmp(qdict_entry_key(e), "x-image")) { qobject_incref(qdict_entry_value(e)); qdict_put_obj(opts, qdict_entry_key(e), qdict_entry_value(e)); } @@ -773,6 +720,12 @@ static void blkdebug_refresh_filename(BlockDriverState *bs) bs->full_open_options = opts; } +static int blkdebug_reopen_prepare(BDRVReopenState *reopen_state, + BlockReopenQueue *queue, Error **errp) +{ + return 0; +} + static BlockDriver bdrv_blkdebug = { .format_name = "blkdebug", .protocol_name = "blkdebug", @@ -781,6 +734,7 @@ static BlockDriver bdrv_blkdebug = { .bdrv_parse_filename = blkdebug_parse_filename, .bdrv_file_open = blkdebug_open, .bdrv_close = blkdebug_close, + .bdrv_reopen_prepare = blkdebug_reopen_prepare, .bdrv_getlength = blkdebug_getlength, .bdrv_truncate = blkdebug_truncate, .bdrv_refresh_filename = blkdebug_refresh_filename, |