mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 03:12:22 +00:00
qemu,inject-nmi: Implement the driver methods
This commit is contained in:
parent
a083d44c87
commit
fcf967f2ad
@ -1705,6 +1705,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)
|
||||
{
|
||||
@ -7192,7 +7236,7 @@ static virDriver qemuDriver = {
|
||||
qemuDomainSnapshotDelete, /* domainSnapshotDelete */
|
||||
qemuDomainMonitorCommand, /* qemuDomainMonitorCommand */
|
||||
qemuDomainOpenConsole, /* domainOpenConsole */
|
||||
NULL, /* domainInjectNMI */
|
||||
qemuDomainInjectNMI, /* domainInjectNMI */
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -204,4 +204,5 @@ int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
|
||||
char **reply_str,
|
||||
bool hmp);
|
||||
|
||||
int qemuMonitorJSONInjectNMI(qemuMonitorPtr mon);
|
||||
#endif /* QEMU_MONITOR_JSON_H */
|
||||
|
@ -2628,3 +2628,31 @@ int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char *cmd,
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qemuMonitorTextInjectNMI(qemuMonitorPtr mon)
|
||||
{
|
||||
const char *cmd = "inject-nmi";
|
||||
char *reply = NULL;
|
||||
|
||||
if (qemuMonitorHMPCommand(mon, cmd, &reply) < 0)
|
||||
goto fail;
|
||||
|
||||
if (strstr(reply, "unknown command") != NULL) {
|
||||
VIR_FREE(reply);
|
||||
|
||||
/* fallback to 'nmi' if qemu has not supported "inject-nmi" yet. */
|
||||
cmd = "nmi 0";
|
||||
reply = NULL;
|
||||
if (qemuMonitorHMPCommand(mon, cmd, &reply) < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
VIR_FREE(reply);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
qemuReportError(VIR_ERR_OPERATION_FAILED,
|
||||
_("failed to inject NMI using command '%s'"),
|
||||
cmd);
|
||||
return -1;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user