qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH] block:Fix FIXED base vpc be probed to raw format


From: Xiaodong Gong
Subject: [Qemu-devel] [PATCH] block:Fix FIXED base vpc be probed to raw format
Date: Sun, 8 Feb 2015 20:39:52 +0800

When open the vpc snapshot based FIXED format, its backing file,
this FIXED vpc image, could be probed as a raw image, because that
the find_image_format just checkout the first sector.

Add a re-probe for the last sector to FIXED base vpc image,when get
a NULL or raw driver in first sector probe.

Signed-off-by: Xiaodong Gong <address@hidden>
---
 block.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 48 insertions(+), 7 deletions(-)

diff --git a/block.c b/block.c
index d45e4dd..e183515 100644
--- a/block.c
+++ b/block.c
@@ -702,20 +702,24 @@ BlockDriver *bdrv_probe_all(const uint8_t *buf, int 
buf_size,
     return drv;
 }
 
-static int find_image_format(BlockDriverState *bs, const char *filename,
-                             BlockDriver **pdrv, Error **errp)
+static int probe_image_format(BlockDriverState *bs, const char *filename,
+                              int64_t offset, BlockDriver **pdrv, Error **errp,
+                              bool isfoot)
 {
     BlockDriver *drv;
     uint8_t buf[BLOCK_PROBE_BUF_SIZE];
     int ret = 0;
 
-    /* Return the raw BlockDriver * to scsi-generic devices or empty drives */
-    if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) {
-        *pdrv = &bdrv_raw;
+    if (!bs || !filename) {
+        *pdrv = NULL;
         return ret;
     }
 
-    ret = bdrv_pread(bs, 0, buf, sizeof(buf));
+    if (offset + sizeof(buf) > bs->total_sectors << BDRV_SECTOR_BITS) {
+        return ret;
+    }
+
+    ret = bdrv_pread(bs, offset, buf, sizeof(buf));
     if (ret < 0) {
         error_setg_errno(errp, -ret, "Could not read image for determining its 
"
                          "format");
@@ -724,12 +728,49 @@ static int find_image_format(BlockDriverState *bs, const 
char *filename,
     }
 
     drv = bdrv_probe_all(buf, ret, filename);
-    if (!drv) {
+    if (!drv && isfoot) {
         error_setg(errp, "Could not determine image format: No compatible "
                    "driver found");
         ret = -ENOENT;
     }
     *pdrv = drv;
+
+    return ret;
+}
+
+static int find_image_format(BlockDriverState *bs, const char *filename,
+                             BlockDriver **pdrv, Error **errp)
+{
+    int last_sector_offset;
+    int ret = 0;
+
+    *pdrv = NULL;
+
+    /* Return the raw BlockDriver * to scsi-generic devices or empty drives */
+    if (bs->sg || !bdrv_is_inserted(bs) || bdrv_getlength(bs) == 0) {
+        *pdrv = &bdrv_raw;
+        return ret;
+    }
+
+    /* probe the header to guess image format */
+    ret = probe_image_format(bs, filename, 0, pdrv, errp, false);
+    if (ret < 0) {
+        return ret;
+    }
+
+    /* The FIXED base img of VHD only has the footer in tail. The drv could
+     * be NULL or raw */
+    if (*pdrv && *pdrv != &bdrv_raw) {
+        return ret;
+    }
+
+    last_sector_offset = (bs->total_sectors - 1) << BDRV_SECTOR_BITS;
+    ret = probe_image_format(bs, filename, last_sector_offset, pdrv,
+        errp, true);
+    if (ret < 0) {
+        return ret;
+    }
+
     return ret;
 }
 
-- 
1.8.3.1




reply via email to

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