Re: [Qemu-devel] [PATCH v8 16/19] block: vhdx - add .bdrv_create() support

2013-10-31 Thread Stefan Hajnoczi
On Wed, Oct 30, 2013 at 10:44:53AM -0400, Jeff Cody wrote:
 +if (image_size  VHDX_MAX_IMAGE_SIZE) {
 +error_setg_errno(errp, EINVAL, Image size too large; max of 
 64TB\n);

Error messages should not include '\n'.

Perhaps this can be fixed when merging the patch.



[Qemu-devel] [PATCH v8 16/19] block: vhdx - add .bdrv_create() support

2013-10-30 Thread Jeff Cody
This adds support for VHDX image creation, for images of type Fixed
and Dynamic.  Differencing types (i.e., VHDX images with backing
files) are currently not supported.

Options for image creation include:
* log size:
The size of the journaling log for VHDX.  Minimum is 1MB,
and it must be a multiple of 1MB. Invalid log sizes will be
silently fixed by rounding up to the nearest MB.

Default is 1MB.

* block size:
This is the size of a payload block.  The range is 1MB to 256MB,
inclusive, and must be a multiple of 1MB as well.  Invalid sizes
and multiples will be silently fixed.  If '0' is passed, then
a sane size is chosen (depending on virtual image size).

Default is 0 (Auto-select).

* subformat:
- dynamic
An image without data pre-allocated.
- fixed
An image with data pre-allocated.

Default is dynamic

When creating the image file, the lettered sections are created:

-.
|   (A)|   (B)|(C)| (D)   | (E)
|  File ID |  Header1 |  Header 2 |  Region Tbl 1 |  Region Tbl 2
|  |  |   |   |
.-.
0 64KB  128KB   192KB   256KB  320KB

. ~ --- ~  ~  ~ ---.
| (F) | (G)   |(H)|
| Journal Log |  BAT / Bitmap |  Metadata |   data ..
| |   |   |
. ~ --- ~  ~  ~ ---.
1MB (var.)  (var.)  (var.)

Signed-off-by: Jeff Cody jc...@redhat.com
---
 block/vhdx.c | 558 +++
 block/vhdx.h |  15 +-
 2 files changed, 572 insertions(+), 1 deletion(-)

diff --git a/block/vhdx.c b/block/vhdx.c
index 7bf7cd6..e439585 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -23,6 +23,19 @@
 #include migration/migration.h
 
 #include uuid/uuid.h
+#include glib.h
+
+/* Options for VHDX creation */
+
+#define VHDX_BLOCK_OPT_LOG_SIZE   log_size
+#define VHDX_BLOCK_OPT_BLOCK_SIZE block_size
+#define VHDX_BLOCK_OPT_ZERO block_state_zero
+
+typedef enum VHDXImageType {
+VHDX_TYPE_DYNAMIC = 0,
+VHDX_TYPE_FIXED,
+VHDX_TYPE_DIFFERENCING,   /* Currently unsupported */
+} VHDXImageType;
 
 /* Several metadata and region table data entries are identified by
  * guids in  a MS-specific GUID format. */
@@ -1320,6 +1333,548 @@ exit:
 }
 
 
+
+/*
+ * Create VHDX Headers
+ *
+ * There are 2 headers, and the highest sequence number will represent
+ * the active header
+ */
+static int vhdx_create_new_headers(BlockDriverState *bs, uint64_t image_size,
+   uint32_t log_size)
+{
+int ret = 0;
+VHDXHeader *hdr = NULL;
+
+hdr = g_malloc0(sizeof(VHDXHeader));
+
+hdr-signature   = VHDX_HEADER_SIGNATURE;
+hdr-sequence_number = g_random_int();
+hdr-log_version = 0;
+hdr-version = 1;
+hdr-log_length  = log_size;
+hdr-log_offset  = VHDX_HEADER_SECTION_END;
+vhdx_guid_generate(hdr-file_write_guid);
+vhdx_guid_generate(hdr-data_write_guid);
+
+ret = vhdx_write_header(bs, hdr, VHDX_HEADER1_OFFSET, false);
+if (ret  0) {
+goto exit;
+}
+hdr-sequence_number++;
+ret = vhdx_write_header(bs, hdr, VHDX_HEADER2_OFFSET, false);
+if (ret  0) {
+goto exit;
+}
+
+exit:
+g_free(hdr);
+return ret;
+}
+
+
+/*
+ * Create the Metadata entries.
+ *
+ * For more details on the entries, see section 3.5 (pg 29) in the
+ * VHDX 1.00 specification.
+ *
+ * We support 5 metadata entries (all required by spec):
+ *  File Parameters,
+ *  Virtual Disk Size,
+ *  Page 83 Data,
+ *  Logical Sector Size,
+ *  Physical Sector Size
+ *
+ * The first 64KB of the Metadata section is reserved for the metadata
+ * header and entries; beyond that, the metadata items themselves reside.
+ */
+static int vhdx_create_new_metadata(BlockDriverState *bs,
+uint64_t image_size,
+uint32_t block_size,
+uint32_t sector_size,
+uint64_t metadata_offset,
+VHDXImageType type)
+{
+int ret = 0;
+uint32_t offset = 0;
+void *buffer = NULL;
+void *entry_buffer;
+VHDXMetadataTableHeader *md_table;;
+VHDXMetadataTableEntry  *md_table_entry;
+
+/* Metadata entries */
+VHDXFileParameters *mt_file_params;
+VHDXVirtualDiskSize*mt_virtual_size;
+VHDXPage83Data *mt_page83;
+VHDXVirtualDiskLogicalSectorSize  *mt_log_sector_size;
+VHDXVirtualDiskPhysicalSectorSize *mt_phys_sector_size;
+
+entry_buffer =