Hello community,

here is the log from the commit of package virt-utils for openSUSE:Factory 
checked in at 2012-02-08 15:43:58
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/virt-utils (Old)
 and      /work/SRC/openSUSE:Factory/.virt-utils.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "virt-utils", Maintainer is "[email protected]"

Changes:
--------
--- /work/SRC/openSUSE:Factory/virt-utils/virt-utils.changes    2011-10-29 
08:01:38.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.virt-utils.new/virt-utils.changes       
2012-02-08 15:43:59.000000000 +0100
@@ -1,0 +2,16 @@
+Tue Feb  7 15:20:38 MST 2012 - [email protected]
+
+- vpc: Round up image size during fixed image creation 
+
+-------------------------------------------------------------------
+Wed Feb  1 15:41:37 UTC 2012 - [email protected]
+
+- add python to BuildRequires (fixes build on openSUSE 11.4 and SLE 11)
+
+-------------------------------------------------------------------
+Tue Jan 31 10:19:27 MST 2012 - [email protected]
+
+- fate#309765: Create images that can be run on Microsoft Hyper-V host 
+  qemu-img-vpc-fixed-disk.patch
+
+-------------------------------------------------------------------
@@ -4,2 +20,8 @@
-- Fix vpc file format.  The data offset field in the Dynamic Disk
-  Header was not correctly initialized.
+- fate#309765: Create images that can be run on Microsoft Hyper-V host
+  Fixes vpc file format data offset field in the Dynamic Disk Header
+  qemu-img-git-vpc-fix.patch
+
+-------------------------------------------------------------------
+Mon Aug  8 19:56:32 UTC 2011 - [email protected]
+
+- update to qemu version 0.15.0

Old:
----
  qemu-img-vpc.patch

New:
----
  qemu-img-git-vpc-fix.patch
  qemu-img-vpc-fixed-disk.patch
  qemu-img-vpc-roundup-fix.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ virt-utils.spec ++++++
--- /var/tmp/diff_new_pack.50SnZH/_old  2012-02-08 15:44:01.000000000 +0100
+++ /var/tmp/diff_new_pack.50SnZH/_new  2012-02-08 15:44:01.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package virt-utils
 #
-# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -15,25 +15,26 @@
 # Please submit bugfixes or comments via http://bugs.opensuse.org/
 #
 
-# norootforbuild
-
 %define qemu_utils 1
 %define internal_utils 1
 %define provide_duplicated_binaries 0
 
 Name:           virt-utils
-BuildRequires:  zlib-devel
 BuildRequires:  glib2-devel
+BuildRequires:  python
+BuildRequires:  zlib-devel
 Version:        1.1.7
-Release:        1
+Release:        0
+Summary:        Virtualization Utilities
 License:        GPL-2.0
 Group:          System/Kernel
-Summary:        Virtualization Utilities
 # git commit id for following rc0 release: b8095f2
 Source0:        qemu-0.15.0.tar.bz2
 Source1:        vm-snapshot-disk
 Patch1:         qemu-img-vmdk-scsi.patch
-Patch2:         qemu-img-vpc.patch
+Patch2:         qemu-img-git-vpc-fix.patch
+Patch3:         qemu-img-vpc-fixed-disk.patch
+Patch4:         qemu-img-vpc-roundup-fix.patch
 Url:            http://www.qemu.org/
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 
@@ -59,6 +60,8 @@
 %setup -q -n qemu-0.15.0
 %patch1 -p1
 %patch2 -p1
+%patch3 -p1
+%patch4 -p1
 %endif
 
 %build

++++++ qemu-0.15.0.tar.bz2 ++++++
/work/SRC/openSUSE:Factory/virt-utils/qemu-0.15.0.tar.bz2 
/work/SRC/openSUSE:Factory/.virt-utils.new/qemu-0.15.0.tar.bz2 differ: char 11, 
line 1

++++++ qemu-img-git-vpc-fix.patch ++++++

Subject: block: Fix vpc initialization of the Dynamic Disk Header
From: Charles Arnold [email protected] Wed Nov 9 09:32:25 2011 -0700
Date: Fri Nov 11 14:02:58 2011 +0100:
Git: 78439f6af1caa3e8bdafc9fc2d62aeefa53ed63a

The Data Offset field in the Dynamic Disk Header is an 8 byte field.
Although the specification (2006-10-11) gives an example of initializing
only the first 4 bytes, images generated by Microsoft on Windows initialize
all 8 bytes.

