qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 1/2] Introducing hidden image format in backing file


From: Uri Lublin
Subject: [Qemu-devel] [PATCH 1/2] Introducing hidden image format in backing file name.
Date: Mon, 26 Jan 2009 20:39:57 +0200

The purpose of this patches is to keep the backing file format together
with its name, 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).

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.

If a hidden format exists, use it for the backing file.
If no hidden format (or an unknown one) exists we go back to probing.

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 <address@hidden>
---
 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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]