|
|
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 |
|