|
|
958e1b |
From 6fb76589c86264784014d8b555dc9c479c534898 Mon Sep 17 00:00:00 2001
|
|
|
958e1b |
From: Jeffrey Cody <jcody@redhat.com>
|
|
|
958e1b |
Date: Tue, 27 May 2014 19:05:11 +0200
|
|
|
958e1b |
Subject: [PATCH 07/13] block: vhdx - account for identical header sections
|
|
|
958e1b |
MIME-Version: 1.0
|
|
|
958e1b |
Content-Type: text/plain; charset=UTF-8
|
|
|
958e1b |
Content-Transfer-Encoding: 8bit
|
|
|
958e1b |
|
|
|
958e1b |
RH-Author: Jeffrey Cody <jcody@redhat.com>
|
|
|
958e1b |
Message-id: <6a956eaa23796489845aaf8b0ef8aa390014e98b.1401217451.git.jcody@redhat.com>
|
|
|
958e1b |
Patchwork-id: 59040
|
|
|
958e1b |
O-Subject: [PATCH qemu-kvm RHEL7.1] block: vhdx - account for identical header sections
|
|
|
958e1b |
Bugzilla: 1097020
|
|
|
958e1b |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
958e1b |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
958e1b |
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
958e1b |
|
|
|
958e1b |
The VHDX spec v1.00 declares that "a header is current if it is the only
|
|
|
958e1b |
valid header or if it is valid and its SequenceNumber field is greater
|
|
|
958e1b |
than the other header’s SequenceNumber field. The parser must only use
|
|
|
958e1b |
data from the current header. If there is no current header, then the
|
|
|
958e1b |
VHDX file is corrupt."
|
|
|
958e1b |
|
|
|
958e1b |
However, the Disk2VHD tool from Microsoft creates a VHDX image file that
|
|
|
958e1b |
has 2 identical headers, including matching checksums and matching
|
|
|
958e1b |
sequence numbers. Likely, as a shortcut the tool is just writing the
|
|
|
958e1b |
header twice, for the active and inactive headers, during the image
|
|
|
958e1b |
creation. Technically, this should be considered a corrupt VHDX file
|
|
|
958e1b |
(at least per the 1.00 spec, and that is how we currently treat it).
|
|
|
958e1b |
|
|
|
958e1b |
But in order to accomodate images created with Disk2VHD, we can safely
|
|
|
958e1b |
create an exception for this case. If we find identical sequence
|
|
|
958e1b |
numbers, then we check the VHDXHeader-sized chunks of each 64KB header
|
|
|
958e1b |
sections (we won't rely just on the crc32c to indicate the headers are
|
|
|
958e1b |
the same). If they are identical, then we go ahead and use the first
|
|
|
958e1b |
one.
|
|
|
958e1b |
|
|
|
958e1b |
Reported-by: Nerijus Baliūnas <nerijus@users.sourceforge.net>
|
|
|
958e1b |
Signed-off-by: Jeff Cody <jcody@redhat.com>
|
|
|
958e1b |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
958e1b |
(cherry picked from commit 6906046169ffa9d829beeeaafe1fadeba51669fb)
|
|
|
958e1b |
|
|
|
958e1b |
Conflicts:
|
|
|
958e1b |
block/vhdx.c
|
|
|
958e1b |
|
|
|
958e1b |
Signed-off-by: Jeff Cody <jcody@redhat.com>
|
|
|
958e1b |
---
|
|
|
958e1b |
Brew: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=7505809
|
|
|
958e1b |
BZ: 1097020
|
|
|
958e1b |
|
|
|
958e1b |
Conflict notes: the conflict was with the ret value; current upstream
|
|
|
958e1b |
removed that in favor of passing in errp to the function
|
|
|
958e1b |
|
|
|
958e1b |
block/vhdx.c | 11 +++++++++--
|
|
|
958e1b |
1 file changed, 9 insertions(+), 2 deletions(-)
|
|
|
958e1b |
|
|
|
958e1b |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
958e1b |
---
|
|
|
958e1b |
block/vhdx.c | 11 +++++++++--
|
|
|
958e1b |
1 files changed, 9 insertions(+), 2 deletions(-)
|
|
|
958e1b |
|
|
|
958e1b |
diff --git a/block/vhdx.c b/block/vhdx.c
|
|
|
958e1b |
index 66a25c9..21ad6ad 100644
|
|
|
958e1b |
--- a/block/vhdx.c
|
|
|
958e1b |
+++ b/block/vhdx.c
|
|
|
958e1b |
@@ -473,8 +473,15 @@ static int vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s)
|
|
|
958e1b |
} else if (h2_seq > h1_seq) {
|
|
|
958e1b |
s->curr_header = 1;
|
|
|
958e1b |
} else {
|
|
|
958e1b |
- ret = -EINVAL;
|
|
|
958e1b |
- goto fail;
|
|
|
958e1b |
+ /* The Microsoft Disk2VHD tool will create 2 identical
|
|
|
958e1b |
+ * headers, with identical sequence numbers. If the headers are
|
|
|
958e1b |
+ * identical, don't consider the file corrupt */
|
|
|
958e1b |
+ if (!memcmp(header1, header2, sizeof(VHDXHeader))) {
|
|
|
958e1b |
+ s->curr_header = 0;
|
|
|
958e1b |
+ } else {
|
|
|
958e1b |
+ ret = -EINVAL;
|
|
|
958e1b |
+ goto fail;
|
|
|
958e1b |
+ }
|
|
|
958e1b |
}
|
|
|
958e1b |
}
|
|
|
958e1b |
|
|
|
958e1b |
--
|
|
|
958e1b |
1.7.1
|
|
|
958e1b |
|