Failure to initialize all 8 bytes results in errors from utilities
like Citrix's vhd-util which checks specifically for the proper Data
Offset field initialization.

Signed-off-by: Charles Arnold <[email protected]>
Reviewed-by: Andreas Färber <[email protected]>
Signed-off-by: Kevin Wolf <[email protected]>

Index: qemu-0.15.0/block/vpc.c
===================================================================
--- qemu-0.15.0.orig/block/vpc.c
+++ qemu-0.15.0/block/vpc.c
@@ -587,7 +587,11 @@ static int vpc_create(const char *filena
 
     memcpy(dyndisk_header->magic, "cxsparse", 8);
 
-    dyndisk_header->data_offset = be64_to_cpu(0xFFFFFFFF);
+    /*
+     * Note: The spec is actually wrong here for data_offset, it says
+     * 0xFFFFFFFF, but MS tools expect all 64 bits to be set.
+     */
+    dyndisk_header->data_offset = be64_to_cpu(0xFFFFFFFFFFFFFFFFULL);
     dyndisk_header->table_offset = be64_to_cpu(3 * 512);
     dyndisk_header->version = be32_to_cpu(0x00010000);
     dyndisk_header->block_size = be32_to_cpu(block_size);
++++++ qemu-img-vpc-fixed-disk.patch ++++++
Index: qemu-0.15.0/block/vpc.c
===================================================================
--- qemu-0.15.0.orig/block/vpc.c
+++ qemu-0.15.0/block/vpc.c
@@ -156,13 +156,27 @@ static int vpc_open(BlockDriverState *bs
     struct vhd_dyndisk_header* dyndisk_header;
     uint8_t buf[HEADER_SIZE];
     uint32_t checksum;
+    int disk_type = VHD_DYNAMIC;
 
     if (bdrv_pread(bs->file, 0, s->footer_buf, HEADER_SIZE) != HEADER_SIZE)
         goto fail;
 
     footer = (struct vhd_footer*) s->footer_buf;
-    if (strncmp(footer->creator, "conectix", 8))
-        goto fail;
+    if (strncmp(footer->creator, "conectix", 8)) {
+        int64_t offset = bdrv_getlength(bs->file);
+        if (offset < HEADER_SIZE) {
+            goto fail;
+        }
+        /* If a fixed disk, the footer is found only at the end of the file */
+        if (bdrv_pread(bs->file, offset-HEADER_SIZE, s->footer_buf, 
HEADER_SIZE)
+                != HEADER_SIZE) {
+            goto fail;
+        }
+        if (strncmp(footer->creator, "conectix", 8)) {
+            goto fail;
+        }
+        disk_type = VHD_FIXED;
+    }
 
     checksum = be32_to_cpu(footer->checksum);
     footer->checksum = 0;
@@ -176,49 +190,54 @@ static int vpc_open(BlockDriverState *bs
     bs->total_sectors = (int64_t)
         be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;
 
-    if (bdrv_pread(bs->file, be64_to_cpu(footer->data_offset), buf, 
HEADER_SIZE)
-            != HEADER_SIZE)
-        goto fail;
-
-    dyndisk_header = (struct vhd_dyndisk_header*) buf;
-
-    if (strncmp(dyndisk_header->magic, "cxsparse", 8))
-        goto fail;
+    if (disk_type == VHD_DYNAMIC) {
+        if (bdrv_pread(bs->file, be64_to_cpu(footer->data_offset), buf,
+                HEADER_SIZE) != HEADER_SIZE) {
+            goto fail;
+        }
 
+        dyndisk_header = (struct vhd_dyndisk_header *) buf;
 
-    s->block_size = be32_to_cpu(dyndisk_header->block_size);
-    s->bitmap_size = ((s->block_size / (8 * 512)) + 511) & ~511;
+        if (strncmp(dyndisk_header->magic, "cxsparse", 8)) {
+            goto fail;
+        }
 
-    s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries);
-    s->pagetable = qemu_malloc(s->max_table_entries * 4);
+        s->block_size = be32_to_cpu(dyndisk_header->block_size);
+        s->bitmap_size = ((s->block_size / (8 * 512)) + 511) & ~511;
 
-    s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);
-    if (bdrv_pread(bs->file, s->bat_offset, s->pagetable,
-            s->max_table_entries * 4) != s->max_table_entries * 4)
-           goto fail;
+        s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries);
+        s->pagetable = qemu_malloc(s->max_table_entries * 4);
 
-    s->free_data_block_offset =
-        (s->bat_offset + (s->max_table_entries * 4) + 511) & ~511;
+        s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);
+        if (bdrv_pread(bs->file, s->bat_offset, s->pagetable,
+                s->max_table_entries * 4) != s->max_table_entries * 4) {
+            goto fail;
+        }
 
