yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone
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