qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, vsementsov@virtuozzo.com, famz@redhat.com,
	qemu-block@nongnu.org, mreitz@redhat.com, stefanha@redhat.com,
	pbonzini@redhat.com, den@openvz.org, jsnow@redhat.com
Subject: [Qemu-devel] [PATCH 11/17] qemu: command line option for dirty bitmaps
Date: Wed, 17 Feb 2016 18:29:03 +0300	[thread overview]
Message-ID: <1455722949-17060-12-git-send-email-vsementsov@virtuozzo.com> (raw)
In-Reply-To: <1455722949-17060-1-git-send-email-vsementsov@virtuozzo.com>

The patch adds the following command line option:

-dirty-bitmap [option1=val1][,option2=val2]...

Avaliable options are:

name
The name of the bitmap.
Should be unique per 'file'/'node' and per 'for_node'.

node
The node to load and bind the bitmap.
It should be specified as 'id' suboption of one of '-node' options.

granularity
Granularity (in bytes) for created dirty bitmap.
If the bitmap is already exists in specified 'file'/'file_id'/device
it's granularity will not be changed but only checked (an error will be
generated if this check fails).

enabled
on|off
Enabled flag for the bitmap.
By default the bitmap will be enabled.

create
on|off
By default is off.
If on, then new bitmap will be created in the image, if the bitmap with
same name is already exists an error will be generated.
If off, then the bitmap will be loaded from the image, if there is no
one an error will be generated.
If create=off and granularity is specified then granularity will be
checked for loaded bitmap and if not match an error will be generated.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
 blockdev.c                | 36 ++++++++++++++++++++++
 include/sysemu/blockdev.h |  1 +
 include/sysemu/sysemu.h   |  1 +
 qemu-options.hx           | 35 +++++++++++++++++++++
 vl.c                      | 78 +++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 151 insertions(+)

diff --git a/blockdev.c b/blockdev.c
index 07cfe25..98ebe7a 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -181,6 +181,12 @@ QemuOpts *drive_def(const char *optstr)
     return qemu_opts_parse_noisily(qemu_find_opts("drive"), optstr, false);
 }
 
+QemuOpts *dirty_bitmap_def(const char *optstr)
+{
+    return qemu_opts_parse_noisily(qemu_find_opts("dirty-bitmap"), optstr,
+                                   false);
+}
+
 QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
                     const char *optstr)
 {
@@ -3953,6 +3959,36 @@ BlockJobInfoList *qmp_query_block_jobs(Error **errp)
     return head;
 }
 
+QemuOptsList qemu_dirty_bitmap_opts = {
+    .name = "dirty-bitmap",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_dirty_bitmap_opts.head),
+    .desc = {
+        {
+            .name = "name",
+            .type = QEMU_OPT_STRING,
+            .help = "Name of the dirty bitmap",
+        },{
+            .name = "node",
+            .type = QEMU_OPT_STRING,
+            .help = "node name to bind the bitmap to (and load it from it)",
+        },{
+            .name = "granularity",
+            .type = QEMU_OPT_NUMBER,
+            .help = "granularity",
+        },{
+            .name = "enabled",
+            .type = QEMU_OPT_BOOL,
+            .help = "enabled flag (default is 'on')",
+        },{
+            .name = "create",
+            .type = QEMU_OPT_BOOL,
+            .help = "create flag (default is 'off'), "
+                    "if on, new dirty bitmap will be created, "
+                    "else the existing one will be loaded"
+        }
+    }
+};
+
 QemuOptsList qemu_common_drive_opts = {
     .name = "drive",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_common_drive_opts.head),
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index b06a060..221143a 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -57,6 +57,7 @@ int drive_get_max_devs(BlockInterfaceType type);
 DriveInfo *drive_get_next(BlockInterfaceType type);
 
 QemuOpts *drive_def(const char *optstr);
+QemuOpts *dirty_bitmap_def(const char *optstr);
 QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
                     const char *optstr);
 DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type);
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index 3bb8897..7dc3980 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -248,6 +248,7 @@ bool usb_enabled(void);
 
 extern QemuOptsList qemu_legacy_drive_opts;
 extern QemuOptsList qemu_common_drive_opts;
+extern QemuOptsList qemu_dirty_bitmap_opts;
 extern QemuOptsList qemu_drive_opts;
 extern QemuOptsList qemu_chardev_opts;
 extern QemuOptsList qemu_device_opts;
diff --git a/qemu-options.hx b/qemu-options.hx
index b4763ba..636a8e7 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -679,6 +679,41 @@ qemu-system-i386 -hda a -hdb b
 @end example
 ETEXI
 
