X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=blockdev.c;h=4775a07d930351c4f32d4b6d8fd8807c19ed6314;hb=28605a22f564860c885bde42ad91840e9aacec45;hp=81f95d920b5412726bcf6fbcf4ed36e68f54fc81;hpb=186ac05f749c69e98030f037aa930ff2bc4ad7fb;p=mirror_qemu.git diff --git a/blockdev.c b/blockdev.c index 81f95d920b..4775a07d93 100644 --- a/blockdev.c +++ b/blockdev.c @@ -531,7 +531,9 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts, if ((buf = qemu_opt_get(opts, "format")) != NULL) { if (is_help_option(buf)) { error_printf("Supported formats:"); - bdrv_iterate_format(bdrv_format_print, NULL); + bdrv_iterate_format(bdrv_format_print, NULL, false); + error_printf("\nSupported formats (read-only):"); + bdrv_iterate_format(bdrv_format_print, NULL, true); error_printf("\n"); goto early_err; } @@ -992,9 +994,7 @@ DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type, blk = blockdev_init(filename, bs_opts, &local_err); bs_opts = NULL; if (!blk) { - if (local_err) { - error_propagate(errp, local_err); - } + error_propagate(errp, local_err); goto fail; } else { assert(!local_err); @@ -1257,7 +1257,6 @@ out_aio_context: * @node: The name of the BDS node to search for bitmaps * @name: The name of the bitmap to search for * @pbs: Output pointer for BDS lookup, if desired. Can be NULL. - * @paio: Output pointer for aio_context acquisition, if desired. Can be NULL. * @errp: Output pointer for error information. Can be NULL. * * @return: A bitmap object on success, or NULL on failure. @@ -1341,7 +1340,7 @@ struct BlkActionState { const BlkActionOps *ops; JobTxn *block_job_txn; TransactionProperties *txn_props; - QSIMPLEQ_ENTRY(BlkActionState) entry; + QTAILQ_ENTRY(BlkActionState) entry; }; /* internal snapshot private data */ @@ -1629,6 +1628,7 @@ static void external_snapshot_prepare(BlkActionState *common, error_setg_errno(errp, -size, "bdrv_getlength failed"); goto out; } + bdrv_refresh_filename(state->old_bs); bdrv_img_create(new_image_file, format, state->old_bs->filename, state->old_bs->drv->format_name, @@ -1703,8 +1703,7 @@ static void external_snapshot_commit(BlkActionState *common) * bdrv_reopen_multiple() across all the entries at once, because we * don't want to abort all of them if one of them fails the reopen */ if (!atomic_read(&state->old_bs->copy_on_read)) { - bdrv_reopen(state->old_bs, state->old_bs->open_flags & ~BDRV_O_RDWR, - NULL); + bdrv_reopen_set_read_only(state->old_bs, true, NULL); } aio_context_release(aio_context); @@ -1966,7 +1965,7 @@ static void block_dirty_bitmap_add_prepare(BlkActionState *common, action->has_granularity, action->granularity, action->has_persistent, action->persistent, action->has_autoload, action->autoload, - action->has_x_disabled, action->x_disabled, + action->has_disabled, action->disabled, &local_err); if (!local_err) { @@ -2011,11 +2010,7 @@ static void block_dirty_bitmap_clear_prepare(BlkActionState *common, return; } - if (bdrv_dirty_bitmap_user_locked(state->bitmap)) { - error_setg(errp, "Cannot modify a bitmap in use by another operation"); - return; - } else if (bdrv_dirty_bitmap_readonly(state->bitmap)) { - error_setg(errp, "Cannot clear a readonly bitmap"); + if (bdrv_dirty_bitmap_check(state->bitmap, BDRV_BITMAP_DEFAULT, errp)) { return; } @@ -2051,7 +2046,7 @@ static void block_dirty_bitmap_enable_prepare(BlkActionState *common, return; } - action = common->action->u.x_block_dirty_bitmap_enable.data; + action = common->action->u.block_dirty_bitmap_enable.data; state->bitmap = block_dirty_bitmap_lookup(action->node, action->name, NULL, @@ -2060,10 +2055,7 @@ static void block_dirty_bitmap_enable_prepare(BlkActionState *common, return; } - if (bdrv_dirty_bitmap_user_locked(state->bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be enabled", action->name); + if (bdrv_dirty_bitmap_check(state->bitmap, BDRV_BITMAP_ALLOW_RO, errp)) { return; } @@ -2092,7 +2084,7 @@ static void block_dirty_bitmap_disable_prepare(BlkActionState *common, return; } - action = common->action->u.x_block_dirty_bitmap_disable.data; + action = common->action->u.block_dirty_bitmap_disable.data; state->bitmap = block_dirty_bitmap_lookup(action->node, action->name, NULL, @@ -2101,10 +2093,7 @@ static void block_dirty_bitmap_disable_prepare(BlkActionState *common, return; } - if (bdrv_dirty_bitmap_user_locked(state->bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be disabled", action->name); + if (bdrv_dirty_bitmap_check(state->bitmap, BDRV_BITMAP_ALLOW_RO, errp)) { return; } @@ -2122,33 +2111,28 @@ static void block_dirty_bitmap_disable_abort(BlkActionState *common) } } +static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(const char *node, + const char *target, + strList *bitmaps, + HBitmap **backup, + Error **errp); + static void block_dirty_bitmap_merge_prepare(BlkActionState *common, Error **errp) { BlockDirtyBitmapMerge *action; BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState, common, common); - BdrvDirtyBitmap *merge_source; if (action_check_completion_mode(common, errp) < 0) { return; } - action = common->action->u.x_block_dirty_bitmap_merge.data; - state->bitmap = block_dirty_bitmap_lookup(action->node, - action->dst_name, - &state->bs, - errp); - if (!state->bitmap) { - return; - } - - merge_source = bdrv_find_dirty_bitmap(state->bs, action->src_name); - if (!merge_source) { - return; - } + action = common->action->u.block_dirty_bitmap_merge.data; - bdrv_merge_dirty_bitmap(state->bitmap, merge_source, &state->backup, errp); + state->bitmap = do_block_dirty_bitmap_merge(action->node, action->target, + action->bitmaps, &state->backup, + errp); } static void abort_prepare(BlkActionState *common, Error **errp) @@ -2212,17 +2196,17 @@ static const BlkActionOps actions[] = { .commit = block_dirty_bitmap_free_backup, .abort = block_dirty_bitmap_restore, }, - [TRANSACTION_ACTION_KIND_X_BLOCK_DIRTY_BITMAP_ENABLE] = { + [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_ENABLE] = { .instance_size = sizeof(BlockDirtyBitmapState), .prepare = block_dirty_bitmap_enable_prepare, .abort = block_dirty_bitmap_enable_abort, }, - [TRANSACTION_ACTION_KIND_X_BLOCK_DIRTY_BITMAP_DISABLE] = { + [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_DISABLE] = { .instance_size = sizeof(BlockDirtyBitmapState), .prepare = block_dirty_bitmap_disable_prepare, .abort = block_dirty_bitmap_disable_abort, }, - [TRANSACTION_ACTION_KIND_X_BLOCK_DIRTY_BITMAP_MERGE] = { + [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_MERGE] = { .instance_size = sizeof(BlockDirtyBitmapState), .prepare = block_dirty_bitmap_merge_prepare, .commit = block_dirty_bitmap_free_backup, @@ -2269,8 +2253,8 @@ void qmp_transaction(TransactionActionList *dev_list, BlkActionState *state, *next; Error *local_err = NULL; - QSIMPLEQ_HEAD(snap_bdrv_states, BlkActionState) snap_bdrv_states; - QSIMPLEQ_INIT(&snap_bdrv_states); + QTAILQ_HEAD(, BlkActionState) snap_bdrv_states; + QTAILQ_INIT(&snap_bdrv_states); /* Does this transaction get canceled as a group on failure? * If not, we don't really need to make a JobTxn. @@ -2301,7 +2285,7 @@ void qmp_transaction(TransactionActionList *dev_list, state->action = dev_info; state->block_job_txn = block_job_txn; state->txn_props = props; - QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, state, entry); + QTAILQ_INSERT_TAIL(&snap_bdrv_states, state, entry); state->ops->prepare(state, &local_err); if (local_err) { @@ -2310,7 +2294,7 @@ void qmp_transaction(TransactionActionList *dev_list, } } - QSIMPLEQ_FOREACH(state, &snap_bdrv_states, entry) { + QTAILQ_FOREACH(state, &snap_bdrv_states, entry) { if (state->ops->commit) { state->ops->commit(state); } @@ -2321,13 +2305,13 @@ void qmp_transaction(TransactionActionList *dev_list, delete_and_fail: /* failure, and it is all-or-none; roll back all operations */ - QSIMPLEQ_FOREACH(state, &snap_bdrv_states, entry) { + QTAILQ_FOREACH_REVERSE(state, &snap_bdrv_states, entry) { if (state->ops->abort) { state->ops->abort(state); } } exit: - QSIMPLEQ_FOREACH_SAFE(state, &snap_bdrv_states, entry, next) { + QTAILQ_FOREACH_SAFE(state, &snap_bdrv_states, entry, next) { if (state->ops->clean) { state->ops->clean(state); } @@ -2828,6 +2812,7 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name, { BlockDriverState *bs; BdrvDirtyBitmap *bitmap; + AioContext *aio_context = NULL; if (!name || name[0] == '\0') { error_setg(errp, "Bitmap name cannot be empty"); @@ -2862,22 +2847,28 @@ void qmp_block_dirty_bitmap_add(const char *node, const char *name, disabled = false; } - if (persistent && - !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp)) - { - return; + if (persistent) { + aio_context = bdrv_get_aio_context(bs); + aio_context_acquire(aio_context); + if (!bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp)) { + goto out; + } } bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp); if (bitmap == NULL) { - return; + goto out; } if (disabled) { bdrv_disable_dirty_bitmap(bitmap); } - bdrv_dirty_bitmap_set_persistance(bitmap, persistent); + bdrv_dirty_bitmap_set_persistence(bitmap, persistent); + out: + if (aio_context) { + aio_context_release(aio_context); + } } void qmp_block_dirty_bitmap_remove(const char *node, const char *name, @@ -2886,28 +2877,33 @@ void qmp_block_dirty_bitmap_remove(const char *node, const char *name, BlockDriverState *bs; BdrvDirtyBitmap *bitmap; Error *local_err = NULL; + AioContext *aio_context = NULL; bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp); if (!bitmap || !bs) { return; } - if (bdrv_dirty_bitmap_user_locked(bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation and" - " cannot be removed", name); + if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY | BDRV_BITMAP_RO, + errp)) { return; } - if (bdrv_dirty_bitmap_get_persistance(bitmap)) { + if (bdrv_dirty_bitmap_get_persistence(bitmap)) { + aio_context = bdrv_get_aio_context(bs); + aio_context_acquire(aio_context); bdrv_remove_persistent_dirty_bitmap(bs, name, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); - return; + goto out; } } bdrv_release_dirty_bitmap(bs, bitmap); + out: + if (aio_context) { + aio_context_release(aio_context); + } } /** @@ -2925,20 +2921,14 @@ void qmp_block_dirty_bitmap_clear(const char *node, const char *name, return; } - if (bdrv_dirty_bitmap_user_locked(bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be cleared", name); - return; - } else if (bdrv_dirty_bitmap_readonly(bitmap)) { - error_setg(errp, "Bitmap '%s' is readonly and cannot be cleared", name); + if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, errp)) { return; } bdrv_clear_dirty_bitmap(bitmap, NULL); } -void qmp_x_block_dirty_bitmap_enable(const char *node, const char *name, +void qmp_block_dirty_bitmap_enable(const char *node, const char *name, Error **errp) { BlockDriverState *bs; @@ -2949,17 +2939,14 @@ void qmp_x_block_dirty_bitmap_enable(const char *node, const char *name, return; } - if (bdrv_dirty_bitmap_user_locked(bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be enabled", name); + if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) { return; } bdrv_enable_dirty_bitmap(bitmap); } -void qmp_x_block_dirty_bitmap_disable(const char *node, const char *name, +void qmp_block_dirty_bitmap_disable(const char *node, const char *name, Error **errp) { BlockDriverState *bs; @@ -2970,34 +2957,63 @@ void qmp_x_block_dirty_bitmap_disable(const char *node, const char *name, return; } - if (bdrv_dirty_bitmap_user_locked(bitmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be disabled", name); + if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) { return; } bdrv_disable_dirty_bitmap(bitmap); } -void qmp_x_block_dirty_bitmap_merge(const char *node, const char *dst_name, - const char *src_name, Error **errp) +static BdrvDirtyBitmap *do_block_dirty_bitmap_merge(const char *node, + const char *target, + strList *bitmaps, + HBitmap **backup, + Error **errp) { BlockDriverState *bs; - BdrvDirtyBitmap *dst, *src; + BdrvDirtyBitmap *dst, *src, *anon; + strList *lst; + Error *local_err = NULL; - dst = block_dirty_bitmap_lookup(node, dst_name, &bs, errp); + dst = block_dirty_bitmap_lookup(node, target, &bs, errp); if (!dst) { - return; + return NULL; } - src = bdrv_find_dirty_bitmap(bs, src_name); - if (!src) { - error_setg(errp, "Dirty bitmap '%s' not found", src_name); - return; + anon = bdrv_create_dirty_bitmap(bs, bdrv_dirty_bitmap_granularity(dst), + NULL, errp); + if (!anon) { + return NULL; } - bdrv_merge_dirty_bitmap(dst, src, NULL, errp); + for (lst = bitmaps; lst; lst = lst->next) { + src = bdrv_find_dirty_bitmap(bs, lst->value); + if (!src) { + error_setg(errp, "Dirty bitmap '%s' not found", lst->value); + dst = NULL; + goto out; + } + + bdrv_merge_dirty_bitmap(anon, src, NULL, &local_err); + if (local_err) { + error_propagate(errp, local_err); + dst = NULL; + goto out; + } + } + + /* Merge into dst; dst is unchanged on failure. */ + bdrv_merge_dirty_bitmap(dst, anon, backup, errp); + + out: + bdrv_release_dirty_bitmap(bs, anon); + return dst; +} + +void qmp_block_dirty_bitmap_merge(const char *node, const char *target, + strList *bitmaps, Error **errp) +{ + do_block_dirty_bitmap_merge(node, target, bitmaps, NULL, errp); } BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node, @@ -3192,6 +3208,7 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device, goto out; } assert(bdrv_get_aio_context(base_bs) == aio_context); + bdrv_refresh_filename(base_bs); base_name = base_bs->filename; } @@ -3311,6 +3328,10 @@ void qmp_block_commit(bool has_job_id, const char *job_id, const char *device, goto out; } } else if (has_top && top) { + /* This strcmp() is just a shortcut, there is no need to + * refresh @bs's filename. If it mismatches, + * bdrv_find_backing_image() will do the refresh and may still + * return @bs. */ if (strcmp(bs->filename, top) != 0) { top_bs = bdrv_find_backing_image(bs, top); } @@ -3471,6 +3492,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn, if (backup->mode != NEW_IMAGE_MODE_EXISTING) { assert(backup->format); if (source) { + bdrv_refresh_filename(source); bdrv_img_create(backup->target, backup->format, source->filename, source->drv->format_name, NULL, size, flags, false, &local_err); @@ -3514,10 +3536,7 @@ static BlockJob *do_drive_backup(DriveBackup *backup, JobTxn *txn, bdrv_unref(target_bs); goto out; } - if (bdrv_dirty_bitmap_user_locked(bmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be used for backup", backup->bitmap); + if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_DEFAULT, errp)) { goto out; } } @@ -3558,6 +3577,11 @@ BlockDeviceInfoList *qmp_query_named_block_nodes(Error **errp) return bdrv_named_nodes_list(errp); } +XDbgBlockGraph *qmp_x_debug_query_block_graph(Error **errp) +{ + return bdrv_get_xdbg_block_graph(errp); +} + BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn, Error **errp) { @@ -3622,10 +3646,7 @@ BlockJob *do_blockdev_backup(BlockdevBackup *backup, JobTxn *txn, error_setg(errp, "Bitmap '%s' could not be found", backup->bitmap); goto out; } - if (bdrv_dirty_bitmap_user_locked(bmap)) { - error_setg(errp, - "Bitmap '%s' is currently in use by another operation" - " and cannot be used for backup", backup->bitmap); + if (bdrv_dirty_bitmap_check(bmap, BDRV_BITMAP_DEFAULT, errp)) { goto out; } } @@ -3735,6 +3756,39 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs, sync = MIRROR_SYNC_MODE_FULL; } + if (has_replaces) { + BlockDriverState *to_replace_bs; + AioContext *replace_aio_context; + int64_t bs_size, replace_size; + + bs_size = bdrv_getlength(bs); + if (bs_size < 0) { + error_setg_errno(errp, -bs_size, "Failed to query device's size"); + return; + } + + to_replace_bs = check_to_replace_node(bs, replaces, errp); + if (!to_replace_bs) { + return; + } + + replace_aio_context = bdrv_get_aio_context(to_replace_bs); + aio_context_acquire(replace_aio_context); + replace_size = bdrv_getlength(to_replace_bs); + aio_context_release(replace_aio_context); + + if (replace_size < 0) { + error_setg_errno(errp, -replace_size, + "Failed to query the replacement node's size"); + return; + } + if (bs_size != replace_size) { + error_setg(errp, "cannot replace image with a mirror image of " + "different size"); + return; + } + } + /* pass the node name to replace to mirror start since it's loose coupling * and will allow to check whether the node still exist at mirror completion */ @@ -3795,33 +3849,11 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) } if (arg->has_replaces) { - BlockDriverState *to_replace_bs; - AioContext *replace_aio_context; - int64_t replace_size; - if (!arg->has_node_name) { error_setg(errp, "a node-name must be provided when replacing a" " named node of the graph"); goto out; } - - to_replace_bs = check_to_replace_node(bs, arg->replaces, &local_err); - - if (!to_replace_bs) { - error_propagate(errp, local_err); - goto out; - } - - replace_aio_context = bdrv_get_aio_context(to_replace_bs); - aio_context_acquire(replace_aio_context); - replace_size = bdrv_getlength(to_replace_bs); - aio_context_release(replace_aio_context); - - if (size != replace_size) { - error_setg(errp, "cannot replace image with a mirror image of " - "different size"); - goto out; - } } if (arg->mode == NEW_IMAGE_MODE_ABSOLUTE_PATHS) { @@ -3846,6 +3878,7 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp) break; case NEW_IMAGE_MODE_ABSOLUTE_PATHS: /* create new image with backing file */ + bdrv_refresh_filename(source); bdrv_img_create(arg->target, format, source->filename, source->drv->format_name, @@ -4100,7 +4133,6 @@ void qmp_change_backing_file(const char *device, BlockDriverState *image_bs = NULL; Error *local_err = NULL; bool ro; - int open_flags; int ret; bs = qmp_get_root_bs(device, errp); @@ -4142,13 +4174,10 @@ void qmp_change_backing_file(const char *device, } /* if not r/w, reopen to make r/w */ - open_flags = image_bs->open_flags; ro = bdrv_is_read_only(image_bs); if (ro) { - bdrv_reopen(image_bs, open_flags | BDRV_O_RDWR, &local_err); - if (local_err) { - error_propagate(errp, local_err); + if (bdrv_reopen_set_read_only(image_bs, false, errp) != 0) { goto out; } } @@ -4164,7 +4193,7 @@ void qmp_change_backing_file(const char *device, } if (ro) { - bdrv_reopen(image_bs, open_flags, &local_err); + bdrv_reopen_set_read_only(image_bs, true, &local_err); error_propagate(errp, local_err); } @@ -4238,6 +4267,53 @@ fail: visit_free(v); } +void qmp_x_blockdev_reopen(BlockdevOptions *options, Error **errp) +{ + BlockDriverState *bs; + AioContext *ctx; + QObject *obj; + Visitor *v = qobject_output_visitor_new(&obj); + Error *local_err = NULL; + BlockReopenQueue *queue; + QDict *qdict; + + /* Check for the selected node name */ + if (!options->has_node_name) { + error_setg(errp, "Node name not specified"); + goto fail; + } + + bs = bdrv_find_node(options->node_name); + if (!bs) { + error_setg(errp, "Cannot find node named '%s'", options->node_name); + goto fail; + } + + /* Put all options in a QDict and flatten it */ + visit_type_BlockdevOptions(v, NULL, &options, &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto fail; + } + + visit_complete(v, &obj); + qdict = qobject_to(QDict, obj); + + qdict_flatten(qdict); + + /* Perform the reopen operation */ + ctx = bdrv_get_aio_context(bs); + aio_context_acquire(ctx); + bdrv_subtree_drained_begin(bs); + queue = bdrv_reopen_queue(NULL, bs, qdict, false); + bdrv_reopen_multiple(queue, errp); + bdrv_subtree_drained_end(bs); + aio_context_release(ctx); + +fail: + visit_free(v); +} + void qmp_blockdev_del(const char *node_name, Error **errp) { AioContext *aio_context; @@ -4259,7 +4335,7 @@ void qmp_blockdev_del(const char *node_name, Error **errp) goto out; } - if (!bs->monitor_list.tqe_prev) { + if (!QTAILQ_IN_USE(bs, monitor_list)) { error_setg(errp, "Node %s is not owned by the monitor", bs->node_name); goto out; @@ -4403,22 +4479,22 @@ void qmp_x_blockdev_set_iothread(const char *node_name, StrOrNull *iothread, aio_context_release(old_context); } -void qmp_x_block_latency_histogram_set( - const char *device, +void qmp_block_latency_histogram_set( + const char *id, bool has_boundaries, uint64List *boundaries, bool has_boundaries_read, uint64List *boundaries_read, bool has_boundaries_write, uint64List *boundaries_write, bool has_boundaries_flush, uint64List *boundaries_flush, Error **errp) { - BlockBackend *blk = blk_by_name(device); + BlockBackend *blk = qmp_get_blk(NULL, id, errp); BlockAcctStats *stats; int ret; if (!blk) { - error_setg(errp, "Device '%s' not found", device); return; } + stats = blk_get_stats(blk); if (!has_boundaries && !has_boundaries_read && !has_boundaries_write && @@ -4433,7 +4509,7 @@ void qmp_x_block_latency_histogram_set( stats, BLOCK_ACCT_READ, has_boundaries_read ? boundaries_read : boundaries); if (ret) { - error_setg(errp, "Device '%s' set read boundaries fail", device); + error_setg(errp, "Device '%s' set read boundaries fail", id); return; } } @@ -4443,7 +4519,7 @@ void qmp_x_block_latency_histogram_set( stats, BLOCK_ACCT_WRITE, has_boundaries_write ? boundaries_write : boundaries); if (ret) { - error_setg(errp, "Device '%s' set write boundaries fail", device); + error_setg(errp, "Device '%s' set write boundaries fail", id); return; } } @@ -4453,7 +4529,7 @@ void qmp_x_block_latency_histogram_set( stats, BLOCK_ACCT_FLUSH, has_boundaries_flush ? boundaries_flush : boundaries); if (ret) { - error_setg(errp, "Device '%s' set flush boundaries fail", device); + error_setg(errp, "Device '%s' set flush boundaries fail", id); return; } }