From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, jcody@redhat.com, stefanha@redhat.com
Subject: [Qemu-devel] [PATCH 20/20] monitor: add commands to start/stop dirty bitmap
Date: Wed, 12 Dec 2012 14:46:39 +0100 [thread overview]
Message-ID: <1355319999-30627-21-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1355319999-30627-1-git-send-email-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
blockdev.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++
blockdev.h | 1 +
hmp-commands.hx | 39 ++++++++++++++++++++++++++++++++++
hmp.c | 27 +++++++++++++++++++++++
hmp.h | 2 ++
qapi-schema.json | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
qmp-commands.hx | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 245 insertions(+)
diff --git a/blockdev.c b/blockdev.c
index 37e6743..96e1b4e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1323,6 +1323,61 @@ void qmp_drive_mirror(const char *device, const char *target,
drive_get_ref(drive_get_by_blockdev(bs));
}
+void qmp_blockdev_dirty_enable(const char *device, const char *file,
+ bool has_granularity, uint32_t granularity,
+ Error **errp)
+{
+ BlockDriverState *bs;
+ DriveInfo *drv;
+ Error *local_err = NULL;
+
+ bs = bdrv_find(device);
+ if (!bs) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+ return;
+ }
+
+ drv = drive_get_by_blockdev(bs);
+ bdrv_enable_dirty_tracking(bs, granularity, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ return;
+ }
+
+ /* Release previous usage of dirty bitmap. */
+ if (drv->dirty_use) {
+ bdrv_disable_persistent_dirty_tracking(bs);
+ bdrv_disable_dirty_tracking(bs);
+ }
+ drv->dirty_use = true;
+
+ bdrv_enable_persistent_dirty_tracking(bs, file, errp);
+}
+
+void qmp_blockdev_dirty_disable(const char *device, bool has_force, bool force, Error **errp)
+{
+ BlockDriverState *bs = bdrv_find(device);
+ DriveInfo *drv;
+
+ if (!bs) {
+ error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+ return;
+ }
+
+ drv = drive_get_by_blockdev(bs);
+ if (!drv->dirty_use) {
+ error_setg(errp, "dirty tracking not enabled on device '%s'", device);
+ return;
+ }
+
+ if (has_force && force) {
+ bdrv_disable_persistent_dirty_tracking(bs);
+ }
+
+ bdrv_disable_dirty_tracking(bs);
+ drv->dirty_use = false;
+}
+
static BlockJob *find_block_job(const char *device)
{
BlockDriverState *bs;
diff --git a/blockdev.h b/blockdev.h
index 5f27b64..deb5bbf 100644
--- a/blockdev.h
+++ b/blockdev.h
@@ -38,6 +38,7 @@ struct DriveInfo {
const char *serial;
QTAILQ_ENTRY(DriveInfo) next;
int refcount;
+ int dirty_use;
};
DriveInfo *drive_get(BlockInterfaceType type, int bus, int unit);
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 010b8c9..349cd0d 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1025,6 +1025,45 @@ using the specified target.
ETEXI
{
+ .name = "dirty_enable",
+ .args_type = "device:B,file:s,granularity:i?",
+ .params = "device file [granularity]",
+ "Defaults to MB if no size suffix is specified, ie. B/K/M/G/T",
+ .help = "initiates tracking of\n\t\t\t"
+ "dirty blocks for a block device.",
+ .mhandler.cmd = hmp_dirty_enable,
+ },
+STEXI
+@item dirty_enable
+@findex dirty_enable
+Start tracking dirty blocks for a block device. Dirty blocks will
+be written to an on-disk file, with one bit per block and an arbitrary
+granularity.
+
+If the dirty bitmap is already active, or used by something else (for
+example @command{drive_mirror}), the granularity argument must be absent
+or equal to the active granularity. The granularity must be a power-of-two
+comprised between 4,096 and 67,108,864.
+ETEXI
+
+ {
+ .name = "dirty_disable",
+ .args_type = "force:-f,device:B",
+ .params = "[-f] device",
+ .help = "prepares to disable tracking\n\t\t\t"
+ "dirty blocks of a block device.",
+ .mhandler.cmd = hmp_dirty_disable,
+ },
+STEXI
+@item dirty_disable
+@findex dirty_disable
+Prepare QEMU to stop tracking dirty blocks for a block device. The
+actual end of dirty tracking could be delayed while the dirty bitmap
+is in use by another command such as @command{drive_mirror}, unless
+the @option{-f} option is used.
+ETEXI
+
+ {
.name = "drive_add",
.args_type = "pci_addr:s,opts:s",
.params = "[[<domain>:]<bus>:]<slot>\n"
diff --git a/hmp.c b/hmp.c
index 428c563..e3d2c47 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1335,3 +1335,30 @@ void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
qmp_nbd_server_stop(&errp);
hmp_handle_error(mon, &errp);
}
+
+void hmp_dirty_enable(Monitor *mon, const QDict *qdict)
+{
+ const char *device = qdict_get_str(qdict, "device");
+ const char *file = qdict_get_str(qdict, "file");
+ bool has_granularity = qdict_haskey(qdict, "granularity");
+ int granularity = -1;
+ Error *errp = NULL;
+
+ if (has_granularity) {
+ granularity = qdict_get_int(qdict, "granularity");
+ }
+
+ qmp_blockdev_dirty_enable(device, file,
+ has_granularity, granularity, &errp);
+ hmp_handle_error(mon, &errp);
+}
+
+void hmp_dirty_disable(Monitor *mon, const QDict *qdict)
+{
+ const char *device = qdict_get_str(qdict, "device");
+ bool force = qdict_get_try_bool(qdict, "force", false);
+ Error *errp = NULL;
+
+ qmp_blockdev_dirty_disable(device, true, force, &errp);
+ hmp_handle_error(mon, &errp);
+}
diff --git a/hmp.h b/hmp.h
index 0ab03be..7408e45 100644
--- a/hmp.h
+++ b/hmp.h
@@ -80,5 +80,7 @@ void hmp_screen_dump(Monitor *mon, const QDict *qdict);
void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
+void hmp_dirty_enable(Monitor *mon, const QDict *qdict);
+void hmp_dirty_disable(Monitor *mon, const QDict *qdict);
#endif
diff --git a/qapi-schema.json b/qapi-schema.json
index fb38106..cdf3772 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -3028,3 +3028,59 @@
# Since: 1.3.0
##
{ 'command': 'nbd-server-stop' }
+
+##
+# @blockdev-dirty-enable:
+#
+# Start tracking dirty blocks for a block device. Dirty blocks will
+# be written to an on-disk file, with one bit per block and an arbitrary
+# granularity. If the file already exists, the dirty bitmap is loaded
+# from the file.
+#
+# It is not an error to use this command if the dirty bitmap is already
+# active; the dirty blocks will simply be written to a new file from this
+# point on.
+#
+# If the dirty bitmap is already active, or used by something else (for
+# example drive-mirror), the granularity argument must be absent or equal
+# to the active granularity. Also, in this case the file must not exist.
+#
+# @device: the name of the device to track dirty blocks of
+#
+# @filename: the name of the file to write the bitmap to
+#
+# @granularity: #optional granularity of the dirty bitmap, default is 64K
+# if the image format doesn't have clusters, 4K if the clusters
+# are smaller than that, else the cluster size. Must be a
+# power of 2 between 512 and 64M.
+#
+# Returns: Nothing on success
+#
+# Since: 1.3
+##
+{ 'command': 'blockdev-dirty-enable',
+ 'data': {'device': 'str', 'filename': 'str', '*granularity': 'uint32' } }
+
+##
+# @blockdev-dirty-disable:
+#
+# Stop tracking dirty blocks for a block device. Dirty blocks will
+# be written to an on-disk file, with one bit per block and an arbitrary
+# granularity.
+#
+# If the dirty bitmap is already active, or used by something else (for
+# example blockdev-drive-mirror), the granularity argument must be absent
+# or equal to the active granularity.
+#
+# @device: the name of the device to track dirty blocks of
+#
+# @force: #optional true to immediately stop writing to the dirty
+# bitmap file; false to do so only when the last user of the
+# dirty bitmap stops using it (default false)
+#
+# Returns: Nothing on success
+#
+# Since: 1.3
+##
+{ 'command': 'blockdev-dirty-disable',
+ 'data': {'device': 'str', '*force': 'bool'} }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 97c52c9..e0fde11 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -2589,6 +2589,71 @@ EQMP
},
{
+ .name = "blockdev-dirty-enable",
+ .args_type = "device:s,file:s,granularity:i?",
+ .mhandler.cmd_new = qmp_marshal_input_blockdev_dirty_enable,
+ },
+SQMP
+blockdev-dirty-enable
+---------------------
+
+Start tracking dirty blocks for a block device. Dirty blocks will
+be written to an on-disk file, with one bit per block and an arbitrary
+granularity. If the file already exists, the dirty bitmap is loaded
+from the file.
+
+It is not an error to use this command if the dirty bitmap is already
+active; the dirty blocks will simply be written to a new file from this
+point on.
+
+If the dirty bitmap is already active, or used by something else (for
+example blockdev-drive-mirror), the granularity argument must be absent
+or equal to the active granularity. Also, in this case the file must
+not exist.
+
+Arguments:
+
+- device: device name (json-string)
+- file: path to the dirty tracking file (json-string)
+- granularity: granularity of the dirty bitmap (json-int, optional,
+ must be a power of two between 512 and 64M.
+
+The default value of the granularity is, if the image format defines
+a cluster size, the cluster size or 4096, whichever is larger. If it
+does not define a cluster size, the default value of the granularity
+is 65536.
+
+Example:
+
+-> { "execute": "blockdev-dirty-enable", "arguments": {
+ "device": "ide0-hd0", "path": "/var/lib/libvirt/dirty/image.dbmp" } }
+<- { "return": {} }
+EQMP
+
+ {
+ .name = "blockdev-dirty-disable",
+ .args_type = "device:s,force:b",
+ .mhandler.cmd_new = qmp_marshal_input_blockdev_dirty_disable,
+ },
+SQMP
+blockdev-dirty-disable
+----------------------
+
+Arguments:
+
+- device: device name (json-string)
+- force: true to immediately stop writing to the dirty bitmap file;
+ false to do so only when the last user of the dirty bitmap stops using
+ it (json-boolean).
+
+Example:
+
+-> { "execute": "blockdev-dirty-disable", "arguments": {
+ "device": "ide0-hd0", "force": false } }
+<- { "return": {} }
+EQMP
+
+ {
.name = "query-block-jobs",
.args_type = "",
.mhandler.cmd_new = qmp_marshal_input_query_block_jobs,
--
1.8.0.1
next prev parent reply other threads:[~2012-12-12 13:48 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-12 13:46 [Qemu-devel] [PATCH 00/20] Block device mirroring enhancements, 12-12-12 edition Paolo Bonzini
2012-12-12 13:46 ` [Qemu-devel] [PATCH 01/20] host-utils: add ffsl Paolo Bonzini
2012-12-12 23:41 ` Eric Blake
2012-12-12 13:46 ` [Qemu-devel] [PATCH 02/20] add hierarchical bitmap data type and test cases Paolo Bonzini
2012-12-14 0:04 ` Eric Blake
2013-01-11 18:27 ` Stefan Hajnoczi
2012-12-12 13:46 ` [Qemu-devel] [PATCH 03/20] block: implement dirty bitmap using HBitmap Paolo Bonzini
2012-12-14 0:27 ` Eric Blake
2012-12-12 13:46 ` [Qemu-devel] [PATCH 04/20] block: make round_to_clusters public Paolo Bonzini
2012-12-14 20:13 ` Eric Blake
2012-12-12 13:46 ` [Qemu-devel] [PATCH 05/20] mirror: perform COW if the cluster size is bigger than the granularity Paolo Bonzini
2012-12-14 20:21 ` Eric Blake
2012-12-12 13:46 ` [Qemu-devel] [PATCH 06/20] block: return count of dirty sectors, not chunks Paolo Bonzini
2012-12-14 20:49 ` Eric Blake
2012-12-12 13:46 ` [Qemu-devel] [PATCH 07/20] block: allow customizing the granularity of the dirty bitmap Paolo Bonzini
2012-12-14 21:27 ` Eric Blake
2012-12-15 9:11 ` Paolo Bonzini
2012-12-12 13:46 ` [Qemu-devel] [PATCH 08/20] mirror: allow customizing the granularity Paolo Bonzini
2012-12-14 22:01 ` Eric Blake
2013-01-14 11:28 ` Stefan Hajnoczi
2012-12-12 13:46 ` [Qemu-devel] [PATCH 09/20] mirror: switch mirror_iteration to AIO Paolo Bonzini
2012-12-14 22:11 ` Eric Blake
2012-12-15 9:09 ` Paolo Bonzini
2012-12-15 13:05 ` Eric Blake
2012-12-12 13:46 ` [Qemu-devel] [PATCH 10/20] mirror: add buf-size argument to drive-mirror Paolo Bonzini
2012-12-14 22:22 ` Eric Blake
2012-12-15 9:09 ` Paolo Bonzini
2013-01-14 11:41 ` Stefan Hajnoczi
2012-12-12 13:46 ` [Qemu-devel] [PATCH 11/20] mirror: support more than one in-flight AIO operation Paolo Bonzini
2012-12-14 22:32 ` Eric Blake
2013-01-14 12:56 ` Stefan Hajnoczi
2013-01-14 13:28 ` Paolo Bonzini
2012-12-12 13:46 ` [Qemu-devel] [PATCH 12/20] mirror: support arbitrarily-sized iterations Paolo Bonzini
2012-12-14 22:39 ` Eric Blake
2012-12-12 13:46 ` [Qemu-devel] [PATCH 13/20] oslib: add a wrapper for mmap/munmap Paolo Bonzini
2012-12-14 22:54 ` Eric Blake
2012-12-15 9:06 ` Paolo Bonzini
2012-12-12 13:46 ` [Qemu-devel] [PATCH 14/20] hbitmap: add hbitmap_alloc_with_data and hbitmap_required_size Paolo Bonzini
2012-12-17 17:14 ` Eric Blake
2012-12-17 17:18 ` Paolo Bonzini
2012-12-12 13:46 ` [Qemu-devel] [PATCH 15/20] hbitmap: add hbitmap_copy Paolo Bonzini
2012-12-17 18:25 ` Eric Blake
2012-12-12 13:46 ` [Qemu-devel] [PATCH 16/20] block: split bdrv_enable_dirty_tracking and bdrv_disable_dirty_tracking Paolo Bonzini
2012-12-20 18:26 ` Eric Blake
2012-12-12 13:46 ` [Qemu-devel] [PATCH 17/20] block: support a persistent dirty bitmap Paolo Bonzini
2012-12-20 23:03 ` Eric Blake
2012-12-12 13:46 ` [Qemu-devel] [PATCH 18/20] mirror: add support for " Paolo Bonzini
2012-12-20 23:49 ` Eric Blake
2012-12-12 13:46 ` [Qemu-devel] [PATCH 19/20] block: choose the default dirty bitmap granularity in bdrv_enable_dirty_tracking Paolo Bonzini
2012-12-20 23:53 ` Eric Blake
2012-12-12 13:46 ` Paolo Bonzini [this message]
2012-12-21 18:30 ` [Qemu-devel] [PATCH 20/20] monitor: add commands to start/stop dirty bitmap Eric Blake
2013-01-14 13:02 ` [Qemu-devel] [PATCH 00/20] Block device mirroring enhancements, 12-12-12 edition Stefan Hajnoczi
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=1355319999-30627-21-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=jcody@redhat.com \
--cc=kwolf@redhat.com \
--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).