Skip to content

Commit

Permalink
blockdev: Keep track of monitor-owned BDS
Browse files Browse the repository at this point in the history
As a side effect, we can now make x-blockdev-del's check whether a BDS
is actually owned by the monitor explicit.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
XanClic committed Feb 2, 2016
1 parent 2c1d04e commit 9c4218e
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 1 deletion.
28 changes: 27 additions & 1 deletion blockdev.c
Expand Up @@ -50,6 +50,9 @@
#include "trace.h"
#include "sysemu/arch_init.h"

static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states);

static const char *const if_name[IF_COUNT] = {
[IF_NONE] = "none",
[IF_IDE] = "ide",
Expand Down Expand Up @@ -702,6 +705,19 @@ static BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
return NULL;
}

void blockdev_close_all_bdrv_states(void)
{
BlockDriverState *bs, *next_bs;

QTAILQ_FOREACH_SAFE(bs, &monitor_bdrv_states, monitor_list, next_bs) {
AioContext *ctx = bdrv_get_aio_context(bs);

aio_context_acquire(ctx);
bdrv_unref(bs);
aio_context_release(ctx);
}
}

static void qemu_opt_rename(QemuOpts *opts, const char *from, const char *to,
Error **errp)
{
Expand Down Expand Up @@ -3875,12 +3891,15 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
if (!bs) {
goto fail;
}

QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
}

if (bs && bdrv_key_required(bs)) {
if (blk) {
blk_unref(blk);
} else {
QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
bdrv_unref(bs);
}
error_setg(errp, "blockdev-add doesn't support encrypted devices");
Expand Down Expand Up @@ -3940,7 +3959,13 @@ void qmp_x_blockdev_del(bool has_id, const char *id,
goto out;
}

if (bs->refcnt > 1 || !QLIST_EMPTY(&bs->parents)) {
if (!blk && !bs->monitor_list.tqe_prev) {
error_setg(errp, "Node %s is not owned by the monitor",
bs->node_name);
goto out;
}

if (bs->refcnt > 1) {
error_setg(errp, "Block device %s is in use",
bdrv_get_device_or_node_name(bs));
goto out;
Expand All @@ -3950,6 +3975,7 @@ void qmp_x_blockdev_del(bool has_id, const char *id,
if (blk) {
blk_unref(blk);
} else {
QTAILQ_REMOVE(&monitor_bdrv_states, bs, monitor_list);
bdrv_unref(bs);
}

Expand Down
4 changes: 4 additions & 0 deletions include/block/block_int.h
Expand Up @@ -445,6 +445,8 @@ struct BlockDriverState {
QTAILQ_ENTRY(BlockDriverState) device_list;
/* element of the list of all BlockDriverStates (all_bdrv_states) */
QTAILQ_ENTRY(BlockDriverState) bs_list;
/* element of the list of monitor-owned BDS */
QTAILQ_ENTRY(BlockDriverState) monitor_list;
QLIST_HEAD(, BdrvDirtyBitmap) dirty_bitmaps;
int refcnt;

Expand Down Expand Up @@ -707,4 +709,6 @@ bool bdrv_requests_pending(BlockDriverState *bs);
void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out);
void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in);

void blockdev_close_all_bdrv_states(void);

#endif /* BLOCK_INT_H */
1 change: 1 addition & 0 deletions stubs/Makefile.objs
@@ -1,5 +1,6 @@
stub-obj-y += arch-query-cpu-def.o
stub-obj-y += bdrv-commit-all.o
stub-obj-y += blockdev-close-all-bdrv-states.o
stub-obj-y += clock-warp.o
stub-obj-y += cpu-get-clock.o
stub-obj-y += cpu-get-icount.o
Expand Down
5 changes: 5 additions & 0 deletions stubs/blockdev-close-all-bdrv-states.c
@@ -0,0 +1,5 @@
#include "block/block_int.h"

void blockdev_close_all_bdrv_states(void)
{
}

0 comments on commit 9c4218e

Please sign in to comment.