From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LRWNY-0002xO-9h for qemu-devel@nongnu.org; Mon, 26 Jan 2009 13:40:12 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LRWNT-0002ul-Ne for qemu-devel@nongnu.org; Mon, 26 Jan 2009 13:40:09 -0500 Received: from [199.232.76.173] (port=56394 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LRWNT-0002uX-8W for qemu-devel@nongnu.org; Mon, 26 Jan 2009 13:40:07 -0500 Received: from mx2.redhat.com ([66.187.237.31]:47783) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LRWNR-0005BD-IF for qemu-devel@nongnu.org; Mon, 26 Jan 2009 13:40:06 -0500 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n0QIe4G7029944 for ; Mon, 26 Jan 2009 13:40:04 -0500 From: Uri Lublin Date: Mon, 26 Jan 2009 20:39:58 +0200 Message-Id: <1232995199-12086-3-git-send-email-uril@redhat.com> In-Reply-To: <1232995199-12086-2-git-send-email-uril@redhat.com> References: <1232995199-12086-1-git-send-email-uril@redhat.com> <1232995199-12086-2-git-send-email-uril@redhat.com> Subject: [Qemu-devel] [PATCH 1/2] Introducing hidden image format in backing file name. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Uri Lublin The purpose of this patch is to 1. Provide a way to know the backing file format without probing it (setting the format at creation time). 2. Enable using qcow2 format (and others) over host block devices. (only if the user specifically asks for it, by providing the format). If no hidden format (or an unknown one) is provided we go back to probing. I call "hidden image format" to the following format of a backing file name: "name\0format". Although it can be considered a hack, that's an easy way to support old images with new qemu as well as old qemu with new images (in which case probing would be done), without changing the qcow2 header. Based on a previous patch from Shahar Frank. http://lists.gnu.org/archive/html/qemu-devel/2008-12/msg01083.html The "name\0format" was suggested by Kevin Wolf on the above thread. Also fixes a security flaw found by Daniel P. Berrange on that same thread which summarizes: "Autoprobing: just say no." Signed-off-by: Uri Lublin --- block-qcow2.c | 5 +++++ block.c | 27 ++++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletions(-) diff --git a/block-qcow2.c b/block-qcow2.c index 8a5b621..4b46b84 100644 --- a/block-qcow2.c +++ b/block-qcow2.c @@ -1499,6 +1499,11 @@ static int qcow_create(const char *filename, int64_t total_size, if (backing_file) { header.backing_file_offset = cpu_to_be64(header_size); backing_filename_len = strlen(backing_file); + + /* account for hidden format */ + if (backing_file[backing_filename_len + 1] != '\0') + backing_filename_len += strlen(backing_file + + backing_filename_len + 1) + 1; header.backing_file_size = cpu_to_be32(backing_filename_len); header_size += backing_filename_len; } diff --git a/block.c b/block.c index 50ec589..b43debc 100644 --- a/block.c +++ b/block.c @@ -254,6 +254,23 @@ static BlockDriver *find_protocol(const char *filename) return NULL; } +/* + * if a hidden file format exist, returns it's appropriate drv + * otherwise returns NULL + */ +static BlockDriver* get_backing_file_format(const char *filename) +{ + BlockDriver *drv = NULL; + int len; + + /* Support hidden format in filename: "name\0format\0" */ + len = strlen(filename); + if (filename[len + 1] != '\0') + drv = bdrv_find_format(filename + len + 1); + return drv; +} + + /* XXX: force raw format if block or character device ? It would simplify the BSD case */ static BlockDriver *find_image_format(const char *filename) @@ -263,6 +280,11 @@ static BlockDriver *find_image_format(const char *filename) uint8_t buf[2048]; BlockDriverState *bs; + /* first check for hidden format */ + drv = get_backing_file_format(filename); + if (drv) + return drv; + /* detect host devices. By convention, /dev/cdrom[N] is always recognized as a host CDROM */ if (strstart(filename, "/dev/cdrom", NULL)) @@ -423,6 +445,7 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, } #endif if (bs->backing_file[0] != '\0') { + BlockDriver *backing_drv ; /* if there is a backing file, use it */ bs->backing_hd = bdrv_new(""); if (!bs->backing_hd) { @@ -430,9 +453,11 @@ int bdrv_open2(BlockDriverState *bs, const char *filename, int flags, bdrv_close(bs); return -ENOMEM; } + backing_drv = get_backing_file_format(bs->backing_file); path_combine(backing_filename, sizeof(backing_filename), filename, bs->backing_file); - if (bdrv_open(bs->backing_hd, backing_filename, open_flags) < 0) + if (bdrv_open2(bs->backing_hd, backing_filename, open_flags, + backing_drv) < 0) goto fail; } -- 1.6.0.6