-    for (i = 0; i < s->max_table_entries; i++) {
-        be32_to_cpus(&s->pagetable[i]);
-        if (s->pagetable[i] != 0xFFFFFFFF) {
-            int64_t next = (512 * (int64_t) s->pagetable[i]) +
-                s->bitmap_size + s->block_size;
+        s->free_data_block_offset =
+            (s->bat_offset + (s->max_table_entries * 4) + 511) & ~511;
 
-            if (next> s->free_data_block_offset)
-                s->free_data_block_offset = next;
+        for (i = 0; i < s->max_table_entries; i++) {
+            be32_to_cpus(&s->pagetable[i]);
+            if (s->pagetable[i] != 0xFFFFFFFF) {
+                int64_t next = (512 * (int64_t) s->pagetable[i]) +
+                    s->bitmap_size + s->block_size;
+
+                if (next > s->free_data_block_offset) {
+                    s->free_data_block_offset = next;
+                }
+            }
         }
-    }
 
-    s->last_bitmap_offset = (int64_t) -1;
+        s->last_bitmap_offset = (int64_t) -1;
 
 #ifdef CACHE
-    s->pageentry_u8 = qemu_malloc(512);
-    s->pageentry_u32 = s->pageentry_u8;
-    s->pageentry_u16 = s->pageentry_u8;
-    s->last_pagetable = -1;
+        s->pageentry_u8 = qemu_malloc(512);
+        s->pageentry_u32 = s->pageentry_u8;
+        s->pageentry_u16 = s->pageentry_u8;
+        s->last_pagetable = -1;
 #endif
+    }
 
     return 0;
  fail:
