Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:Update
qemu-linux-user.5922
0100-block-vpc-give-option-to-force-the-.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0100-block-vpc-give-option-to-force-the-.patch of Package qemu-linux-user.5922
From 6f3c5c6c63cbbe8f398342f11463e17ccab63b89 Mon Sep 17 00:00:00 2001 From: Jeff Cody <jcody@redhat.com> Date: Thu, 25 Feb 2016 12:27:29 -0500 Subject: [PATCH] block/vpc: give option to force the current_size field in .bdrv_create When QEMU creates a VHD image, it goes by the original spec, calculating the current_size based on the nearest CHS geometry (with an exception for disks > 127GB). Apparently, Azure will only allow images that are sized to the nearest MB, and the current_size as calculated from CHS cannot guarantee that. Allow QEMU to create images similar to how Hyper-V creates images, by setting current_size to the specified virtual disk size. This introduces an option, force_size, to be passed to the vpc format during image creation, e.g.: qemu-img convert -f raw -o force_size -O vpc test.img test.vhd When using the "force_size" option, the creator app field used by QEMU will be "qem2" instead of "qemu", to indicate the difference. In light of this, we also add parsing of the "qem2" field during vpc_open. Bug reference: https://bugs.launchpad.net/qemu/+bug/1490611 Signed-off-by: Jeff Cody <jcody@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> (cherry picked from commit fb9245c2610932d33ce148b58714fcc7b3c6eb5f) [CYL: BSC#943446] Signed-off-by: Chunyan Liu <cyliu@suse.com> --- block/vpc.c | 42 +++++++++++++++++++++++++++++++++++------- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/block/vpc.c b/block/vpc.c index 6475e7d3d5..c1329145fc 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -45,8 +45,14 @@ enum vhd_type { // Seconds since Jan 1, 2000 0:00:00 (UTC) #define VHD_TIMESTAMP_BASE 946684800 +#define VHD_CHS_MAX_C 65535LL +#define VHD_CHS_MAX_H 16 +#define VHD_CHS_MAX_S 255 + #define VHD_MAX_SECTORS (65535LL * 255 * 255) -#define VHD_MAX_GEOMETRY (65535LL * 16 * 255) +#define VHD_MAX_GEOMETRY (VHD_CHS_MAX_C * VHD_CHS_MAX_H * VHD_CHS_MAX_S) + +#define VPC_OPT_FORCE_SIZE "force_size" // always big-endian typedef struct vhd_footer { @@ -287,6 +293,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags, * Known creator apps: * 'vpc ' : CHS Virtual PC (uses disk geometry) * 'qemu' : CHS QEMU (uses disk geometry) + * 'qem2' : current_size QEMU (uses current_size) * 'win ' : current_size Hyper-V * 'd2v ' : current_size Disk2vhd * @@ -295,6 +302,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags, * that have CHS geometry of the maximum size. */ use_chs = (!!strncmp(footer->creator_app, "win ", 4) && + !!strncmp(footer->creator_app, "qem2", 4) && !!strncmp(footer->creator_app, "d2v ", 4)) || s->force_use_chs; if (!use_chs || bs->total_sectors == VHD_MAX_GEOMETRY || s->force_use_sz) { @@ -845,6 +853,7 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp) int64_t total_size; int disk_type; int ret = -EIO; + bool force_size; Error *local_err = NULL; BlockDriverState *bs = NULL; @@ -865,6 +874,8 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp) disk_type = VHD_DYNAMIC; } + force_size = qemu_opt_get_bool_del(opts, VPC_OPT_FORCE_SIZE, false); + ret = bdrv_create_file(filename, opts, &local_err); if (ret < 0) { error_propagate(errp, local_err); @@ -882,13 +893,20 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp) * sectors requested until we get enough (or fail). This ensures that * qemu-img convert doesn't truncate images, but rather rounds up. * - * If the image size can't be represented by a spec conform CHS geometry, + * If the image size can't be represented by a spec conformant CHS geometry, * we set the geometry to 65535 x 16 x 255 (CxHxS) sectors and use * the image size from the VHD footer to calculate total_sectors. */ - total_sectors = MIN(VHD_MAX_GEOMETRY, total_size / BDRV_SECTOR_SIZE); - for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; i++) { - calculate_geometry(total_sectors + i, &cyls, &heads, &secs_per_cyl); + if (force_size) { + /* This will force the use of total_size for sector count, below */ + cyls = VHD_CHS_MAX_C; + heads = VHD_CHS_MAX_H; + secs_per_cyl = VHD_CHS_MAX_S; + } else { + total_sectors = MIN(VHD_MAX_GEOMETRY, total_size / BDRV_SECTOR_SIZE); + for (i = 0; total_sectors > (int64_t)cyls * heads * secs_per_cyl; i++) { + calculate_geometry(total_sectors + i, &cyls, &heads, &secs_per_cyl); + } } if ((int64_t)cyls * heads * secs_per_cyl == VHD_MAX_GEOMETRY) { @@ -909,8 +927,11 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp) 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); + if (force_size) { + memcpy(footer->creator_app, "qem2", 4); + } else { + memcpy(footer->creator_app, "qemu", 4); + } memcpy(footer->creator_os, "Wi2k", 4); footer->features = cpu_to_be32(0x02); @@ -991,6 +1012,13 @@ static QemuOptsList vpc_create_opts = { "Type of virtual hard disk format. Supported formats are " "{dynamic (default) | fixed} " }, + { + .name = VPC_OPT_FORCE_SIZE, + .type = QEMU_OPT_BOOL, + .help = "Force disk size calculation to use the actual size " + "specified, rather than using the nearest CHS-based " + "calculation" + }, { /* end of list */ } } };
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor