block: Exclude nested options only for children in append_open_options()
Some drivers have nested options (e.g. blkdebug rule arrays), which don't belong to a child node and shouldn't be removed. Don't remove all options with "." in their name, but check for the complete prefixes of actually existing child nodes. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
9e700c1ac6
commit
260fecf13b
20
block.c
20
block.c
@ -1101,11 +1101,13 @@ static int bdrv_fill_options(QDict **options, const char **pfilename,
|
|||||||
|
|
||||||
static BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
|
static BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs,
|
||||||
BlockDriverState *child_bs,
|
BlockDriverState *child_bs,
|
||||||
|
const char *child_name,
|
||||||
const BdrvChildRole *child_role)
|
const BdrvChildRole *child_role)
|
||||||
{
|
{
|
||||||
BdrvChild *child = g_new(BdrvChild, 1);
|
BdrvChild *child = g_new(BdrvChild, 1);
|
||||||
*child = (BdrvChild) {
|
*child = (BdrvChild) {
|
||||||
.bs = child_bs,
|
.bs = child_bs,
|
||||||
|
.name = g_strdup(child_name),
|
||||||
.role = child_role,
|
.role = child_role,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1119,6 +1121,7 @@ static void bdrv_detach_child(BdrvChild *child)
|
|||||||
{
|
{
|
||||||
QLIST_REMOVE(child, next);
|
QLIST_REMOVE(child, next);
|
||||||
QLIST_REMOVE(child, next_parent);
|
QLIST_REMOVE(child, next_parent);
|
||||||
|
g_free(child->name);
|
||||||
g_free(child);
|
g_free(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1165,7 +1168,7 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd)
|
|||||||
bs->backing = NULL;
|
bs->backing = NULL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
bs->backing = bdrv_attach_child(bs, backing_hd, &child_backing);
|
bs->backing = bdrv_attach_child(bs, backing_hd, "backing", &child_backing);
|
||||||
bs->open_flags &= ~BDRV_O_NO_BACKING;
|
bs->open_flags &= ~BDRV_O_NO_BACKING;
|
||||||
pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_hd->filename);
|
pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_hd->filename);
|
||||||
pstrcpy(bs->backing_format, sizeof(bs->backing_format),
|
pstrcpy(bs->backing_format, sizeof(bs->backing_format),
|
||||||
@ -1321,7 +1324,7 @@ BdrvChild *bdrv_open_child(const char *filename,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = bdrv_attach_child(parent, bs, child_role);
|
c = bdrv_attach_child(parent, bs, bdref_key, child_role);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
qdict_del(options, bdref_key);
|
qdict_del(options, bdref_key);
|
||||||
@ -3951,13 +3954,22 @@ static bool append_open_options(QDict *d, BlockDriverState *bs)
|
|||||||
{
|
{
|
||||||
const QDictEntry *entry;
|
const QDictEntry *entry;
|
||||||
QemuOptDesc *desc;
|
QemuOptDesc *desc;
|
||||||
|
BdrvChild *child;
|
||||||
bool found_any = false;
|
bool found_any = false;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
for (entry = qdict_first(bs->options); entry;
|
for (entry = qdict_first(bs->options); entry;
|
||||||
entry = qdict_next(bs->options, entry))
|
entry = qdict_next(bs->options, entry))
|
||||||
{
|
{
|
||||||
/* Only take options for this level */
|
/* Exclude options for children */
|
||||||
if (strchr(qdict_entry_key(entry), '.')) {
|
QLIST_FOREACH(child, &bs->children, next) {
|
||||||
|
if (strstart(qdict_entry_key(entry), child->name, &p)
|
||||||
|
&& (!*p || *p == '.'))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (child) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,6 +351,7 @@ extern const BdrvChildRole child_format;
|
|||||||
|
|
||||||
struct BdrvChild {
|
struct BdrvChild {
|
||||||
BlockDriverState *bs;
|
BlockDriverState *bs;
|
||||||
|
char *name;
|
||||||
const BdrvChildRole *role;
|
const BdrvChildRole *role;
|
||||||
QLIST_ENTRY(BdrvChild) next;
|
QLIST_ENTRY(BdrvChild) next;
|
||||||
QLIST_ENTRY(BdrvChild) next_parent;
|
QLIST_ENTRY(BdrvChild) next_parent;
|
||||||
|
Loading…
Reference in New Issue
Block a user