From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58732) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1a9wdi-0000Ng-BJ for qemu-devel@nongnu.org; Fri, 18 Dec 2015 10:08:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1a9wdh-0004K6-7g for qemu-devel@nongnu.org; Fri, 18 Dec 2015 10:08:14 -0500 From: Kevin Wolf Date: Fri, 18 Dec 2015 16:07:15 +0100 Message-Id: <1450451274-7472-10-git-send-email-kwolf@redhat.com> In-Reply-To: <1450451274-7472-1-git-send-email-kwolf@redhat.com> References: <1450451274-7472-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PULL 09/48] block: Exclude nested options only for children in append_open_options() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: kwolf@redhat.com, qemu-devel@nongnu.org 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 Reviewed-by: Max Reitz --- block.c | 20 ++++++++++++++++---- include/block/block_int.h | 1 + 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/block.c b/block.c index 0cc3c8b..fa351ac 100644 --- a/block.c +++ b/block.c @@ -1101,11 +1101,13 @@ static int bdrv_fill_options(QDict **options, const char **pfilename, static BdrvChild *bdrv_attach_child(BlockDriverState *parent_bs, BlockDriverState *child_bs, + const char *child_name, const BdrvChildRole *child_role) { BdrvChild *child = g_new(BdrvChild, 1); *child = (BdrvChild) { .bs = child_bs, + .name = g_strdup(child_name), .role = child_role, }; @@ -1119,6 +1121,7 @@ static void bdrv_detach_child(BdrvChild *child) { QLIST_REMOVE(child, next); QLIST_REMOVE(child, next_parent); + g_free(child->name); g_free(child); } @@ -1165,7 +1168,7 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd) bs->backing = NULL; 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; pstrcpy(bs->backing_file, sizeof(bs->backing_file), backing_hd->filename); pstrcpy(bs->backing_format, sizeof(bs->backing_format), @@ -1321,7 +1324,7 @@ BdrvChild *bdrv_open_child(const char *filename, goto done; } - c = bdrv_attach_child(parent, bs, child_role); + c = bdrv_attach_child(parent, bs, bdref_key, child_role); done: qdict_del(options, bdref_key); @@ -3951,13 +3954,22 @@ static bool append_open_options(QDict *d, BlockDriverState *bs) { const QDictEntry *entry; QemuOptDesc *desc; + BdrvChild *child; bool found_any = false; + const char *p; for (entry = qdict_first(bs->options); entry; entry = qdict_next(bs->options, entry)) { - /* Only take options for this level */ - if (strchr(qdict_entry_key(entry), '.')) { + /* Exclude options for children */ + QLIST_FOREACH(child, &bs->children, next) { + if (strstart(qdict_entry_key(entry), child->name, &p) + && (!*p || *p == '.')) + { + break; + } + } + if (child) { continue; } diff --git a/include/block/block_int.h b/include/block/block_int.h index c2ce965..0284f81 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -351,6 +351,7 @@ extern const BdrvChildRole child_format; struct BdrvChild { BlockDriverState *bs; + char *name; const BdrvChildRole *role; QLIST_ENTRY(BdrvChild) next; QLIST_ENTRY(BdrvChild) next_parent; -- 1.8.3.1