On Thu, Apr 21, 2011 at 02:43:07PM +0800, Lai Jiangshan wrote: > > > Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxx> > --- > 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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list