|
|
9ae3a8 |
From 26c4eb4923589b410b1aec705b8665afb5e78794 Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: Fam Zheng <famz@redhat.com>
|
|
|
9ae3a8 |
Date: Mon, 19 Aug 2013 18:54:27 +0800
|
|
|
9ae3a8 |
Subject: [PATCH 12/13] vmdk: support vmfsSparse files
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Message-id: <1377573001-27070-13-git-send-email-famz@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 53792
|
|
|
9ae3a8 |
O-Subject: [RHEL-7 qemu-kvm PATCH 12/13] vmdk: support vmfsSparse files
|
|
|
9ae3a8 |
Bugzilla: 995866
|
|
|
9ae3a8 |
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
VMware ESX hosts use a variant of the VMDK3 format, identified by the
|
|
|
9ae3a8 |
vmfsSparse create type ad the VMFSSPARSE extent type.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
It has 16 KB grain tables (L2) and a variable-size grain directory (L1).
|
|
|
9ae3a8 |
In addition, the grain size is always 512, but that is not a problem
|
|
|
9ae3a8 |
because it is included in the header.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
The format of the extents is documented in the VMDK spec. The format
|
|
|
9ae3a8 |
of the descriptor file is not documented precisely, but it can be
|
|
|
9ae3a8 |
found at http://kb.vmware.com/kb/10026353 (Recreating a missing virtual
|
|
|
9ae3a8 |
machine disk (VMDK) descriptor file for delta disks).
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
With these patches, vmfsSparse files only work if opened through the
|
|
|
9ae3a8 |
descriptor file. Data files without descriptor files, as far as I
|
|
|
9ae3a8 |
could understand, are not supported by ESX.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Fam Zheng <famz@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
v2: Rebase to patch 01.
|
|
|
9ae3a8 |
Change le64_to_cpu to le32_to_cpu.
|
|
|
9ae3a8 |
Rename vmdk_open_vmdk3 to vmdk_open_vmfs_sparse, which represents the
|
|
|
9ae3a8 |
current usage of this format.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Fam Zheng <famz@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
9ae3a8 |
(cherry picked from commit daac8fdc68c5f0118ce24fcac5873ddaa0d0c9f9)
|
|
|
9ae3a8 |
Signed-off-by: Fam Zheng <famz@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
block/vmdk.c | 17 +++++++++--------
|
|
|
9ae3a8 |
1 files changed, 9 insertions(+), 8 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/block/vmdk.c b/block/vmdk.c
|
|
|
9ae3a8 |
index 4997da4..4d0c82a 100644
|
|
|
9ae3a8 |
--- a/block/vmdk.c
|
|
|
9ae3a8 |
+++ b/block/vmdk.c
|
|
|
9ae3a8 |
@@ -481,9 +481,9 @@ static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
|
|
|
9ae3a8 |
return ret;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-static int vmdk_open_vmdk3(BlockDriverState *bs,
|
|
|
9ae3a8 |
- BlockDriverState *file,
|
|
|
9ae3a8 |
- int flags)
|
|
|
9ae3a8 |
+static int vmdk_open_vmfs_sparse(BlockDriverState *bs,
|
|
|
9ae3a8 |
+ BlockDriverState *file,
|
|
|
9ae3a8 |
+ int flags)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
int ret;
|
|
|
9ae3a8 |
uint32_t magic;
|
|
|
9ae3a8 |
@@ -674,7 +674,7 @@ static int vmdk_open_sparse(BlockDriverState *bs,
|
|
|
9ae3a8 |
magic = be32_to_cpu(magic);
|
|
|
9ae3a8 |
switch (magic) {
|
|
|
9ae3a8 |
case VMDK3_MAGIC:
|
|
|
9ae3a8 |
- return vmdk_open_vmdk3(bs, file, flags);
|
|
|
9ae3a8 |
+ return vmdk_open_vmfs_sparse(bs, file, flags);
|
|
|
9ae3a8 |
break;
|
|
|
9ae3a8 |
case VMDK4_MAGIC:
|
|
|
9ae3a8 |
return vmdk_open_vmdk4(bs, file, flags);
|
|
|
9ae3a8 |
@@ -718,7 +718,8 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
if (sectors <= 0 ||
|
|
|
9ae3a8 |
- (strcmp(type, "FLAT") && strcmp(type, "SPARSE")) ||
|
|
|
9ae3a8 |
+ (strcmp(type, "FLAT") && strcmp(type, "SPARSE") &&
|
|
|
9ae3a8 |
+ strcmp(type, "VMFSSPARSE")) ||
|
|
|
9ae3a8 |
(strcmp(access, "RW"))) {
|
|
|
9ae3a8 |
goto next_line;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
@@ -741,8 +742,8 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
|
|
9ae3a8 |
return ret;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
extent->flat_start_offset = flat_offset << 9;
|
|
|
9ae3a8 |
- } else if (!strcmp(type, "SPARSE")) {
|
|
|
9ae3a8 |
- /* SPARSE extent */
|
|
|
9ae3a8 |
+ } else if (!strcmp(type, "SPARSE") || !strcmp(type, "VMFSSPARSE")) {
|
|
|
9ae3a8 |
+ /* SPARSE extent and VMFSSPARSE extent are both "COWD" sparse file*/
|
|
|
9ae3a8 |
ret = vmdk_open_sparse(bs, extent_file, bs->open_flags);
|
|
|
9ae3a8 |
if (ret) {
|
|
|
9ae3a8 |
bdrv_delete(extent_file);
|
|
|
9ae3a8 |
@@ -789,6 +790,7 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
|
|
|
9ae3a8 |
goto exit;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
if (strcmp(ct, "monolithicFlat") &&
|
|
|
9ae3a8 |
+ strcmp(ct, "vmfsSparse") &&
|
|
|
9ae3a8 |
strcmp(ct, "twoGbMaxExtentSparse") &&
|
|
|
9ae3a8 |
strcmp(ct, "twoGbMaxExtentFlat")) {
|
|
|
9ae3a8 |
fprintf(stderr,
|
|
|
9ae3a8 |
@@ -1381,7 +1383,6 @@ static int coroutine_fn vmdk_co_write_zeroes(BlockDriverState *bs,
|
|
|
9ae3a8 |
return ret;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
-
|
|
|
9ae3a8 |
static int vmdk_create_extent(const char *filename, int64_t filesize,
|
|
|
9ae3a8 |
bool flat, bool compress, bool zeroed_grain)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.7.1
|
|
|
9ae3a8 |
|