From patchwork Mon Apr 22 11:31:20 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 238493 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 234A32C013F for ; Mon, 22 Apr 2013 22:14:21 +1000 (EST) Received: from localhost ([::1]:45638 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UUF38-0002e4-O9 for incoming@patchwork.ozlabs.org; Mon, 22 Apr 2013 07:36:46 -0400 Received: from eggs.gnu.org ([208.118.235.92]:37108) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UUEyS-0004DG-MX for qemu-devel@nongnu.org; Mon, 22 Apr 2013 07:31:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UUEyQ-00023C-OK for qemu-devel@nongnu.org; Mon, 22 Apr 2013 07:31:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:62202) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UUEyQ-000238-Fq for qemu-devel@nongnu.org; Mon, 22 Apr 2013 07:31:54 -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 r3MBVrAA008223 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 22 Apr 2013 07:31:53 -0400 Received: from dhcp-200-207.str.redhat.com (ovpn-116-69.ams2.redhat.com [10.36.116.69]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r3MBVfDa031324; Mon, 22 Apr 2013 07:31:51 -0400 From: Kevin Wolf To: anthony@codemonkey.ws Date: Mon, 22 Apr 2013 13:31:20 +0200 Message-Id: <1366630294-18984-7-git-send-email-kwolf@redhat.com> In-Reply-To: <1366630294-18984-1-git-send-email-kwolf@redhat.com> References: <1366630294-18984-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, qemu-devel@nongnu.org Subject: [Qemu-devel] [PATCH 06/20] block: Add driver-specific options for backing files X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Options starting in "backing." are passed to the backing file now. If you don't need to specify the filename for the backing file, you can add it on the command line instead of in the image file: $ qemu-nbd -t /tmp/test.img $ qemu-img create -f qcow2 empty.qcow2 1G $ qemu-system-x86_64 -drive file=empty.qcow2,backing.file.driver=nbd,\ backing.file.host=localhost Note that this doesn't override the backing filename from the image. If the image has one, this will fail because NBD doesn't want the options and a filename at the same time. Signed-off-by: Kevin Wolf Reviewed-by: Eric Blake --- block.c | 27 +++++++++++++++++++++++---- block/mirror.c | 2 +- include/block/block.h | 2 +- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/block.c b/block.c index bea47c4..f717e1a 100644 --- a/block.c +++ b/block.c @@ -845,18 +845,33 @@ fail: return ret; } -int bdrv_open_backing_file(BlockDriverState *bs) +/* + * Opens the backing file for a BlockDriverState if not yet open + * + * options is a QDict of options to pass to the block drivers, or NULL for an + * empty set of options. The reference to the QDict is transferred to this + * function (even on failure), so if the caller intends to reuse the dictionary, + * it needs to use QINCREF() before calling bdrv_file_open. + */ +int bdrv_open_backing_file(BlockDriverState *bs, QDict *options) { char backing_filename[PATH_MAX]; int back_flags, ret; BlockDriver *back_drv = NULL; if (bs->backing_hd != NULL) { + QDECREF(options); return 0; } + /* NULL means an empty set of options */ + if (options == NULL) { + options = qdict_new(); + } + bs->open_flags &= ~BDRV_O_NO_BACKING; - if (bs->backing_file[0] == '\0') { + if (bs->backing_file[0] == '\0' && qdict_size(options) == 0) { + QDECREF(options); return 0; } @@ -871,7 +886,8 @@ int bdrv_open_backing_file(BlockDriverState *bs) /* backing files always opened read-only */ back_flags = bs->open_flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT); - ret = bdrv_open(bs->backing_hd, backing_filename, NULL, + ret = bdrv_open(bs->backing_hd, + *backing_filename ? backing_filename : NULL, options, back_flags, back_drv); if (ret < 0) { bdrv_delete(bs->backing_hd); @@ -1027,7 +1043,10 @@ int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, /* If there is a backing file, use it */ if ((flags & BDRV_O_NO_BACKING) == 0) { - ret = bdrv_open_backing_file(bs); + QDict *backing_options; + + extract_subqdict(options, &backing_options, "backing."); + ret = bdrv_open_backing_file(bs, backing_options); if (ret < 0) { goto close_and_fail; } diff --git a/block/mirror.c b/block/mirror.c index a62ad86..8b07dec 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -507,7 +507,7 @@ static void mirror_complete(BlockJob *job, Error **errp) MirrorBlockJob *s = container_of(job, MirrorBlockJob, common); int ret; - ret = bdrv_open_backing_file(s->target); + ret = bdrv_open_backing_file(s->target, NULL); if (ret < 0) { char backing_filename[PATH_MAX]; bdrv_get_full_backing_filename(s->target, backing_filename, diff --git a/include/block/block.h b/include/block/block.h index ebd9512..1251c5c 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -137,7 +137,7 @@ int bdrv_parse_cache_flags(const char *mode, int *flags); int bdrv_parse_discard_flags(const char *mode, int *flags); int bdrv_file_open(BlockDriverState **pbs, const char *filename, QDict *options, int flags); -int bdrv_open_backing_file(BlockDriverState *bs); +int bdrv_open_backing_file(BlockDriverState *bs, QDict *options); int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options, int flags, BlockDriver *drv); BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,