[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 20/20] monitor: add commands to start/stop dirty bit
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH 20/20] monitor: add commands to start/stop dirty bitmap |
Date: |
Wed, 12 Dec 2012 14:46:39 +0100 |
Signed-off-by: Paolo Bonzini <address@hidden>
---
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
address@hidden dirty_enable
address@hidden 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
address@hidden dirty_disable
address@hidden 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
- [Qemu-devel] [PATCH 16/20] block: split bdrv_enable_dirty_tracking and bdrv_disable_dirty_tracking, (continued)
- [Qemu-devel] [PATCH 16/20] block: split bdrv_enable_dirty_tracking and bdrv_disable_dirty_tracking, Paolo Bonzini, 2012/12/12
- [Qemu-devel] [PATCH 18/20] mirror: add support for persistent dirty bitmap, Paolo Bonzini, 2012/12/12
- [Qemu-devel] [PATCH 19/20] block: choose the default dirty bitmap granularity in bdrv_enable_dirty_tracking, Paolo Bonzini, 2012/12/12
- [Qemu-devel] [PATCH 01/20] host-utils: add ffsl, Paolo Bonzini, 2012/12/12
- [Qemu-devel] [PATCH 17/20] block: support a persistent dirty bitmap, Paolo Bonzini, 2012/12/12
- [Qemu-devel] [PATCH 20/20] monitor: add commands to start/stop dirty bitmap,
Paolo Bonzini <=