@@ -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);