From patchwork Thu Nov 6 12:54:36 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Denis V. Lunev" X-Patchwork-Id: 407443 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 8ED961400A8 for ; Thu, 6 Nov 2014 23:58:12 +1100 (AEDT) Received: from localhost ([::1]:52685 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XmMde-0007aZ-Qn for incoming@patchwork.ozlabs.org; Thu, 06 Nov 2014 07:58:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59565) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XmMYf-0007oQ-Q8 for qemu-devel@nongnu.org; Thu, 06 Nov 2014 07:53:06 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XmMYY-00050D-Le for qemu-devel@nongnu.org; Thu, 06 Nov 2014 07:53:01 -0500 Received: from mailhub.sw.ru ([195.214.232.25]:44853 helo=relay.sw.ru) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XmMYV-0004uC-6Q for qemu-devel@nongnu.org; Thu, 06 Nov 2014 07:52:54 -0500 Received: from hades.sw.ru ([10.30.8.132]) by relay.sw.ru (8.13.4/8.13.4) with ESMTP id sA6CqJSY030627; Thu, 6 Nov 2014 16:52:28 +0400 (MSK) From: "Denis V. Lunev" To: Date: Thu, 6 Nov 2014 15:54:36 +0300 Message-Id: <1415278478-19384-6-git-send-email-den@openvz.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1415278478-19384-1-git-send-email-den@openvz.org> References: <1415278478-19384-1-git-send-email-den@openvz.org> X-detected-operating-system: by eggs.gnu.org: OpenBSD 3.x X-Received-From: 195.214.232.25 Cc: Kevin Wolf , "Denis V. Lunev" , qemu-devel@nongnu.org, Stefan Hajnoczi Subject: [Qemu-devel] [PATCH 5/7] block/parallels: support padded Parallels images X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Unfortunately, old guest OSes do not align partitions to page size by default. This is true for Windows 2003 and Windows XP. For the time being Parallels was created an optimization for such OSes in its desktop product. Desktop users are not qualified enough to create properly aligned installations. Thus Parallels makes a blind guess on a customer behalf and creates so-called "padded" images if guest OS type is specified as WinXP, Win2k and Win2k3. "Padding" is a value which should be added to guest LBA to obtain sector number inside the image. This results in a shifted images. 0123 offset inside image (in 512 byte sectors) +------- +.012 guest data (512 byte sectors) +------- The information about this is available in DiskDescriptor.xml ONLY. There is no such data in the image header. There share of such images could be evaluated as 6-8% according to the statistics in my hands. This patch obtains proper value from XML and applies it on reading. Signed-off-by: Denis V. Lunev Acked-by: Roman Kagan Reviewed-by: Jeff Cody CC: Kevin Wolf CC: Stefan Hajnoczi --- block/parallels.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/block/parallels.c b/block/parallels.c index 4a8240d..b27d1ea 100644 --- a/block/parallels.c +++ b/block/parallels.c @@ -63,6 +63,7 @@ typedef struct BDRVParallelsState { unsigned int tracks; unsigned int off_multiplier; + unsigned int padding; } BDRVParallelsState; @@ -245,6 +246,7 @@ static int parallels_open_xml(BlockDriverState *bs, int flags, Error **errp) const char *data; char image_path[PATH_MAX]; Error *local_err = NULL; + BDRVParallelsState *s = bs->opaque; ret = size = bdrv_getlength(bs->file); if (ret < 0) { @@ -274,6 +276,19 @@ static int parallels_open_xml(BlockDriverState *bs, int flags, Error **errp) if (root == NULL) { goto fail; } + + data = xml_get_text(root, "Disk_Parameters", "Padding", NULL); + if (data != NULL) { + char *endptr; + unsigned long pad; + + pad = strtoul(data, &endptr, 0); + if ((endptr != NULL && *endptr != '\0') || pad > UINT_MAX) { + goto fail; + } + s->padding = (uint32_t)pad; + } + image = xml_seek(root, "StorageData", "Storage", "Image", NULL); data = ""; /* make gcc happy */ for (size = 0; image != NULL; image = image->next) { @@ -375,6 +390,10 @@ static int64_t seek_to_sector(BlockDriverState *bs, int64_t sector_num) static int parallels_read(BlockDriverState *bs, int64_t sector_num, uint8_t *buf, int nb_sectors) { + BDRVParallelsState *s = bs->opaque; + + sector_num += s->padding; + while (nb_sectors > 0) { int64_t position = seek_to_sector(bs, sector_num); if (position >= 0) {