[libvirt] [PATCH 1.1/3] qemu: Fallback to HMP when savevm QMP command is not found

Daniel P. Berrange berrange at redhat.com
Thu Mar 3 15:03:59 UTC 2011


On Fri, Feb 25, 2011 at 07:04:08PM +0100, Jiri Denemark wrote:
> qemu driver in libvirt gained support for creating domain snapshots
> almost a year ago in libvirt 0.8.0. Since then we enabled QMP support
> for qemu >= 0.13.0 but a QMP equivalent of savevm command is not
> implemented in current qemu (0.14.0) so the domain snapshot support is
> not very useful.
> 
> This patch detects when the appropriate QMP command is not implemented
> and tries to use human-monitor-command (aka HMP passthrough) to run
> savevm HMP command.
> ---
>  src/qemu/qemu_monitor_json.c |  144 +++++++++++++++++++++++++++++++++--------
>  1 files changed, 116 insertions(+), 28 deletions(-)
> 
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index e6903a1..6dd7980 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -675,6 +675,65 @@ static void qemuMonitorJSONHandleVNCDisconnect(qemuMonitorPtr mon, virJSONValueP
>  }
>  
>  
> +static int ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_FMT_PRINTF(3, 4)
> +qemuMonitorJSONHumanCommand(qemuMonitorPtr mon,
> +                            char **reply_str,
> +                            const char *fmt, ...)
> +{
> +    virJSONValuePtr cmd = NULL;
> +    virJSONValuePtr reply = NULL;
> +    virJSONValuePtr obj;
> +    char *cmd_str = NULL;
> +    va_list ap;
> +    int ret = -1;
> +
> +    va_start(ap, fmt);
> +    if (virVasprintf(&cmd_str, fmt, ap) < 0) {
> +        virReportOOMError();
> +        goto cleanup;
> +    }

This is a little dodgy because it doesn't take care of any data
escaping of special characters in the args.

> @@ -2389,6 +2448,47 @@ int qemuMonitorJSONSetDrivePassphrase(qemuMonitorPtr mon,
>      return ret;
>  }
>  
> +
> +static int
> +qemuMonitorJSONCreateSnapshotHMP(qemuMonitorPtr mon, const char *name)
> +{
> +    char *reply = NULL;
> +    int ret = -1;
> +
> +    if (qemuMonitorJSONHumanCommand(mon, &reply, "savevm \"%s\"", name) < 0) {
> +        qemuReportError(VIR_ERR_OPERATION_FAILED, "%s",
> +                        _("failed to take snapshot using HMP command"));
> +        goto cleanup;
> +    }
> +
> +    if (strstr(reply, "Error while creating snapshot")) {
> +        qemuReportError(VIR_ERR_OPERATION_FAILED,
> +                        _("failed to take snapshot: %s"), reply);
> +        goto cleanup;
> +    }
> +    else if (strstr(reply, "No block device can accept snapshots")) {
> +        qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
> +                        _("this domain does not have a device to"
> +                          " take snapshots"));
> +        goto cleanup;
> +    }
> +    else if (strstr(reply, "Could not open VM state file")) {
> +        qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", reply);
> +        goto cleanup;
> +    }
> +    else if (strstr(reply, "Error")
> +             && strstr(reply, "while writing VM")) {
> +        qemuReportError(VIR_ERR_OPERATION_FAILED, "%s", reply);
> +        goto cleanup;
> +    }
> +
> +    ret = 0;
> +
> +cleanup:
> +    VIR_FREE(reply);
> +    return ret;
> +}

Could we re-factor the  qemuMonitorTextCreateSnapshot() command so
that the code which generates the command string & the code which
checks the reply are separate callback methods. Then, this JSON
code could do something like

  static int
  qemuMonitorJSONCreateSnapshotHMP(qemuMonitorPtr mon, const char *name)
  {
    if (!(cmdstr = qemuMonitorTextMakeCreateSnapshotCommand(...)))
        return -1;

    reply = qemuMonitorJSONHumanCommand(cmdstr)
    VIR_FREE(cmdstr);
    if (!reply)
        return -1;

    if (qemuMonitorTextCheckCreateSnapshotReply(reply) < 0)
        return -1;

    return 0;
  }




Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list