@@ -374,7 +393,11 @@ static int vpc_read(BlockDriverState *bs
     int ret;
     int64_t offset;
     int64_t sectors, sectors_per_block;
+    struct vhd_footer *footer = (struct vhd_footer *) s->footer_buf;
 
+    if (cpu_to_be32(footer->type) == VHD_FIXED) {
+        return bdrv_read(bs->file, sector_num, buf, nb_sectors);
+    }
     while (nb_sectors > 0) {
         offset = get_sector_offset(bs, sector_num, 0);
 
@@ -408,7 +431,11 @@ static int vpc_write(BlockDriverState *b
     int64_t offset;
     int64_t sectors, sectors_per_block;
     int ret;
+    struct vhd_footer *footer =  (struct vhd_footer *) s->footer_buf;
 
+    if (cpu_to_be32(footer->type) == VHD_FIXED) {
+        return bdrv_write(bs->file, sector_num, buf, nb_sectors);
+    }
     while (nb_sectors > 0) {
         offset = get_sector_offset(bs, sector_num, 1);
 
@@ -490,70 +517,14 @@ static int calculate_geometry(int64_t to
     return 0;
 }
 
-static int vpc_create(const char *filename, QEMUOptionParameter *options)
+static int create_dynamic_disk(int fd, uint8_t *buf, int64_t total_sectors)
 {
-    uint8_t buf[1024];
-    struct vhd_footer* footer = (struct vhd_footer*) buf;
     struct vhd_dyndisk_header* dyndisk_header =
         (struct vhd_dyndisk_header*) buf;
-    int fd, i;
-    uint16_t cyls = 0;
-    uint8_t heads = 0;
-    uint8_t secs_per_cyl = 0;
     size_t block_size, num_bat_entries;
-    int64_t total_sectors = 0;
+    int i;
     int ret = -EIO;
 
-    // Read out options
-    total_sectors = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n /
-                    BDRV_SECTOR_SIZE;
-
-    // Create the file
-    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
-    if (fd < 0)
-        return -EIO;
-
-    /* Calculate matching total_size and geometry. Increase the number of
-       sectors requested until we get enough (or fail). */
-    for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; i++) {
-        if (calculate_geometry(total_sectors + i,
-                               &cyls, &heads, &secs_per_cyl)) {
-            ret = -EFBIG;
-            goto fail;
-        }
-    }
-    total_sectors = (int64_t) cyls * heads * secs_per_cyl;
-
-    // Prepare the Hard Disk Footer
-    memset(buf, 0, 1024);
-
-    memcpy(footer->creator, "conectix", 8);
-    // TODO Check if "qemu" creator_app is ok for VPC
-    memcpy(footer->creator_app, "qemu", 4);
-    memcpy(footer->creator_os, "Wi2k", 4);
-
-    footer->features = be32_to_cpu(0x02);
-    footer->version = be32_to_cpu(0x00010000);
-    footer->data_offset = be64_to_cpu(HEADER_SIZE);
-    footer->timestamp = be32_to_cpu(time(NULL) - VHD_TIMESTAMP_BASE);
-
-    // Version of Virtual PC 2007
-    footer->major = be16_to_cpu(0x0005);
-    footer->minor =be16_to_cpu(0x0003);
-
-    footer->orig_size = be64_to_cpu(total_sectors * 512);
-    footer->size = be64_to_cpu(total_sectors * 512);
-
-    footer->cyls = be16_to_cpu(cyls);
-    footer->heads = heads;
-    footer->secs_per_cyl = secs_per_cyl;
-
-    footer->type = be32_to_cpu(VHD_DYNAMIC);
-
-    // TODO uuid is missing
-
-    footer->checksum = be32_to_cpu(vpc_checksum(buf, HEADER_SIZE));
-
     // Write the footer (twice: at the beginning and at the end)
     block_size = 0x200000;
     num_bat_entries = (total_sectors + block_size / 512) / (block_size / 512);
@@ -581,7 +552,6 @@ static int vpc_create(const char *filena
         }
     }
 
-
     // Prepare the Dynamic Disk Header
     memset(buf, 0, 1024);
 
@@ -610,6 +580,132 @@ static int vpc_create(const char *filena
     ret = 0;
 
  fail:
+    return ret;
+}
+
+static int create_fixed_disk(int fd, uint8_t *buf, int64_t total_size)
+{
+    int ret = -EIO;
+
+    /* Add footer to total size */
+    total_size += 512;
+    if (ftruncate(fd, total_size) != 0) {
+        ret = -errno;
+        goto fail;
+    }
+    if (lseek(fd, -512, SEEK_END) < 0) {
+        goto fail;
+    }
+    if (write(fd, buf, HEADER_SIZE) != HEADER_SIZE) {
+        goto fail;
+    }
+
+    ret = 0;
+
+ fail:
+    return ret;
+}
+
+static int vpc_create(const char *filename, QEMUOptionParameter *options)
+{
+    uint8_t buf[1024];
+    struct vhd_footer *footer = (struct vhd_footer *) buf;
+    QEMUOptionParameter *disk_type_param;
+    int fd, i;
+    uint16_t cyls = 0;
+    uint8_t heads = 0;
+    uint8_t secs_per_cyl = 0;
+    int64_t total_sectors;
+    int64_t total_size;
+    int disk_type;
+    int ret = -EIO;
+
+    /* Read out options */
+    total_size = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n;
+
+    disk_type_param = get_option_parameter(options, BLOCK_OPT_SUBFMT);
+    if (disk_type_param && disk_type_param->value.s) {
+        if (!strcmp(disk_type_param->value.s, "dynamic")) {
+            disk_type = VHD_DYNAMIC;
+        } else if (!strcmp(disk_type_param->value.s, "fixed")) {
+            disk_type = VHD_FIXED;
+        } else {
+            return -EINVAL;
+        }
+    } else {
+        disk_type = VHD_DYNAMIC;
+    }
+
+    /* Create the file */
+    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
+    if (fd < 0) {
+        return -EIO;
+    }
+
+    total_sectors = total_size / BDRV_SECTOR_SIZE;
+    if (disk_type == VHD_DYNAMIC) {
+        /* Calculate matching total_size and geometry. Increase the number of
+           sectors requested until we get enough (or fail). */
+        for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl;
+             i++) {
+            if (calculate_geometry(total_sectors + i,
+                                   &cyls, &heads, &secs_per_cyl)) {
+                ret = -EFBIG;
+                goto fail;
+            }
+        }
+    } else {
+        if (calculate_geometry(total_sectors, &cyls, &heads, &secs_per_cyl)) {
+            ret = -EFBIG;
+            goto fail;
+        }
+    }
+    total_sectors = (int64_t) cyls * heads * secs_per_cyl;
+
+    /* Prepare the Hard Disk Footer */
+    memset(buf, 0, 1024);
+
+    memcpy(footer->creator, "conectix", 8);
+    /* TODO Check if "qemu" creator_app is ok for VPC */
+    memcpy(footer->creator_app, "qemu", 4);
+    memcpy(footer->creator_os, "Wi2k", 4);
+
+    footer->features = be32_to_cpu(0x02);
+    footer->version = be32_to_cpu(0x00010000);
+    if (disk_type == VHD_DYNAMIC) {
+        footer->data_offset = be64_to_cpu(HEADER_SIZE);
+    } else {
+        footer->data_offset = be64_to_cpu(0xFFFFFFFFFFFFFFFFULL);
+    }
+    footer->timestamp = be32_to_cpu(time(NULL) - VHD_TIMESTAMP_BASE);
+
+    /* Version of Virtual PC 2007 */
+    footer->major = be16_to_cpu(0x0005);
+    footer->minor = be16_to_cpu(0x0003);
+    if (disk_type == VHD_DYNAMIC) {
+        footer->orig_size = be64_to_cpu(total_sectors * 512);
+        footer->size = be64_to_cpu(total_sectors * 512);
+    } else {
+        footer->orig_size = be64_to_cpu(total_size);
+        footer->size = be64_to_cpu(total_size);
+    }
+    footer->cyls = be16_to_cpu(cyls);
+    footer->heads = heads;
+    footer->secs_per_cyl = secs_per_cyl;
+
+    footer->type = be32_to_cpu(disk_type);
+
+    /* TODO uuid is missing */
+
+    footer->checksum = be32_to_cpu(vpc_checksum(buf, HEADER_SIZE));
+
+    if (disk_type == VHD_DYNAMIC) {
+        ret = create_dynamic_disk(fd, buf, total_sectors);
+    } else {
+        ret = create_fixed_disk(fd, buf, total_size);
+    }
+
+ fail:
     close(fd);
     return ret;
 }
@@ -629,6 +725,13 @@ static QEMUOptionParameter vpc_create_op
         .type = OPT_SIZE,
         .help = "Virtual disk size"
     },
+    {
+        .name = BLOCK_OPT_SUBFMT,
+        .type = OPT_STRING,
+        .help =
+            "Type of virtual hard disk format. Supported formats are "
+            "{dynamic (default) | fixed} "
+    },
     { NULL }
 };
 
