[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH V18 21/25] block: add QemuOpts support for vpc.c
From: |
Dong Xu Wang |
Subject: |
[Qemu-devel] [PATCH V18 21/25] block: add QemuOpts support for vpc.c |
Date: |
Tue, 13 Aug 2013 12:32:02 +0800 |
Signed-off-by: Dong Xu Wang <address@hidden>
---
block/vpc.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 125 insertions(+)
diff --git a/block/vpc.c b/block/vpc.c
index fe4f311..aa1263a 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -786,6 +786,109 @@ static int vpc_create(const char *filename,
QEMUOptionParameter *options)
return ret;
}
+static int vpc_create_new(const char *filename, QemuOpts *opts)
+{
+ uint8_t buf[1024];
+ struct vhd_footer *footer = (struct vhd_footer *) buf;
+ char *disk_type_param = NULL;
+ 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 = 0;
+ int disk_type = VHD_DYNAMIC;
+ int ret = -EIO;
+
+ /* Read out opts */
+ total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
+ disk_type_param = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);
+ if (disk_type_param) {
+ if (!strcmp(disk_type_param, "dynamic")) {
+ disk_type = VHD_DYNAMIC;
+ } else if (!strcmp(disk_type_param, "fixed")) {
+ disk_type = VHD_FIXED;
+ } else {
+ ret = -EINVAL;
+ goto finish;
+ }
+ }
+
+ /* Create the file */
+ fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
+ if (fd < 0) {
+ ret = -EIO;
+ goto finish;
+ }
+
+ /*
+ * 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;
+ 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);
+ 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);
+
+#if defined(CONFIG_UUID)
+ uuid_generate(footer->uuid);
+#endif
+
+ 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:
+ qemu_close(fd);
+finish:
+ g_free(disk_type_param);
+ return ret;
+}
+
static int vpc_has_zero_init(BlockDriverState *bs)
{
BDRVVPCState *s = bs->opaque;
@@ -826,6 +929,26 @@ static QEMUOptionParameter vpc_create_options[] = {
{ NULL }
};
+static QemuOptsList vpc_create_opts = {
+ .name = "vpc-create-opts",
+ .head = QTAILQ_HEAD_INITIALIZER(vpc_create_opts.head),
+ .desc = {
+ {
+ .name = BLOCK_OPT_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "Virtual disk size"
+ },
+ {
+ .name = BLOCK_OPT_SUBFMT,
+ .type = QEMU_OPT_STRING,
+ .help =
+ "Type of virtual hard disk format. Supported formats are "
+ "{dynamic (default) | fixed} "
+ },
+ { /* end of list */ }
+ }
+};
+
static BlockDriver bdrv_vpc = {
.format_name = "vpc",
.instance_size = sizeof(BDRVVPCState),
@@ -835,11 +958,13 @@ static BlockDriver bdrv_vpc = {
.bdrv_close = vpc_close,
.bdrv_reopen_prepare = vpc_reopen_prepare,
.bdrv_create = vpc_create,
+ .bdrv_create_new = vpc_create_new,
.bdrv_read = vpc_co_read,
.bdrv_write = vpc_co_write,
.create_options = vpc_create_options,
+ .bdrv_create_opts = &vpc_create_opts,
.bdrv_has_zero_init = vpc_has_zero_init,
};
--
1.7.11.7
- [Qemu-devel] [PATCH V18 15/25] block: add QemuOpts support for raw.c, (continued)
- [Qemu-devel] [PATCH V18 15/25] block: add QemuOpts support for raw.c, Dong Xu Wang, 2013/08/13
- [Qemu-devel] [PATCH V18 16/25] block: add QemuOpts support for rbd.c, Dong Xu Wang, 2013/08/13
- [Qemu-devel] [PATCH V18 17/25] block: add QemuOpts support for sheepdog.c, Dong Xu Wang, 2013/08/13
- [Qemu-devel] [PATCH V18 18/25] block: add QemuOpts support for ssh.c, Dong Xu Wang, 2013/08/13
- [Qemu-devel] [PATCH V18 19/25] block: add QemuOpts support for vdi.c, Dong Xu Wang, 2013/08/13
- [Qemu-devel] [PATCH V18 20/25] block: add QemuOpts support for vmdk.c, Dong Xu Wang, 2013/08/13
- [Qemu-devel] [PATCH V18 22/25] block: add QemuOpts support for block.c, Dong Xu Wang, 2013/08/13
- [Qemu-devel] [PATCH V18 23/25] block: clean temp code and use QemuOpts in block, Dong Xu Wang, 2013/08/13
- [Qemu-devel] [PATCH V18 24/25] qapi: query-command-line-options outputs def_value_str, Dong Xu Wang, 2013/08/13
- [Qemu-devel] [PATCH V18 25/25] qemu-option: remove QEMUOptionParameter related functions and struct, Dong Xu Wang, 2013/08/13
- [Qemu-devel] [PATCH V18 21/25] block: add QemuOpts support for vpc.c,
Dong Xu Wang <=