[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