+DEF("dirty-bitmap", HAS_ARG, QEMU_OPTION_dirty_bitmap,
+    "-dirty-bitmap name=name,node=@var{id}\n"
+    "              [,granularity=granularity][,enabled=on|off][,create=on|off]\n",
+    QEMU_ARCH_ALL)
+STEXI
+@item -dirty-bitmap @var{option}[,@var{option}[,@var{option}[,...]]]
+@findex -dirty-bitmap
+
+Define a dirty-bitmap. Valid options are:
+
+@table @option
+@item name=@var{name}
+The name of the bitmap. Should be unique per @var{file}/@var{node} and per
+@var{for_node}.
+@item node=@var{node}
+The node to load and bind the bitmap. It should be specified as @var{id} suboption
+of one of @option{-node} options.
+@item granularity=@var{granularity}
+Granularity (in bytes) for created dirty bitmap. If the bitmap is already
+exists in specified @var{file}/@var{file_id}/@var{device} it's granularity will
+not be changed but only checked (an error will be generated if this check
+fails).
+@item enabled=@var{enabled}
+Enabled flag for the bitmap. By default the bitmap will be enabled.
+@item create=@var{create}
+By default is off.
+If on, then new bitmap will be created in the image, if the bitmap with same
+name is already exists an error will be generated.
+If off, then the bitmap will be loaded from the image, if there is no one an
+error will be generated.
+If create=off and granularity is specified then granularity will be checked for
+loaded bitmap and if not match an error will be generated.
+@end table
+ETEXI
+
 DEF("mtdblock", HAS_ARG, QEMU_OPTION_mtdblock,
     "-mtdblock file  use 'file' as on-board Flash memory image\n",
     QEMU_ARCH_ALL)
diff --git a/vl.c b/vl.c
index f043009..a0f08c5 100644
--- a/vl.c
+++ b/vl.c
@@ -1144,6 +1144,70 @@ static int cleanup_add_fd(void *opaque, QemuOpts *opts, Error **errp)
 #define MTD_OPTS ""
 #define SD_OPTS ""
 
+static int dirty_bitmap_func(void *opaque, QemuOpts *opts, Error **errp)
+{
+    BlockDriverState *bs = NULL;
+    BdrvDirtyBitmap *bitmap = NULL;
+
+    const char *name = qemu_opt_get(opts, "name");
+    const char *node = qemu_opt_get(opts, "node");
+
+    uint64_t granularity = qemu_opt_get_number(opts, "granularity", 0);
+    bool enabled = qemu_opt_get_bool(opts, "enabled", true);
+    bool create = qemu_opt_get_bool(opts, "create", false);
+
+    if (name == NULL) {
+        error_setg(errp, "'name' option is necessary");
+        return -EINVAL;
+    }
+
+    if (node == NULL) {
+        error_setg(errp, "'node' option is necessary");
+        return -EINVAL;
+    }
+
+    bs = bdrv_lookup_bs(node, node, errp);
+    if (bs == NULL) {
+        return -ENOENT;
+    }
+
+    if (create) {
+        if (bdrv_load_check_dirty_bitmap(bs, name)) {
+            error_setg(errp, "bitmap '%s' already exists", name);
+            return -EEXIST;
+        }
+
+        if (granularity == 0) {
+            granularity = bdrv_get_default_bitmap_granularity(bs);
+        }
+
+        bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp);
+        if (bitmap == NULL) {
+            return -EINVAL;
+        }
+    } else {
+        bitmap = bdrv_load_dirty_bitmap(bs, name, errp);
+        if (bitmap == NULL) {
+            return -EINVAL;
+        }
+
+        if (granularity != 0 &&
+            granularity != bdrv_dirty_bitmap_granularity(bitmap)) {
+            bdrv_release_dirty_bitmap(bs, bitmap);
+            error_setg(errp, "granularity doesn't match");
+            return -EINVAL;
+        }
+    }
+
+    bdrv_dirty_bitmap_set_internal_persistance(bitmap, true);
+
+    if (!enabled) {
+        bdrv_disable_dirty_bitmap(bitmap);
+    }
+
+    return 0;
+}
+
 static int drive_init_func(void *opaque, QemuOpts *opts, Error **errp)
 {
     BlockInterfaceType *block_default_type = opaque;
@@ -3006,6 +3070,7 @@ int main(int argc, char **argv, char **envp)
     module_call_init(MODULE_INIT_QOM);
 
     qemu_add_opts(&qemu_drive_opts);
+    qemu_add_opts(&qemu_dirty_bitmap_opts);
     qemu_add_drive_opts(&qemu_legacy_drive_opts);
     qemu_add_drive_opts(&qemu_common_drive_opts);
     qemu_add_drive_opts(&qemu_drive_opts);
@@ -3139,6 +3204,11 @@ int main(int argc, char **argv, char **envp)
                     exit(1);
                 }
                 break;
