blockdev: Separate BB name management
Introduce separate functions (monitor_add_blk() and monitor_remove_blk()) which set or unset a BB name. Since the name is equivalent to the monitor's reference to a BB, adding a name the same as declaring the BB to be monitor-owned and removing it revokes this status, hence the function names. Signed-off-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
2cf22d6a1a
commit
e5e785500b
@ -90,30 +90,17 @@ BlockBackend *blk_new(const char *name, Error **errp)
|
|||||||
{
|
{
|
||||||
BlockBackend *blk;
|
BlockBackend *blk;
|
||||||
|
|
||||||
assert(name && name[0]);
|
|
||||||
if (!id_wellformed(name)) {
|
|
||||||
error_setg(errp, "Invalid device name");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (blk_by_name(name)) {
|
|
||||||
error_setg(errp, "Device with id '%s' already exists", name);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (bdrv_find_node(name)) {
|
|
||||||
error_setg(errp,
|
|
||||||
"Device name '%s' conflicts with an existing node name",
|
|
||||||
name);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
blk = g_new0(BlockBackend, 1);
|
blk = g_new0(BlockBackend, 1);
|
||||||
blk->name = g_strdup(name);
|
|
||||||
blk->refcnt = 1;
|
blk->refcnt = 1;
|
||||||
notifier_list_init(&blk->remove_bs_notifiers);
|
notifier_list_init(&blk->remove_bs_notifiers);
|
||||||
notifier_list_init(&blk->insert_bs_notifiers);
|
notifier_list_init(&blk->insert_bs_notifiers);
|
||||||
|
|
||||||
QTAILQ_INSERT_TAIL(&block_backends, blk, link);
|
QTAILQ_INSERT_TAIL(&block_backends, blk, link);
|
||||||
QTAILQ_INSERT_TAIL(&monitor_block_backends, blk, monitor_link);
|
|
||||||
|
if (!monitor_add_blk(blk, name, errp)) {
|
||||||
|
blk_unref(blk);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
@ -174,7 +161,10 @@ BlockBackend *blk_new_open(const char *name, const char *filename,
|
|||||||
|
|
||||||
static void blk_delete(BlockBackend *blk)
|
static void blk_delete(BlockBackend *blk)
|
||||||
{
|
{
|
||||||
|
monitor_remove_blk(blk);
|
||||||
|
|
||||||
assert(!blk->refcnt);
|
assert(!blk->refcnt);
|
||||||
|
assert(!blk->name);
|
||||||
assert(!blk->dev);
|
assert(!blk->dev);
|
||||||
if (blk->bs) {
|
if (blk->bs) {
|
||||||
blk_remove_bs(blk);
|
blk_remove_bs(blk);
|
||||||
@ -185,15 +175,7 @@ static void blk_delete(BlockBackend *blk)
|
|||||||
g_free(blk->root_state.throttle_group);
|
g_free(blk->root_state.throttle_group);
|
||||||
throttle_group_unref(blk->root_state.throttle_state);
|
throttle_group_unref(blk->root_state.throttle_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Avoid double-remove after blk_hide_on_behalf_of_hmp_drive_del() */
|
|
||||||
if (blk->name[0]) {
|
|
||||||
QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link);
|
|
||||||
}
|
|
||||||
g_free(blk->name);
|
|
||||||
|
|
||||||
QTAILQ_REMOVE(&block_backends, blk, link);
|
QTAILQ_REMOVE(&block_backends, blk, link);
|
||||||
|
|
||||||
drive_info_del(blk->legacy_dinfo);
|
drive_info_del(blk->legacy_dinfo);
|
||||||
block_acct_cleanup(&blk->stats);
|
block_acct_cleanup(&blk->stats);
|
||||||
g_free(blk);
|
g_free(blk);
|
||||||
@ -279,14 +261,63 @@ BlockBackend *blk_next(BlockBackend *blk)
|
|||||||
: QTAILQ_FIRST(&monitor_block_backends);
|
: QTAILQ_FIRST(&monitor_block_backends);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a BlockBackend into the list of backends referenced by the monitor, with
|
||||||
|
* the given @name acting as the handle for the monitor.
|
||||||
|
* Strictly for use by blockdev.c.
|
||||||
|
*
|
||||||
|
* @name must not be null or empty.
|
||||||
|
*
|
||||||
|
* Returns true on success and false on failure. In the latter case, an Error
|
||||||
|
* object is returned through @errp.
|
||||||
|
*/
|
||||||
|
bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp)
|
||||||
|
{
|
||||||
|
assert(!blk->name);
|
||||||
|
assert(name && name[0]);
|
||||||
|
|
||||||
|
if (!id_wellformed(name)) {
|
||||||
|
error_setg(errp, "Invalid device name");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (blk_by_name(name)) {
|
||||||
|
error_setg(errp, "Device with id '%s' already exists", name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (bdrv_find_node(name)) {
|
||||||
|
error_setg(errp,
|
||||||
|
"Device name '%s' conflicts with an existing node name",
|
||||||
|
name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
blk->name = g_strdup(name);
|
||||||
|
QTAILQ_INSERT_TAIL(&monitor_block_backends, blk, monitor_link);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remove a BlockBackend from the list of backends referenced by the monitor.
|
||||||
|
* Strictly for use by blockdev.c.
|
||||||
|
*/
|
||||||
|
void monitor_remove_blk(BlockBackend *blk)
|
||||||
|
{
|
||||||
|
if (!blk->name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link);
|
||||||
|
g_free(blk->name);
|
||||||
|
blk->name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return @blk's name, a non-null string.
|
* Return @blk's name, a non-null string.
|
||||||
* Wart: the name is empty iff @blk has been hidden with
|
* Returns an empty string iff @blk is not referenced by the monitor.
|
||||||
* blk_hide_on_behalf_of_hmp_drive_del().
|
|
||||||
*/
|
*/
|
||||||
const char *blk_name(BlockBackend *blk)
|
const char *blk_name(BlockBackend *blk)
|
||||||
{
|
{
|
||||||
return blk->name;
|
return blk->name ?: "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -377,8 +408,7 @@ BlockBackend *blk_by_legacy_dinfo(DriveInfo *dinfo)
|
|||||||
*/
|
*/
|
||||||
void blk_hide_on_behalf_of_hmp_drive_del(BlockBackend *blk)
|
void blk_hide_on_behalf_of_hmp_drive_del(BlockBackend *blk)
|
||||||
{
|
{
|
||||||
QTAILQ_REMOVE(&monitor_block_backends, blk, monitor_link);
|
monitor_remove_blk(blk);
|
||||||
blk->name[0] = 0;
|
|
||||||
if (blk->bs) {
|
if (blk->bs) {
|
||||||
bdrv_make_anon(blk->bs);
|
bdrv_make_anon(blk->bs);
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,8 @@ void blk_remove_all_bs(void);
|
|||||||
const char *blk_name(BlockBackend *blk);
|
const char *blk_name(BlockBackend *blk);
|
||||||
BlockBackend *blk_by_name(const char *name);
|
BlockBackend *blk_by_name(const char *name);
|
||||||
BlockBackend *blk_next(BlockBackend *blk);
|
BlockBackend *blk_next(BlockBackend *blk);
|
||||||
|
bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp);
|
||||||
|
void monitor_remove_blk(BlockBackend *blk);
|
||||||
|
|
||||||
BlockDriverState *blk_bs(BlockBackend *blk);
|
BlockDriverState *blk_bs(BlockBackend *blk);
|
||||||
void blk_remove_bs(BlockBackend *blk);
|
void blk_remove_bs(BlockBackend *blk);
|
||||||
|
Loading…
Reference in New Issue
Block a user