Skip to content

Commit

Permalink
blockdev: acquire AioContext in change-backing-file
Browse files Browse the repository at this point in the history
Add dataplane support to the change-backing-file QMP commands.  By
acquiring the AioContext we avoid race conditions with the dataplane
thread which may also be accessing the BlockDriverState.

Note that this command operates on both bs and a node in its chain
(image_bs).  The bdrv_chain_contains(bs, image_bs) check guarantees that
bs and image_bs are in the same AioContext.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
stefanhaRH authored and kevmw committed Dec 10, 2014
1 parent e344209 commit 729962f
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 6 deletions.
19 changes: 13 additions & 6 deletions blockdev.c
Expand Up @@ -2584,6 +2584,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;
Expand All @@ -2597,34 +2598,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 */
Expand All @@ -2635,7 +2639,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;
}
}

Expand All @@ -2655,6 +2659,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)
Expand Down
1 change: 1 addition & 0 deletions hw/block/dataplane/virtio-blk.c
Expand Up @@ -197,6 +197,7 @@ 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_INTERNAL_SNAPSHOT_DELETE,
Expand Down

0 comments on commit 729962f

Please sign in to comment.