958e1b
From feb051e6d8bc62e6b9e162ada4dc576c59edc00f Mon Sep 17 00:00:00 2001
958e1b
Message-Id: <feb051e6d8bc62e6b9e162ada4dc576c59edc00f.1418766606.git.jen@redhat.com>
958e1b
In-Reply-To: <6f81b4847eb68ebdf54a8f1a771e19d112d74152.1418766606.git.jen@redhat.com>
958e1b
References: <6f81b4847eb68ebdf54a8f1a771e19d112d74152.1418766606.git.jen@redhat.com>
958e1b
From: Fam Zheng <famz@redhat.com>
958e1b
Date: Thu, 4 Dec 2014 00:05:06 -0600
958e1b
Subject: [CHANGE 12/31] vmdk: push vmdk_read_desc up to caller
958e1b
To: rhvirt-patches@redhat.com,
958e1b
    jen@redhat.com
958e1b
958e1b
RH-Author: Fam Zheng <famz@redhat.com>
958e1b
Message-id: <1417651524-18041-13-git-send-email-famz@redhat.com>
958e1b
Patchwork-id: 62685
958e1b
O-Subject: [RHEL-7.1 qemu-kvm PATCH v5 12/30] vmdk: push vmdk_read_desc up to caller
958e1b
Bugzilla: 1134251
958e1b
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
958e1b
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
958e1b
RH-Acked-by: Max Reitz <mreitz@redhat.com>
958e1b
958e1b
From: Paolo Bonzini <pbonzini@redhat.com>
958e1b
958e1b
Currently, we just try reading a VMDK file as both image and descriptor.
958e1b
This makes it hard to choose which of the two attempts gave the best error.
958e1b
We'll decide in advance if the file looks like an image or a descriptor,
958e1b
and this patch is the first step to that end.
958e1b
958e1b
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
958e1b
Reviewed-by: Fam Zheng <famz@redhat.com>
958e1b
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
958e1b
(cherry picked from commit d1833ef52be349e41d17e9c5ddaea8bb4ad3a7fb)
958e1b
Signed-off-by: Fam Zheng <famz@redhat.com>
958e1b
Signed-off-by: Jeff E. Nelson <jen@redhat.com>
958e1b
---
958e1b
 block/vmdk.c | 55 +++++++++++++++++++++++++++++++------------------------
958e1b
 1 file changed, 31 insertions(+), 24 deletions(-)
958e1b
958e1b
diff --git a/block/vmdk.c b/block/vmdk.c
958e1b
index 425064c..458bceb 100644
958e1b
--- a/block/vmdk.c
958e1b
+++ b/block/vmdk.c
958e1b
@@ -526,8 +526,8 @@ static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
958e1b
     return ret;
958e1b
 }
958e1b
 
958e1b
-static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
958e1b
-                               uint64_t desc_offset, Error **errp);
958e1b
+static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
958e1b
+                               Error **errp);
958e1b
 
958e1b
 static char *vmdk_read_desc(BlockDriverState *file, uint64_t desc_offset,
958e1b
                             Error **errp)
958e1b
@@ -576,7 +576,13 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
958e1b
     if (header.capacity == 0) {
958e1b
         uint64_t desc_offset = le64_to_cpu(header.desc_offset);
958e1b
         if (desc_offset) {
958e1b
-            return vmdk_open_desc_file(bs, flags, desc_offset << 9, errp);
958e1b
+            char *buf = vmdk_read_desc(file, desc_offset << 9, errp);
958e1b
+            if (!buf) {
958e1b
+                return -EINVAL;
958e1b
+            }
958e1b
+            ret = vmdk_open_desc_file(bs, flags, buf, errp);
958e1b
+            g_free(buf);
958e1b
+            return ret;
958e1b
         }
958e1b
     }
958e1b
 
