[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 07/40] block/vpc: give option to force the current_si
From: |
Kevin Wolf |
Subject: |
[Qemu-devel] [PULL 07/40] block/vpc: give option to force the current_size field in .bdrv_create |
Date: |
Mon, 14 Mar 2016 18:37:08 +0100 |
From: Jeff Cody <address@hidden>
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 <address@hidden>
Signed-off-by: Kevin Wolf <address@hidden>
---
block/vpc.c | 42 +++++++++++++++++++++++++++++++++++-------
1 file changed, 35 insertions(+), 7 deletions(-)
diff --git a/block/vpc.c b/block/vpc.c
index 54a38a7..318e6d6 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -46,8 +46,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 {
@@ -288,6 +294,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
*
@@ -296,6 +303,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) {
@@ -850,6 +858,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;
@@ -870,6 +879,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);
@@ -887,13 +898,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) {
@@ -912,8 +930,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);
@@ -994,6 +1015,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 */ }
}
};
--
1.8.3.1
- [Qemu-devel] [PULL 03/40] block/qapi: Factor out bdrv_query_bds_stats(), (continued)
- [Qemu-devel] [PULL 03/40] block/qapi: Factor out bdrv_query_bds_stats(), Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 01/40] qemu-img: eliminate memory leak, Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 02/40] block/qapi: Factor out bdrv_query_blk_stats(), Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 04/40] block/qapi: Include empty drives in query-blockstats, Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 05/40] block/vpc: choose size calculation method based on creator_app field, Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 09/40] docs: fix invalid node name in qmp event, Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 11/40] quorum: modify vote rules for flush operation, Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 06/40] block/vpc: tests for auto-detecting VPC and Hyper-V VHD images, Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 10/40] qmp event: Refactor QUORUM_REPORT_BAD, Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 08/40] block/vpc: add tests for image creation force_size parameter, Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 07/40] block/vpc: give option to force the current_size field in .bdrv_create,
Kevin Wolf <=
- [Qemu-devel] [PULL 12/40] blockdev: Snapshotting must not open second instance of old top, Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 15/40] vmdk: Switch to heap arrays for vmdk_write_cid, Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 13/40] block: Fix snapshot=on cache modes, Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 14/40] block: Fix cache mode defaults in bds_tree_init(), Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 16/40] vmdk: Switch to heap arrays for vmdk_read_cid, Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 17/40] vmdk: Switch to heap arrays for vmdk_parent_open, Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 21/40] block: Introduce blk_set_allow_write_beyond_eof(), Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 23/40] qcow: Use BB functions in .bdrv_create(), Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 22/40] parallels: Use BB functions in .bdrv_create(), Kevin Wolf, 2016/03/14
- [Qemu-devel] [PULL 20/40] block: Use writeback in .bdrv_create() implementations, Kevin Wolf, 2016/03/14