mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 06:35:24 +00:00
Qemu arbitrary monitor commands.
Implement the qemu driver's virDomainQemuMonitorCommand and hook it into the API entry point. Changes since v1: - Rename the (external) qemuMonitorCommand to qemuDomainMonitorCommand - Add virCheckFlags to qemuDomainMonitorCommand Changes since v2: - Drop ATTRIBUTE_UNUSED from the flags Changes since v3: - Add a flag to priv so we only print out monitor command warning once. Note that this has not been plumbed into qemuDomainObjPrivateXMLFormat or qemuDomainObjPrivateXMLParse, which means that if you run a monitor command, restart libvirtd, and then run another monitor command, you may get an an erroneous VIR_INFO. It's a pretty minor matter, and I didn't think it warranted the additional code. - Add BeginJob/EndJob calls around EnterMonitor/ExitMonitor Signed-off-by: Chris Lalancette <clalance@redhat.com>
This commit is contained in:
parent
21adf03c2d
commit
057e855324
@ -121,6 +121,7 @@ struct _qemuDomainObjPrivate {
|
|||||||
qemuMonitorPtr mon;
|
qemuMonitorPtr mon;
|
||||||
virDomainChrDefPtr monConfig;
|
virDomainChrDefPtr monConfig;
|
||||||
int monJSON;
|
int monJSON;
|
||||||
|
int monitor_warned;
|
||||||
|
|
||||||
int nvcpupids;
|
int nvcpupids;
|
||||||
int *vcpupids;
|
int *vcpupids;
|
||||||
@ -3716,6 +3717,8 @@ static int qemudStartVMDaemon(virConnectPtr conn,
|
|||||||
#endif
|
#endif
|
||||||
priv->monJSON = 0;
|
priv->monJSON = 0;
|
||||||
|
|
||||||
|
priv->monitor_warned = 0;
|
||||||
|
|
||||||
if ((ret = virFileDeletePid(driver->stateDir, vm->def->name)) != 0) {
|
if ((ret = virFileDeletePid(driver->stateDir, vm->def->name)) != 0) {
|
||||||
virReportSystemError(ret,
|
virReportSystemError(ret,
|
||||||
_("Cannot remove stale PID file for %s"),
|
_("Cannot remove stale PID file for %s"),
|
||||||
@ -12561,6 +12564,57 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int qemuDomainMonitorCommand(virDomainPtr domain, const char *cmd,
|
||||||
|
char **result, 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 (!priv->monitor_warned) {
|
||||||
|
VIR_INFO("Qemu monitor command '%s' executed; libvirt results may be unpredictable!",
|
||||||
|
cmd);
|
||||||
|
priv->monitor_warned = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
qemuDomainObjEnterMonitorWithDriver(driver, vm);
|
||||||
|
ret = qemuMonitorArbitraryCommand(priv->mon, cmd, result);
|
||||||
|
qemuDomainObjExitMonitorWithDriver(driver, vm);
|
||||||
|
if (qemuDomainObjEndJob(vm) == 0) {
|
||||||
|
vm = NULL;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (vm)
|
||||||
|
virDomainObjUnlock(vm);
|
||||||
|
qemuDriverUnlock(driver);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static virDriver qemuDriver = {
|
static virDriver qemuDriver = {
|
||||||
VIR_DRV_QEMU,
|
VIR_DRV_QEMU,
|
||||||
"QEMU",
|
"QEMU",
|
||||||
@ -12660,7 +12714,7 @@ static virDriver qemuDriver = {
|
|||||||
qemuDomainSnapshotCurrent, /* domainSnapshotCurrent */
|
qemuDomainSnapshotCurrent, /* domainSnapshotCurrent */
|
||||||
qemuDomainRevertToSnapshot, /* domainRevertToSnapshot */
|
qemuDomainRevertToSnapshot, /* domainRevertToSnapshot */
|
||||||
qemuDomainSnapshotDelete, /* domainSnapshotDelete */
|
qemuDomainSnapshotDelete, /* domainSnapshotDelete */
|
||||||
NULL, /* qemuDomainMonitorCommand */
|
qemuDomainMonitorCommand, /* qemuDomainMonitorCommand */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1918,3 +1918,16 @@ int qemuMonitorDeleteSnapshot(qemuMonitorPtr mon, const char *name)
|
|||||||
ret = qemuMonitorTextDeleteSnapshot(mon, name);
|
ret = qemuMonitorTextDeleteSnapshot(mon, name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qemuMonitorArbitraryCommand(qemuMonitorPtr mon, const char *cmd, char **reply)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
DEBUG("mon=%p, cmd=%s, reply=%p", mon, cmd, reply);
|
||||||
|
|
||||||
|
if (mon->json)
|
||||||
|
ret = qemuMonitorJSONArbitraryCommand(mon, cmd, reply);
|
||||||
|
else
|
||||||
|
ret = qemuMonitorTextArbitraryCommand(mon, cmd, reply);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -389,4 +389,6 @@ int qemuMonitorCreateSnapshot(qemuMonitorPtr mon, const char *name);
|
|||||||
int qemuMonitorLoadSnapshot(qemuMonitorPtr mon, const char *name);
|
int qemuMonitorLoadSnapshot(qemuMonitorPtr mon, const char *name);
|
||||||
int qemuMonitorDeleteSnapshot(qemuMonitorPtr mon, const char *name);
|
int qemuMonitorDeleteSnapshot(qemuMonitorPtr mon, const char *name);
|
||||||
|
|
||||||
|
int qemuMonitorArbitraryCommand(qemuMonitorPtr mon, const char *cmd, char **reply);
|
||||||
|
|
||||||
#endif /* QEMU_MONITOR_H */
|
#endif /* QEMU_MONITOR_H */
|
||||||
|
@ -2345,3 +2345,31 @@ int qemuMonitorJSONDeleteSnapshot(qemuMonitorPtr mon, const char *name)
|
|||||||
virJSONValueFree(reply);
|
virJSONValueFree(reply);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
|
||||||
|
const char *cmd_str,
|
||||||
|
char **reply_str)
|
||||||
|
{
|
||||||
|
virJSONValuePtr cmd = NULL;
|
||||||
|
virJSONValuePtr reply = NULL;
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
cmd = virJSONValueFromString(cmd_str);
|
||||||
|
if (!cmd)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
*reply_str = virJSONValueToString(reply);
|
||||||
|
if (!(*reply_str))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virJSONValueFree(cmd);
|
||||||
|
virJSONValueFree(reply);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -196,4 +196,8 @@ int qemuMonitorJSONCreateSnapshot(qemuMonitorPtr mon, const char *name);
|
|||||||
int qemuMonitorJSONLoadSnapshot(qemuMonitorPtr mon, const char *name);
|
int qemuMonitorJSONLoadSnapshot(qemuMonitorPtr mon, const char *name);
|
||||||
int qemuMonitorJSONDeleteSnapshot(qemuMonitorPtr mon, const char *name);
|
int qemuMonitorJSONDeleteSnapshot(qemuMonitorPtr mon, const char *name);
|
||||||
|
|
||||||
|
int qemuMonitorJSONArbitraryCommand(qemuMonitorPtr mon,
|
||||||
|
const char *cmd_str,
|
||||||
|
char **reply_str);
|
||||||
|
|
||||||
#endif /* QEMU_MONITOR_JSON_H */
|
#endif /* QEMU_MONITOR_JSON_H */
|
||||||
|
@ -2567,3 +2567,24 @@ cleanup:
|
|||||||
VIR_FREE(reply);
|
VIR_FREE(reply);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char *cmd,
|
||||||
|
char **reply)
|
||||||
|
{
|
||||||
|
char *safecmd = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!(safecmd = qemuMonitorEscapeArg(cmd))) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = qemuMonitorCommand(mon, safecmd, reply);
|
||||||
|
if (ret != 0)
|
||||||
|
qemuReportError(VIR_ERR_OPERATION_FAILED,
|
||||||
|
_("failed to run cmd '%s'"), safecmd);
|
||||||
|
|
||||||
|
VIR_FREE(safecmd);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@ -194,4 +194,7 @@ int qemuMonitorTextCreateSnapshot(qemuMonitorPtr mon, const char *name);
|
|||||||
int qemuMonitorTextLoadSnapshot(qemuMonitorPtr mon, const char *name);
|
int qemuMonitorTextLoadSnapshot(qemuMonitorPtr mon, const char *name);
|
||||||
int qemuMonitorTextDeleteSnapshot(qemuMonitorPtr mon, const char *name);
|
int qemuMonitorTextDeleteSnapshot(qemuMonitorPtr mon, const char *name);
|
||||||
|
|
||||||
|
int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char *cmd,
|
||||||
|
char **reply);
|
||||||
|
|
||||||
#endif /* QEMU_MONITOR_TEXT_H */
|
#endif /* QEMU_MONITOR_TEXT_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user