static void mirror_complete(BlockJob *job, Error **errp) { MirrorBlockJob *s = container_of(job, MirrorBlockJob, common); BlockDriverState *target; target = blk_bs(s->target); if (!s->synced) { error_setg(errp, "The active block job '%s' cannot be completed", job->id); return; } if (s->backing_mode == MIRROR_OPEN_BACKING_CHAIN) { int ret; assert(!target->backing); ret = bdrv_open_backing_file(target, NULL, "backing", errp); if (ret < 0) { return; } } /* block all operations on to_replace bs */ if (s->replaces) { AioContext *replace_aio_context; s->to_replace = bdrv_find_node(s->replaces); if (!s->to_replace) { error_setg(errp, "Node name '%s' not found", s->replaces); return; } replace_aio_context = bdrv_get_aio_context(s->to_replace); aio_context_acquire(replace_aio_context); /* TODO Translate this into permission system. Current definition of * GRAPH_MOD would require to request it for the parents; they might * not even be BlockDriverStates, however, so a BdrvChild can't address * them. May need redefinition of GRAPH_MOD. */ error_setg(&s->replace_blocker, "block device is in use by block-job-complete"); bdrv_op_block_all(s->to_replace, s->replace_blocker); bdrv_ref(s->to_replace); aio_context_release(replace_aio_context); } s->should_complete = true; block_job_enter(&s->common); }
void qmp_block_set_write_threshold(const char *node_name, uint64_t threshold_bytes, Error **errp) { BlockDriverState *bs; AioContext *aio_context; bs = bdrv_find_node(node_name); if (!bs) { error_setg(errp, "Device '%s' not found", node_name); return; } aio_context = bdrv_get_aio_context(bs); aio_context_acquire(aio_context); bdrv_write_threshold_set(bs, threshold_bytes); aio_context_release(aio_context); }