Patchwork [2/2] VMDK4: Parse and check the createType (VMDK file type) field.

login
register
mail settings
Submitter Richard W.M. Jones
Date Dec. 18, 2009, 4:07 p.m.
Message ID <20091218160710.GB28180@amd.home.annexia.org>
Download mbox | patch
Permalink /patch/41418/
State New
Headers show

Comments

Richard W.M. Jones - Dec. 18, 2009, 4:07 p.m.
Add Signed-off-by line.

Rich.

Patch

diff --git a/block/vmdk.c b/block/vmdk.c
index 0f59ea5..4cb126b 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -81,6 +81,7 @@  typedef struct BDRVVmdkState {
     /* VMDK4 fields */
     int64_t cid_offset;
     int64_t parent_cid_offset;
+    char *create_type;
 } BDRVVmdkState;
 
 typedef struct VmdkMetaData {
@@ -161,6 +162,13 @@  static int vmdk4_parse_desc_assignment(BlockDriverState *bs,
     if (!strncmp(p, "parentCID=", 10))
         s->parent_cid_offset = file_offset + 10;
 
+    if (strncmp(p, "createType=\"", 12) == 0) {
+        p[len-1] = '\0';        /* Remove trailing double quote. */
+        if (s->create_type)
+            qemu_free(s->create_type);
+        s->create_type = qemu_strdup(p+12);
+    }
+
     return 0;
 }
 
@@ -174,6 +182,7 @@  static int vmdk4_parse_desc(BlockDriverState *bs, VMDK4Header *header)
 
     s->cid_offset = 0;
     s->parent_cid_offset = 0;
+    s->create_type = NULL;
 
     /* Stored in the header are the offset/size in sectors. */
     desc_size = le64_to_cpu(header->desc_size) * SECTOR_SIZE;
@@ -522,6 +531,16 @@  static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
         if (vmdk4_parse_desc(bs, &header) == -1)
             goto fail;
 
+        if (s->create_type &&
+            !(!strcmp(s->create_type, "monolithicSparse") ||
+              !strcmp(s->create_type, "monolithicFlat") ||
+              !strcmp(s->create_type, "twoGbMaxExtentSparse") ||
+              !strcmp(s->create_type, "twoGbMaxExtentFlat"))) {
+            fprintf (stderr, "vmdk: disk type '%s' is not supported by qemu\n",
+                     s->create_type);
+            goto fail;
+        }
+
         if (parent_open)
             s->is_parent = 1;
         else
@@ -560,6 +579,7 @@  static int vmdk_open(BlockDriverState *bs, const char *filename, int flags)
     qemu_free(s->l1_backup_table);
     qemu_free(s->l1_table);
     qemu_free(s->l2_cache);
+    qemu_free(s->create_type);
     bdrv_delete(s->hd);
     return -1;
 }
@@ -928,6 +948,7 @@  static void vmdk_close(BlockDriverState *bs)
 
     qemu_free(s->l1_table);
     qemu_free(s->l2_cache);
+    qemu_free(s->create_type);
     // try to close parent image, if exist
     vmdk_parent_close(s->hd);
     bdrv_delete(s->hd);