958e1b
@@ -727,16 +733,12 @@ static int vmdk_parse_description(const char *desc, const char *opt_name,
958e1b
 
958e1b
 /* Open an extent file and append to bs array */
958e1b
 static int vmdk_open_sparse(BlockDriverState *bs,
958e1b
-                            BlockDriverState *file,
958e1b
-                            int flags, Error **errp)
958e1b
+                            BlockDriverState *file, int flags,
958e1b
+                            char *buf, Error **errp)
958e1b
 {
958e1b
     uint32_t magic;
958e1b
 
958e1b
-    if (bdrv_pread(file, 0, &magic, sizeof(magic)) != sizeof(magic)) {
958e1b
-        return -EIO;
958e1b
-    }
958e1b
-
958e1b
-    magic = be32_to_cpu(magic);
958e1b
+    magic = ldl_be_p(buf);
958e1b
     switch (magic) {
958e1b
         case VMDK3_MAGIC:
958e1b
             return vmdk_open_vmfs_sparse(bs, file, flags, errp);
958e1b
@@ -821,8 +823,14 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
958e1b
             extent->flat_start_offset = flat_offset << 9;
958e1b
         } else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
958e1b
             /* SPARSE extent and VMFSSPARSE extent are both "COWD" sparse file*/
958e1b
-            ret = vmdk_open_sparse(bs, extent_file, bs->open_flags, errp);
958e1b
+            char *buf = vmdk_read_desc(extent_file, 0, errp);
958e1b
+            if (!buf) {
958e1b
+                ret = -EINVAL;
958e1b
+            } else {
958e1b
+                ret = vmdk_open_sparse(bs, extent_file, bs->open_flags, buf, errp);
958e1b
+            }
958e1b
             if (ret) {
958e1b
+                g_free(buf);
958e1b
                 bdrv_unref(extent_file);
958e1b
                 return ret;
958e1b
             }
958e1b
@@ -845,20 +853,13 @@ next_line:
958e1b
     return 0;
958e1b
 }
958e1b
 
958e1b
-static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
958e1b
-                               uint64_t desc_offset, Error **errp)
958e1b
+static int vmdk_open_desc_file(BlockDriverState *bs, int flags, char *buf,
958e1b
+                               Error **errp)
958e1b
 {
958e1b
     int ret;
958e1b
-    char *buf;
958e1b
     char ct[128];
958e1b
     BDRVVmdkState *s = bs->opaque;
958e1b
 
958e1b
-    buf = vmdk_read_desc(bs->file, desc_offset, errp);
958e1b
-    if (!buf) {
958e1b
-        return -EINVAL;
958e1b
-        goto exit;
958e1b
-    }
958e1b
-
958e1b
     if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) {
958e1b
         error_setg(errp, "invalid VMDK image descriptor");
958e1b
         ret = -EINVAL;
958e1b
@@ -877,20 +878,25 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
958e1b
     s->desc_offset = 0;
958e1b
     ret = vmdk_parse_extents(buf, bs, bs->file->filename, errp);
958e1b
 exit:
958e1b
-    g_free(buf);
958e1b
     return ret;
958e1b
 }
958e1b
 
958e1b
 static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
958e1b
                      Error **errp)
958e1b
 {
958e1b
+    char *buf = NULL;
958e1b
     int ret;
958e1b
     BDRVVmdkState *s = bs->opaque;
958e1b
 
958e1b
-    if (vmdk_open_sparse(bs, bs->file, flags, errp) == 0) {
958e1b
+    buf = vmdk_read_desc(bs->file, 0, errp);
958e1b
+    if (!buf) {
958e1b
+        return -EINVAL;
958e1b
+    }
958e1b
+
958e1b
+    if (vmdk_open_sparse(bs, bs->file, flags, buf, errp) == 0) {
958e1b
         s->desc_offset = 0x200;
958e1b
     } else {
958e1b
-        ret = vmdk_open_desc_file(bs, flags, 0, errp);
958e1b
+        ret = vmdk_open_desc_file(bs, flags, buf, errp);
958e1b
         if (ret) {
958e1b
             goto fail;
958e1b
         }
958e1b
@@ -909,10 +915,11 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
958e1b
               QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
958e1b
               "vmdk", bs->device_name, "live migration");
958e1b
     migrate_add_blocker(s->migration_blocker);
958e1b
-
958e1b
+    g_free(buf);
958e1b
     return 0;
958e1b
 
958e1b
 fail:
958e1b
+    g_free(buf);
958e1b
     g_free(s->create_type);
958e1b
     s->create_type = NULL;
958e1b
     vmdk_free_extents(bs);
958e1b
-- 
958e1b
2.1.0
958e1b