+            case QEMU_OPTION_dirty_bitmap:
+                if (dirty_bitmap_def(optarg) == NULL) {
+                    exit(1);
+                }
+                break;
             case QEMU_OPTION_set:
                 if (qemu_set_option(optarg) != 0)
                     exit(1);
@@ -4454,6 +4524,14 @@ int main(int argc, char **argv, char **envp)
 
     parse_numa_opts(machine_class);
 
+    if (qemu_opts_foreach(qemu_find_opts("dirty-bitmap"), dirty_bitmap_func,
+                          NULL, &err)) {
+        if (err != NULL) {
+            error_report_err(err);
+        }
+        exit(1);
+    }
+
     if (qemu_opts_foreach(qemu_find_opts("mon"),
                           mon_init_func, NULL, NULL)) {
         exit(1);
-- 
1.8.3.1

  parent reply	other threads:[~2016-02-17 15:30 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-17 15:28 [Qemu-devel] [PATCH v4 RFC 00/17] qcow2: persistent dirty bitmaps Vladimir Sementsov-Ogievskiy
2016-02-17 15:28 ` [Qemu-devel] [PATCH 01/17] hbitmap: load/store Vladimir Sementsov-Ogievskiy
2016-02-17 15:28 ` [Qemu-devel] [PATCH 02/17] qcow2: Bitmaps extension: structs and consts Vladimir Sementsov-Ogievskiy
2016-02-17 15:28 ` [Qemu-devel] [PATCH 03/17] qcow2-dirty-bitmap: read dirty bitmap directory Vladimir Sementsov-Ogievskiy
2016-02-17 15:28 ` [Qemu-devel] [PATCH 04/17] qcow2-dirty-bitmap: add qcow2_bitmap_load() Vladimir Sementsov-Ogievskiy
2016-02-17 15:28 ` [Qemu-devel] [PATCH 05/17] qcow2-dirty-bitmap: add qcow2_bitmap_store() Vladimir Sementsov-Ogievskiy
2016-02-17 15:28 ` [Qemu-devel] [PATCH 06/17] qcow2: add dirty bitmaps extension Vladimir Sementsov-Ogievskiy
2016-02-17 15:28 ` [Qemu-devel] [PATCH 07/17] qcow2-dirty-bitmap: add qcow2_bitmap_load_check() Vladimir Sementsov-Ogievskiy
2016-02-17 15:29 ` [Qemu-devel] [PATCH 08/17] block: store persistent dirty bitmaps Vladimir Sementsov-Ogievskiy
2016-02-17 15:29 ` [Qemu-devel] [PATCH 09/17] block: add bdrv_load_dirty_bitmap() Vladimir Sementsov-Ogievskiy
2016-02-17 15:29 ` [Qemu-devel] [PATCH 10/17] qcow2-dirty-bitmap: add autoclear bit Vladimir Sementsov-Ogievskiy
2016-02-17 15:29 ` Vladimir Sementsov-Ogievskiy [this message]
2016-02-17 15:29 ` [Qemu-devel] [PATCH 12/17] qcow2-dirty-bitmap: add IN_USE flag Vladimir Sementsov-Ogievskiy
2016-02-17 15:29 ` [Qemu-devel] [PATCH 13/17] qcow2-dirty-bitmaps: disallow stroing bitmap to other bs Vladimir Sementsov-Ogievskiy
2016-02-17 15:29 ` [Qemu-devel] [PATCH 14/17] iotests: add VM.test_launcn() Vladimir Sementsov-Ogievskiy
2016-02-17 15:29 ` [Qemu-devel] [PATCH 15/17] iotests: test internal persistent dirty bitmap Vladimir Sementsov-Ogievskiy
2016-02-17 15:29 ` [Qemu-devel] [PATCH 16/17] qcow2-dirty-bitmap: add AUTO flag Vladimir Sementsov-Ogievskiy
2016-02-17 15:29 ` [Qemu-devel] [PATCH 17/17] qcow2-dirty-bitmap: add EXTRA_DATA_COMPATIBLE flag Vladimir Sementsov-Ogievskiy
2016-02-26 21:41 ` [Qemu-devel] [PATCH v4 RFC 00/17] qcow2: persistent dirty bitmaps John Snow
2016-02-29 15:49   ` Vladimir Sementsov-Ogievskiy
2016-03-03  9:10 ` Denis V. Lunev
2016-03-04 18:00 ` John Snow
2016-03-05 12:26   ` Vladimir Sementsov-Ogievskiy

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=1455722949-17060-12-git-send-email-vsementsov@virtuozzo.com \
    --to=vsementsov@virtuozzo.com \
    --cc=den@openvz.org \
    --cc=famz@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@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).