++++++ qemu-img-vpc-roundup-fix.patch ++++++
>From 08e8fee7df7cc63353134a7135da696414fbfd28 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <[email protected]>
Date: Tue, 7 Feb 2012 10:15:47 +0100
Subject: [PATCH] vpc: Round up image size during fixed image creation

The geometry calculation algorithm from the VHD spec rounds the image
size down if it doesn't exactly match a geometry. During image
conversion, this causes the image to be truncated. For dynamic images,
we already have code in place to round up instead, let's do the same for
fixed images.

Signed-off-by: Kevin Wolf <[email protected]>
---
 block/vpc.c |   23 ++++++++++-------------
 1 files changed, 10 insertions(+), 13 deletions(-)

Index: qemu-0.15.0/block/vpc.c
===================================================================
--- qemu-0.15.0.orig/block/vpc.c
+++ qemu-0.15.0/block/vpc.c
@@ -642,24 +642,21 @@ static int vpc_create(const char *filena
         return -EIO;
     }
 
+    /*
+     * Calculate matching total_size and geometry. Increase the number of
+     * sectors requested until we get enough (or fail). This ensures that
+     * qemu-img convert doesn't truncate images, but rather rounds up.
+     */
     total_sectors = total_size / BDRV_SECTOR_SIZE;
-    if (disk_type == VHD_DYNAMIC) {
-        /* Calculate matching total_size and geometry. Increase the number of
-           sectors requested until we get enough (or fail). */
-        for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl;
-             i++) {
-            if (calculate_geometry(total_sectors + i,
-                                   &cyls, &heads, &secs_per_cyl)) {
-                ret = -EFBIG;
-                goto fail;
-            }
-        }
-    } else {
-        if (calculate_geometry(total_sectors, &cyls, &heads, &secs_per_cyl)) {
+    for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; i++) {
+        if (calculate_geometry(total_sectors + i, &cyls, &heads,
+                               &secs_per_cyl))
+        {
             ret = -EFBIG;
             goto fail;
         }
     }
+
     total_sectors = (int64_t) cyls * heads * secs_per_cyl;
 
     /* Prepare the Hard Disk Footer */
-- 
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to