[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