From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:34719) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UHdnD-0000Ox-JC for qemu-devel@nongnu.org; Mon, 18 Mar 2013 13:24:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UHdn8-0004UY-GS for qemu-devel@nongnu.org; Mon, 18 Mar 2013 13:24:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33877) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UHdn8-0004UP-8G for qemu-devel@nongnu.org; Mon, 18 Mar 2013 13:24:10 -0400 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r2IHO940012690 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 18 Mar 2013 13:24:09 -0400 From: Kevin Wolf Date: Mon, 18 Mar 2013 18:23:52 +0100 Message-Id: <1363627441-8297-3-git-send-email-kwolf@redhat.com> In-Reply-To: <1363627441-8297-1-git-send-email-kwolf@redhat.com> References: <1363627441-8297-1-git-send-email-kwolf@redhat.com> Subject: [Qemu-devel] [PATCH 02/11] block: Pass bdrv_file_open() options to block drivers List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, pbonzini@redhat.com Specify -drive file.option=... on the command line to pass the option to the protocol instead of the format driver. Signed-off-by: Kevin Wolf --- block.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/block.c b/block.c index 5f4859e..9bc9bf3 100644 --- a/block.c +++ b/block.c @@ -676,7 +676,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file, assert(drv != NULL); assert(bs->file == NULL); - assert(options == NULL || bs->options != options); + assert(options != NULL && bs->options != options); trace_bdrv_open_common(bs, filename, flags, drv->format_name); @@ -755,22 +755,48 @@ int bdrv_file_open(BlockDriverState **pbs, const char *filename, BlockDriver *drv; int ret; - QDECREF(options); - drv = bdrv_find_protocol(filename); if (!drv) { + QDECREF(options); return -ENOENT; } + /* NULL means an empty set of options */ + if (options == NULL) { + options = qdict_new(); + } + bs = bdrv_new(""); - ret = bdrv_open_common(bs, NULL, filename, NULL, flags, drv); + bs->options = options; + options = qdict_clone_shallow(options); + + ret = bdrv_open_common(bs, NULL, filename, options, flags, drv); if (ret < 0) { - bdrv_delete(bs); - return ret; + goto fail; + } + + /* Check if any unknown options were used */ + if (qdict_size(options) != 0) { + const QDictEntry *entry = qdict_first(options); + qerror_report(ERROR_CLASS_GENERIC_ERROR, "Block protocol '%s' doesn't " + "support the option '%s'", + drv->format_name, entry->key); + ret = -EINVAL; + goto fail; } + QDECREF(options); + bs->growable = 1; *pbs = bs; return 0; + +fail: + QDECREF(options); + if (!bs->drv) { + QDECREF(bs->options); + } + bdrv_delete(bs); + return ret; } int bdrv_open_backing_file(BlockDriverState *bs) @@ -810,6 +836,25 @@ int bdrv_open_backing_file(BlockDriverState *bs) return 0; } +static void extract_subqdict(QDict *src, QDict **dst, const char *start) +{ + const QDictEntry *entry, *next; + const char *p; + + *dst = qdict_new(); + entry = qdict_first(src); + + while (entry != NULL) { + next = qdict_next(src, entry); + if (strstart(entry->key, start, &p)) { + qobject_incref(entry->value); + qdict_put_obj(*dst, p, entry->value); + qdict_del(src, entry->key); + } + entry = next; + } +} + /* * Opens a disk image (raw, qcow2, vmdk, ...) * @@ -825,6 +870,7 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ char tmp_filename[PATH_MAX + 1]; BlockDriverState *file = NULL; + QDict *file_options = NULL; /* NULL means an empty set of options */ if (options == NULL) { @@ -896,7 +942,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, flags |= BDRV_O_ALLOW_RDWR; } - ret = bdrv_file_open(&file, filename, NULL, bdrv_open_flags(bs, flags)); + extract_subqdict(options, &file_options, "file."); + + ret = bdrv_file_open(&file, filename, file_options, + bdrv_open_flags(bs, flags)); if (ret < 0) { goto fail; } -- 1.8.1.4