[libvirt] [PATCHv4 09/18] blockjob: expose qemu commands for mirrored storage migration
Jiri Denemark
jdenemar at redhat.com
Fri Apr 13 12:31:08 UTC 2012
On Mon, Apr 09, 2012 at 21:52:18 -0600, Eric Blake wrote:
> As mentioned several commits ago when the capability bits were added,
> the new block copy storage migration sequence requires both the
> 'drive-mirror' and 'drive-reopen' monitor commands.
>
> As of this[1] qemu email, both commands have been proposed but not yet
> incorporated into the tree; in fact, the implementation I tested with
> has changed to match this[2] email that suggested a mandatory
> 'full':'bool' argument rather than 'mode':'no-backing-file'. So there
> is a risk that qemu 1.1 will have yet another subtly different
> implementation.
> [1]https://lists.gnu.org/archive/html/qemu-devel/2012-03/msg01524.html
> [2]https://lists.gnu.org/archive/html/qemu-devel/2012-04/msg00886.html
>
> * src/qemu/qemu_monitor_json.c (qemuMonitorJSONDriveMirror)
> (qemuMonitorDriveReopen): New functions.
> * src/qemu/qemu_monitor_json.h (qemuMonitorJSONDriveMirror)
> (qemuMonitorDriveReopen): Declare them.
> * src/qemu/qemu_monitor.c (qemuMonitorDriveMirror)
> (qemuMonitorDriveReopen): New passthroughs.
> * src/qemu/qemu_monitor.h (qemuMonitorDriveMirror)
> (qemuMonitorDriveReopen): Declare them.
> ---
> src/qemu/qemu_monitor.c | 50 ++++++++++++++++++++++++++++++
> src/qemu/qemu_monitor.h | 13 ++++++++
> src/qemu/qemu_monitor_json.c | 70 ++++++++++++++++++++++++++++++++++++++++++
> src/qemu/qemu_monitor_json.h | 19 ++++++++++-
> 4 files changed, 150 insertions(+), 2 deletions(-)
>
> diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
> index e1a8d4c..969e453 100644
> --- a/src/qemu/qemu_monitor.c
> +++ b/src/qemu/qemu_monitor.c
> @@ -2685,6 +2685,32 @@ qemuMonitorDiskSnapshot(qemuMonitorPtr mon, virJSONValuePtr actions,
> return ret;
> }
>
> +/* Add the drive-mirror action to a transaction. */
> +int
> +qemuMonitorDriveMirror(qemuMonitorPtr mon, virJSONValuePtr actions,
> + const char *device, const char *file,
> + const char *format, unsigned int flags)
> +{
> + int ret = -1;
> +
> + VIR_DEBUG("mon=%p, actions=%p, device=%s, file=%s, format=%s, flags=%x",
> + mon, actions, device, file, format, flags);
> +
> + if (!mon) {
> + qemuReportError(VIR_ERR_INVALID_ARG, "%s",
> + _("monitor must not be NULL"));
> + return -1;
> + }
> +
> + if (mon->json)
> + ret = qemuMonitorJSONDriveMirror(mon, actions, device, file, format,
> + flags);
> + else
> + qemuReportError(VIR_ERR_INVALID_ARG, "%s",
> + _("drive-mirror requires JSON monitor"));
Why is this VIR_ERR_INVALID_ARG instead of VIR_ERR_CONFIG_UNSUPPORTED?
> + return ret;
> +}
> +
> /* Use the transaction QMP command to run atomic snapshot commands. */
> int
> qemuMonitorTransaction(qemuMonitorPtr mon, virJSONValuePtr actions)
> @@ -2701,6 +2727,30 @@ qemuMonitorTransaction(qemuMonitorPtr mon, virJSONValuePtr actions)
> return ret;
> }
>
> +/* Use the drive-reopen monitor command. */
> +int
> +qemuMonitorDriveReopen(qemuMonitorPtr mon, const char *device,
> + const char *file, const char *format)
> +{
> + int ret = -1;
> +
> + VIR_DEBUG("mon=%p, device=%s, file=%s, format=%s",
> + mon, device, file, format);
> +
> + if (!mon) {
> + qemuReportError(VIR_ERR_INVALID_ARG, "%s",
> + _("monitor must not be NULL"));
> + return -1;
> + }
> +
> + if (mon->json)
> + ret = qemuMonitorJSONDriveReopen(mon, device, file, format);
> + else
> + qemuReportError(VIR_ERR_INVALID_ARG, "%s",
> + _("drive-reopen requires JSON monitor"));
Likewise.
> + return ret;
> +}
> +
> int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
> const char *cmd,
> char **reply,
> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
> index 2e6ac79..0534b4a 100644
> --- a/src/qemu/qemu_monitor.h
> +++ b/src/qemu/qemu_monitor.h
> @@ -508,8 +508,21 @@ int qemuMonitorDiskSnapshot(qemuMonitorPtr mon,
> const char *file,
> const char *format,
> bool reuse);
> +
> +int qemuMonitorDriveMirror(qemuMonitorPtr mon,
> + virJSONValuePtr actions,
> + const char *device,
> + const char *file,
> + const char *format,
> + unsigned int flags)
> + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
> int qemuMonitorTransaction(qemuMonitorPtr mon, virJSONValuePtr actions)
> ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
> +int qemuMonitorDriveReopen(qemuMonitorPtr mon,
> + const char *device,
> + const char *file,
> + const char *format)
> + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
>
> int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
> const char *cmd,
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index aea3765..89f0eb8 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -3189,6 +3189,49 @@ cleanup:
> }
>
> int
> +qemuMonitorJSONDriveMirror(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
> + virJSONValuePtr actions,
> + const char *device, const char *file,
> + const char *format, unsigned int flags)
> +{
> + int ret = -1;
> + virJSONValuePtr cmd;
> + virJSONValuePtr reply = NULL;
> + bool shallow = (flags & VIR_DOMAIN_BLOCK_REBASE_SHALLOW) != 0;
> + bool reuse = (flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT) != 0;
> +
> + cmd = qemuMonitorJSONMakeCommandRaw(actions != NULL,
> + "drive-mirror",
> + "s:device", device,
> + "s:target", file,
> + "b:full", !shallow,
> + "s:mode",
> + reuse ? "existing" : "absolute-paths",
> + format ? "s:format" : NULL, format,
> + NULL);
> + if (!cmd)
> + return -1;
> +
> + if (actions) {
> + if (virJSONValueArrayAppend(actions, cmd) < 0) {
> + virReportOOMError();
> + } else {
> + cmd = NULL;
> + ret = 0;
> + }
> + } else {
> + if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
> + goto cleanup;
> + ret = qemuMonitorJSONCheckError(cmd, reply);
> + }
> +
> +cleanup:
> + virJSONValueFree(cmd);
> + virJSONValueFree(reply);
> + return ret;
> +}
> +
> +int
> qemuMonitorJSONTransaction(qemuMonitorPtr mon, virJSONValuePtr actions)
> {
> int ret = -1;
> @@ -3216,6 +3259,33 @@ cleanup:
> return ret;
> }
>
> +int
> +qemuMonitorJSONDriveReopen(qemuMonitorPtr mon, const char *device,
> + const char *file, const char *format)
> +{
> + int ret;
> + virJSONValuePtr cmd;
> + virJSONValuePtr reply = NULL;
> +
> + cmd = qemuMonitorJSONMakeCommand("drive-reopen",
> + "s:device", device,
> + "s:new-image-file", file,
> + format ? "s:format" : NULL, format,
> + NULL);
> + if (!cmd)
> + return -1;
> +
> + if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
> + goto cleanup;
> +
> + ret = qemuMonitorJSONCheckError(cmd, reply);
> +
> +cleanup:
> + virJSONValueFree(cmd);
> + virJSONValueFree(reply);
> + return ret;
> +}
> +
> int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
> const char *cmd_str,
> char **reply_str,
> diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
> index a0f67aa..9cfae8d 100644
> --- a/src/qemu/qemu_monitor_json.h
> +++ b/src/qemu/qemu_monitor_json.h
> @@ -230,8 +230,23 @@ int qemuMonitorJSONDiskSnapshot(qemuMonitorPtr mon,
> const char *device,
> const char *file,
> const char *format,
> - bool reuse);
> -int qemuMonitorJSONTransaction(qemuMonitorPtr mon, virJSONValuePtr actions);
> + bool reuse)
> + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3)
> + ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5);
> +int qemuMonitorJSONDriveMirror(qemuMonitorPtr mon,
> + virJSONValuePtr actions,
> + const char *device,
> + const char *file,
> + const char *format,
> + unsigned int flags)
> + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
> +int qemuMonitorJSONTransaction(qemuMonitorPtr mon, virJSONValuePtr actions)
> + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
> +int qemuMonitorJSONDriveReopen(qemuMonitorPtr mon,
> + const char *device,
> + const char *file,
> + const char *format)
> + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
>
> int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
> const char *cmd_str,
OK
Jirka
More information about the libvir-list
mailing list