[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 10/27] block/parallels: support parallels image crea
From: |
Denis V. Lunev |
Subject: |
[Qemu-devel] [PATCH 10/27] block/parallels: support parallels image creation |
Date: |
Wed, 11 Mar 2015 13:28:04 +0300 |
Do not even care to create WithoutFreeSpace image, it is obsolete.
Always create WithouFreSpacExt one.
The code also does not spend a lot of efforts to fill cylinders and
heads fields, they are not used actually in a real life neither in
QEMU nor in Parallels products.
Signed-off-by: Denis V. Lunev <address@hidden>
Reviwed-by: Roman Kagan <address@hidden>
CC: Kevin Wolf <address@hidden>
CC: Stefan Hajnoczi <address@hidden>
---
block/parallels.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 97 insertions(+)
diff --git a/block/parallels.c b/block/parallels.c
index 61d7da7..28338ec 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -33,6 +33,9 @@
#define HEADER_MAGIC2 "WithouFreSpacExt"
#define HEADER_VERSION 2
+#define DEFAULT_CLUSTER_SIZE 1048576 /* 1 MiB */
+
+
// always little-endian
typedef struct ParallelsHeader {
char magic[16]; // "WithoutFreeSpace"
@@ -300,12 +303,103 @@ fail:
return ret;
}
+static int parallels_create(const char *filename, QemuOpts *opts, Error **errp)
+{
+ int64_t total_size, cl_size;
+ uint8_t tmp[BDRV_SECTOR_SIZE];
+ Error *local_err = NULL;
+ BlockDriverState *file;
+ uint32_t cat_entries, cat_sectors;
+ ParallelsHeader header;
+ int ret;
+
+ total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),
+ BDRV_SECTOR_SIZE);
+ cl_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,
+ DEFAULT_CLUSTER_SIZE), BDRV_SECTOR_SIZE);
+
+ ret = bdrv_create_file(filename, opts, &local_err);
+ if (ret < 0) {
+ error_propagate(errp, local_err);
+ return ret;
+ }
+
+ file = NULL;
+ ret = bdrv_open(&file, filename, NULL, NULL,
+ BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err);
+ if (ret < 0) {
+ error_propagate(errp, local_err);
+ return ret;
+ }
+ ret = bdrv_truncate(file, 0);
+ if (ret < 0) {
+ goto exit;
+ }
+
+ cat_entries = DIV_ROUND_UP(total_size, cl_size);
+ cat_sectors = DIV_ROUND_UP(cat_entries * sizeof(uint32_t) +
+ sizeof(ParallelsHeader), cl_size);
+ cat_sectors = (cat_sectors * cl_size) >> BDRV_SECTOR_BITS;
+
+ memset(&header, 0, sizeof(header));
+ memcpy(header.magic, HEADER_MAGIC2, sizeof(header.magic));
+ header.version = cpu_to_le32(HEADER_VERSION);
+ /* don't care much about geometry, it is not used on image level */
+ header.heads = cpu_to_le32(16);
+ header.cylinders = cpu_to_le32(total_size / BDRV_SECTOR_SIZE / 16 / 32);
+ header.tracks = cpu_to_le32(cl_size >> BDRV_SECTOR_BITS);
+ header.catalog_entries = cpu_to_le32(cat_entries);
+ header.nb_sectors = cpu_to_le64(DIV_ROUND_UP(total_size,
BDRV_SECTOR_SIZE));
+ header.data_off = cpu_to_le32(cat_sectors);
+
+ /* write all the data */
+ memset(tmp, 0, sizeof(tmp));
+ memcpy(tmp, &header, sizeof(header));
+
+ ret = bdrv_pwrite(file, 0, tmp, BDRV_SECTOR_SIZE);
+ if (ret < 0) {
+ goto exit;
+ }
+ ret = bdrv_write_zeroes(file, 1, cat_sectors - 1, 0);
+ if (ret < 0) {
+ goto exit;
+ }
+ ret = 0;
+
+done:
+ bdrv_unref(file);
+ return ret;
+
+exit:
+ error_setg_errno(errp, -ret, "Failed to create Parallels image");
+ goto done;
+}
+
static void parallels_close(BlockDriverState *bs)
{
BDRVParallelsState *s = bs->opaque;
g_free(s->catalog_bitmap);
}
+static QemuOptsList parallels_create_opts = {
+ .name = "parallels-create-opts",
+ .head = QTAILQ_HEAD_INITIALIZER(parallels_create_opts.head),
+ .desc = {
+ {
+ .name = BLOCK_OPT_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "Virtual disk size",
+ },
+ {
+ .name = BLOCK_OPT_CLUSTER_SIZE,
+ .type = QEMU_OPT_SIZE,
+ .help = "Parallels image cluster size",
+ .def_value_str = stringify(DEFAULT_CLUSTER_SIZE),
+ },
+ { /* end of list */ }
+ }
+};
+
static BlockDriver bdrv_parallels = {
.format_name = "parallels",
.instance_size = sizeof(BDRVParallelsState),
@@ -315,6 +409,9 @@ static BlockDriver bdrv_parallels = {
.bdrv_co_get_block_status = parallels_co_get_block_status,
.bdrv_co_readv = parallels_co_readv,
.bdrv_co_writev = parallels_co_writev,
+
+ .bdrv_create = parallels_create,
+ .create_opts = ¶llels_create_opts,
};
static void bdrv_parallels_init(void)
--
1.9.1
- [Qemu-devel] [PATCH 21/27] block/parallels: no need to flush on each block allocation table update, (continued)
- [Qemu-devel] [PATCH 21/27] block/parallels: no need to flush on each block allocation table update, Denis V. Lunev, 2015/03/10
- [Qemu-devel] [PATCH 02/27] block/parallels: rename parallels_header to ParallelsHeader, Denis V. Lunev, 2015/03/10
- [Qemu-devel] [PATCH v3 0/27] write/create for Parallels images with reasonable performance, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 22/27] block/parallels: improve image reading performance, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 05/27] block/parallels: add get_block_status, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 01/27] iotests, parallels: quote TEST_IMG in 076 test to be path-safe, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 03/27] block/parallels: switch to bdrv_read, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 24/27] block/parallels: delay writing to BAT till bdrv_co_flush_to_os, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 13/27] block/parallels: rename catalog_ names to bat_, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 10/27] block/parallels: support parallels image creation,
Denis V. Lunev <=
- [Qemu-devel] [PATCH 27/27] block/parallels: improve image writing performance further, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 19/27] block/parallels: implement incorrect close detection, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 11/27] iotests, parallels: test for newly created parallels image via qemu-img, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 15/27] block/parallels: keep BAT bitmap data in little endian in memory, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 18/27] block/parallels: implement parallels_check method of block driver, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 21/27] block/parallels: no need to flush on each block allocation table update, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 08/27] block/parallels: _co_writev callback for Parallels format, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 12/27] parallels: change copyright information in the image header, Denis V. Lunev, 2015/03/11
- [Qemu-devel] [PATCH 04/27] block/parallels: read up to cluster end in one go, Denis V. Lunev, 2015/03/11