Skip to content

Commit

Permalink
block: Drop permissions when migration completes
Browse files Browse the repository at this point in the history
With image locking, permissions affect other qemu processes as well. We
want to be sure that the destination can run, so let's drop permissions
on the source when migration completes.

Signed-off-by: Kevin Wolf <[email protected]>
Reviewed-by: Eric Blake <[email protected]>
  • Loading branch information
kevmw committed May 11, 2017
1 parent 4417ab7 commit cfa1a57
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 4 deletions.
12 changes: 11 additions & 1 deletion block.c
Original file line number Diff line number Diff line change
Expand Up @@ -4019,7 +4019,7 @@ void bdrv_invalidate_cache_all(Error **errp)
static int bdrv_inactivate_recurse(BlockDriverState *bs,
bool setting_flag)
{
BdrvChild *child;
BdrvChild *child, *parent;
int ret;

if (!setting_flag && bs->drv->bdrv_inactivate) {
Expand All @@ -4038,6 +4038,16 @@ static int bdrv_inactivate_recurse(BlockDriverState *bs,

if (setting_flag) {
bs->open_flags |= BDRV_O_INACTIVE;

QLIST_FOREACH(parent, &bs->parents, next_parent) {
if (parent->role->inactivate) {
ret = parent->role->inactivate(parent);
if (ret < 0) {
bs->open_flags &= ~BDRV_O_INACTIVE;
return ret;
}
}
}
}
return 0;
}
Expand Down
25 changes: 25 additions & 0 deletions block/block-backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,30 @@ static void blk_root_activate(BdrvChild *child, Error **errp)
}
}

static int blk_root_inactivate(BdrvChild *child)
{
BlockBackend *blk = child->opaque;

if (blk->disable_perm) {
return 0;
}

/* Only inactivate BlockBackends for guest devices (which are inactive at
* this point because the VM is stopped) and unattached monitor-owned
* BlockBackends. If there is still any other user like a block job, then
* we simply can't inactivate the image. */
if (!blk->dev && !blk->name[0]) {
return -EPERM;
}

blk->disable_perm = true;
if (blk->root) {
bdrv_child_try_set_perm(blk->root, 0, BLK_PERM_ALL, &error_abort);
}

return 0;
}

static const BdrvChildRole child_root = {
.inherit_options = blk_root_inherit_options,

Expand All @@ -168,6 +192,7 @@ static const BdrvChildRole child_root = {
.drained_end = blk_root_drained_end,

.activate = blk_root_activate,
.inactivate = blk_root_inactivate,
};

/*
Expand Down
7 changes: 4 additions & 3 deletions include/block/block_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -473,10 +473,11 @@ struct BdrvChildRole {
void (*drained_begin)(BdrvChild *child);
void (*drained_end)(BdrvChild *child);

/* Notifies the parent that the child has been activated (e.g. when
* migration is completing) and it can start requesting permissions and
* doing I/O on it. */
/* Notifies the parent that the child has been activated/inactivated (e.g.
* when migration is completing) and it can start/stop requesting
* permissions and doing I/O on it. */
void (*activate)(BdrvChild *child, Error **errp);
int (*inactivate)(BdrvChild *child);

void (*attach)(BdrvChild *child);
void (*detach)(BdrvChild *child);
Expand Down

0 comments on commit cfa1a57

Please sign in to comment.