From: Andrey Gruzdev <andrey.gruzdev@virtuozzo.com>
To: qemu-devel@nongnu.org
Cc: Den Lunev <den@openvz.org>, Eric Blake <eblake@redhat.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Juan Quintela <quintela@redhat.com>,
"Dr . David Alan Gilbert" <dgilbert@redhat.com>,
Markus Armbruster <armbru@redhat.com>,
Peter Xu <peterx@redhat.com>,
Andrey Gruzdev <andrey.gruzdev@virtuozzo.com>
Subject: [RFC PATCH 2/9] migration/snap-tool: Snapshot image create/open routines for qemu-snap tool
Date: Wed, 17 Mar 2021 19:32:15 +0300 [thread overview]
Message-ID: <20210317163222.182609-3-andrey.gruzdev@virtuozzo.com> (raw)
In-Reply-To: <20210317163222.182609-1-andrey.gruzdev@virtuozzo.com>
Implementation of routines for QCOW2 image creation and opening. Some
predefined parameters for image creation and opening are introduced that
provide reasonable tradeoff between performance, file size and usability.
Thus, it was chosen to disable preallocation and keep image file dense on
host file system, the apparent file size equals allocated in this case
which is anyways beneficial for the user experience.
Larger 1MB cluster size is adopted to reduce allocation overhead and
improve I/O performance while keeping internal fragmentation of snapshot
image reasonably small.
Signed-off-by: Andrey Gruzdev <andrey.gruzdev@virtuozzo.com>
---
qemu-snap.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 90 insertions(+), 4 deletions(-)
diff --git a/qemu-snap.c b/qemu-snap.c
index c7118927f7..c9f8d7166a 100644
--- a/qemu-snap.c
+++ b/qemu-snap.c
@@ -31,6 +31,16 @@
#include "migration/qemu-file.h"
#include "qemu-snap.h"
+/* QCOW2 image options */
+#define BLK_FORMAT_DRIVER "qcow2"
+#define BLK_CREATE_OPT_STRING "preallocation=off,lazy_refcounts=on," \
+ "extended_l2=off,compat=v3,cluster_size=1M," \
+ "refcount_bits=8"
+/* L2 cache size to cover 2TB of memory */
+#define BLK_L2_CACHE_SIZE "16M"
+/* Single L2 cache entry for the whole L2 table */
+#define BLK_L2_CACHE_ENTRY_SIZE "1M"
+
#define OPT_CACHE 256
#define OPT_AIO 257
@@ -104,30 +114,106 @@ static void snap_load_destroy_state(void)
/* TODO: implement */
}
+static BlockBackend *snap_create(const char *filename, int64_t image_size,
+ int flags, bool writethrough)
+{
+ char *create_opt_string;
+ QDict *blk_opts;
+ BlockBackend *blk;
+ Error *local_err = NULL;
+
+ /* Create QCOW2 image with given parameters */
+ create_opt_string = g_strdup(BLK_CREATE_OPT_STRING);
+ bdrv_img_create(filename, BLK_FORMAT_DRIVER, NULL, NULL,
+ create_opt_string, image_size, flags, true, &local_err);
+ g_free(create_opt_string);
+
+ if (local_err) {
+ error_reportf_err(local_err, "Could not create '%s': ", filename);
+ goto fail;
+ }
+
+ /* Block backend open options */
+ blk_opts = qdict_new();
+ qdict_put_str(blk_opts, "driver", BLK_FORMAT_DRIVER);
+ qdict_put_str(blk_opts, "l2-cache-size", BLK_L2_CACHE_SIZE);
+ qdict_put_str(blk_opts, "l2-cache-entry-size", BLK_L2_CACHE_ENTRY_SIZE);
+
+ /* Open block backend instance for the created image */
+ blk = blk_new_open(filename, NULL, blk_opts, flags, &local_err);
+ if (!blk) {
+ error_reportf_err(local_err, "Could not open '%s': ", filename);
+ /* Delete image file */
+ qemu_unlink(filename);
+ goto fail;
+ }
+
+ blk_set_enable_write_cache(blk, !writethrough);
+ return blk;
+
+fail:
+ return NULL;
+}
+
+static BlockBackend *snap_open(const char *filename, int flags)
+{
+ QDict *blk_opts;
+ BlockBackend *blk;
+ Error *local_err = NULL;
+
+ /* Block backend open options */
+ blk_opts = qdict_new();
+ qdict_put_str(blk_opts, "driver", BLK_FORMAT_DRIVER);
+ qdict_put_str(blk_opts, "l2-cache-size", BLK_L2_CACHE_SIZE);
+ qdict_put_str(blk_opts, "l2-cache-entry-size", BLK_L2_CACHE_ENTRY_SIZE);
+
+ /* Open block backend instance */
+ blk = blk_new_open(filename, NULL, blk_opts, flags, &local_err);
+ if (!blk) {
+ error_reportf_err(local_err, "Could not open '%s': ", filename);
+ return NULL;
+ }
+
+ return blk;
+}
+
static int snap_save(const SnapSaveParams *params)
{
SnapSaveState *sn;
+ int res = -1;
snap_save_init_state();
sn = snap_save_get_state();
- (void) sn;
+ sn->blk = snap_create(params->filename, params->image_size,
+ params->bdrv_flags, params->writethrough);
+ if (!sn->blk) {
+ goto fail;
+ }
+
+fail:
snap_save_destroy_state();
- return 0;
+ return res;
}
static int snap_load(SnapLoadParams *params)
{
SnapLoadState *sn;
+ int res = -1;
snap_load_init_state();
sn = snap_load_get_state();
- (void) sn;
+ sn->blk = snap_open(params->filename, params->bdrv_flags);
+ if (!sn->blk) {
+ goto fail;
+ }
+
+fail:
snap_load_destroy_state();
- return 0;
+ return res;
}
static int64_t cvtnum_full(const char *name, const char *value,
--
2.25.1
next prev parent reply other threads:[~2021-03-17 17:11 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-17 16:32 [RFC PATCH 0/9] migration/snap-tool: External snapshot utility Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 1/9] migration/snap-tool: Introduce qemu-snap tool Andrey Gruzdev
2021-03-17 16:32 ` Andrey Gruzdev [this message]
2021-03-17 16:32 ` [RFC PATCH 3/9] migration/snap-tool: Preparations to run code in main loop context Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 4/9] migration/snap-tool: Introduce qemu_ftell2() routine to qemu-file.c Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 5/9] migration/snap-tool: Block layer AIO support and file utility routines Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 6/9] migration/snap-tool: Move RAM_SAVE_FLAG_xxx defines to migration/ram.h Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 7/9] migration/snap-tool: Complete implementation of snapshot saving Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 8/9] migration/snap-tool: Implementation of snapshot loading in precopy Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 9/9] migration/snap-tool: Implementation of snapshot loading in postcopy Andrey Gruzdev
2021-03-29 8:11 ` [RFC PATCH 0/9] migration/snap-tool: External snapshot utility Andrey Gruzdev
2021-04-15 23:50 ` Peter Xu
2021-04-16 12:27 ` Andrey Gruzdev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210317163222.182609-3-andrey.gruzdev@virtuozzo.com \
--to=andrey.gruzdev@virtuozzo.com \
--cc=armbru@redhat.com \
--cc=den@openvz.org \
--cc=dgilbert@redhat.com \
--cc=eblake@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).