[libvirt] [PATCH 6/6 V3] qemu, inject-nmi: Implement the driver methods

Daniel P. Berrange berrange at redhat.com
Mon May 9 16:17:22 UTC 2011


On Thu, Apr 21, 2011 at 02:43:07PM +0800, Lai Jiangshan wrote:
> 
> 
> Signed-off-by: Lai Jiangshan <laijs at cn.fujitsu.com>
> ---
>  src/qemu/qemu_driver.c       |   46 +++++++++++++++++++++++++++++++++++++++++-
>  src/qemu/qemu_monitor.c      |   14 ++++++++++++
>  src/qemu/qemu_monitor.h      |    2 +
>  src/qemu/qemu_monitor_json.c |   27 ++++++++++++++++++++++++
>  src/qemu/qemu_monitor_json.h |    1 +
>  src/qemu/qemu_monitor_text.c |   20 ++++++++++++++++++
>  src/qemu/qemu_monitor_text.h |    1 +
>  7 files changed, 110 insertions(+), 1 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index ac1adbb..548e657 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -1702,6 +1702,50 @@ static int qemudDomainSetMaxMemory(virDomainPtr dom, unsigned long memory)
>      return qemudDomainSetMemoryFlags(dom, memory, VIR_DOMAIN_MEM_MAXIMUM);
>  }
>  
> +static int qemuDomainInjectNMI(virDomainPtr domain, unsigned int flags)
> +{
> +    struct qemud_driver *driver = domain->conn->privateData;
> +    virDomainObjPtr vm = NULL;
> +    int ret = -1;
> +    qemuDomainObjPrivatePtr priv;
> +
> +    virCheckFlags(0, -1);
> +
> +    qemuDriverLock(driver);
> +    vm = virDomainFindByUUID(&driver->domains, domain->uuid);
> +    if (!vm) {
> +        char uuidstr[VIR_UUID_STRING_BUFLEN];
> +        virUUIDFormat(domain->uuid, uuidstr);
> +        qemuReportError(VIR_ERR_NO_DOMAIN,
> +                        _("no domain with matching uuid '%s'"), uuidstr);
> +        goto cleanup;
> +    }
> +
> +    if (!virDomainObjIsActive(vm)) {
> +        qemuReportError(VIR_ERR_OPERATION_INVALID,
> +                        "%s", _("domain is not running"));
> +        goto cleanup;
> +    }
> +
> +    priv = vm->privateData;
> +
> +    if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
> +        goto cleanup;
> +    qemuDomainObjEnterMonitorWithDriver(driver, vm);
> +    ret = qemuMonitorInjectNMI(priv->mon);
> +    qemuDomainObjExitMonitorWithDriver(driver, vm);
> +    if (qemuDomainObjEndJob(vm) == 0) {
> +        vm = NULL;
> +        goto cleanup;
> +    }
> +
> +cleanup:
> +    if (vm)
> +        virDomainObjUnlock(vm);
> +    qemuDriverUnlock(driver);
> +    return ret;
> +}
> +
>  static int qemudDomainGetInfo(virDomainPtr dom,
>                                virDomainInfoPtr info)
>  {
> @@ -7031,7 +7075,7 @@ static virDriver qemuDriver = {
>      qemuDomainSnapshotDelete, /* domainSnapshotDelete */
>      qemuDomainMonitorCommand, /* qemuDomainMonitorCommand */
>      qemuDomainOpenConsole, /* domainOpenConsole */
> -    NULL, /* domainInjectNMI */
> +    qemuDomainInjectNMI, /* domainInjectNMI */
>  };
>  
>  
> diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
> index 2d28f8d..5ed41e1 100644
> --- a/src/qemu/qemu_monitor.c
> +++ b/src/qemu/qemu_monitor.c
> @@ -2228,3 +2228,17 @@ int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
>          ret = qemuMonitorTextArbitraryCommand(mon, cmd, reply);
>      return ret;
>  }
> +
> +
> +int qemuMonitorInjectNMI(qemuMonitorPtr mon)
> +{
> +    int ret;
> +
> +    VIR_DEBUG("mon=%p", mon);
> +
> +    if (mon->json)
> +        ret = qemuMonitorJSONInjectNMI(mon);
> +    else
> +        ret = qemuMonitorTextInjectNMI(mon);
> +    return ret;
> +}
> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
> index c90219b..b84e230 100644
> --- a/src/qemu/qemu_monitor.h
> +++ b/src/qemu/qemu_monitor.h
> @@ -423,6 +423,8 @@ int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
>                                  char **reply,
>                                  bool hmp);
>  
> +int qemuMonitorInjectNMI(qemuMonitorPtr mon);
> +
>  /**
>   * When running two dd process and using <> redirection, we need a
>   * shell that will not truncate files.  These two strings serve that
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index 20a78e1..04ef077 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -2513,3 +2513,30 @@ cleanup:
>  
>      return ret;
>  }
> +
> +int qemuMonitorJSONInjectNMI(qemuMonitorPtr mon)
> +{
> +    int ret;
> +    virJSONValuePtr cmd;
> +    virJSONValuePtr reply = NULL;
> +
> +    cmd = qemuMonitorJSONMakeCommand("inject-nmi", NULL);
> +    if (!cmd)
> +        return -1;
> +
> +    if ((ret = qemuMonitorJSONCommand(mon, cmd, &reply)) < 0)
> +        goto cleanup;
> +
> +    if (qemuMonitorJSONHasError(reply, "CommandNotFound") &&
> +        qemuMonitorCheckHMP(mon, "inject-nmi")) {
> +        VIR_DEBUG0("inject-nmi command not found, trying HMP");
> +        ret = qemuMonitorTextInjectNMI(mon);
> +    } else {
> +        ret = qemuMonitorJSONCheckError(cmd, reply);
> +    }
> +
> +cleanup:
> +    virJSONValueFree(cmd);
> +    virJSONValueFree(reply);
> +    return ret;
> +}
> diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
> index 086f0e1..f2dc4d2 100644
> --- a/src/qemu/qemu_monitor_json.h
> +++ b/src/qemu/qemu_monitor_json.h
> @@ -204,4 +204,5 @@ int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
>                                      char **reply_str,
>                                      bool hmp);
>  
> +int qemuMonitorJSONInjectNMI(qemuMonitorPtr mon);
>  #endif /* QEMU_MONITOR_JSON_H */
> diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
> index 53781c8..2ce871c 100644
> --- a/src/qemu/qemu_monitor_text.c
> +++ b/src/qemu/qemu_monitor_text.c
> @@ -2628,3 +2628,23 @@ int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char *cmd,
>  
>      return ret;
>  }
> +
> +int qemuMonitorTextInjectNMI(qemuMonitorPtr mon)
> +{
> +    const char *cmd = "nmi 0";
> +    char *reply = NULL;
> +
> +    /*
> +     * FIXME: qemu's inject-nmi command is not introduced until qemu-0.15,
> +     * use "nmi 0" instead temporary.
> +     */

So in future if we need to support NMI in non-JSON mode, we'd want to
run 'inject-nmi' in HMP, and then check for 'unknown command', and
fallback to 'nmi'.

> +    if (qemuMonitorHMPCommand(mon, cmd, &reply) < 0) {
> +        qemuReportError(VIR_ERR_OPERATION_FAILED,
> +                         _("failed to inject NMI using command '%s'"),
> +                         cmd);
> +        return -1;
> +    }
> +
> +    VIR_FREE(reply);
> +    return 0;
> +}
> diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
> index 0838a2b..dbae72b 100644
> --- a/src/qemu/qemu_monitor_text.h
> +++ b/src/qemu/qemu_monitor_text.h
> @@ -198,4 +198,5 @@ int qemuMonitorTextDeleteSnapshot(qemuMonitorPtr mon, const char *name);
>  int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char *cmd,
>                                      char **reply);
>  
> +int qemuMonitorTextInjectNMI(qemuMonitorPtr mon);
>  #endif /* QEMU_MONITOR_TEXT_H */

ACK, since the only issue can be dealt with later

Regards,
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