提交 aedfcce3 编写于 作者: A Andres Lagar-Cavilla 提交者: Michal Privoznik

Add RESUME event listener to qemu monitor.

Perform all the appropriate plumbing.

When qemu/KVM VMs are paused manually through a monitor not-owned by libvirt,
libvirt will think of them as "paused" event after they are resumed and
effectively running. With this patch the discrepancy goes away.

This is meant to address bug 892791.
Signed-off-by: NAndres Lagar-Cavilla <andres@lagarcavilla.org>
上级 3b54b2e3
......@@ -1022,6 +1022,16 @@ int qemuMonitorEmitStop(qemuMonitorPtr mon)
}
int qemuMonitorEmitResume(qemuMonitorPtr mon)
{
int ret = -1;
VIR_DEBUG("mon=%p", mon);
QEMU_MONITOR_CALLBACK(mon, ret, domainResume, mon->vm);
return ret;
}
int qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset)
{
int ret = -1;
......
......@@ -97,6 +97,8 @@ struct _qemuMonitorCallbacks {
virDomainObjPtr vm);
int (*domainStop)(qemuMonitorPtr mon,
virDomainObjPtr vm);
int (*domainResume)(qemuMonitorPtr mon,
virDomainObjPtr vm);
int (*domainRTCChange)(qemuMonitorPtr mon,
virDomainObjPtr vm,
long long offset);
......@@ -187,6 +189,7 @@ int qemuMonitorEmitShutdown(qemuMonitorPtr mon);
int qemuMonitorEmitReset(qemuMonitorPtr mon);
int qemuMonitorEmitPowerdown(qemuMonitorPtr mon);
int qemuMonitorEmitStop(qemuMonitorPtr mon);
int qemuMonitorEmitResume(qemuMonitorPtr mon);
int qemuMonitorEmitRTCChange(qemuMonitorPtr mon, long long offset);
int qemuMonitorEmitWatchdog(qemuMonitorPtr mon, int action);
int qemuMonitorEmitIOError(qemuMonitorPtr mon,
......
......@@ -55,6 +55,7 @@ static void qemuMonitorJSONHandleShutdown(qemuMonitorPtr mon, virJSONValuePtr da
static void qemuMonitorJSONHandleReset(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandlePowerdown(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleStop(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleWatchdog(qemuMonitorPtr mon, virJSONValuePtr data);
static void qemuMonitorJSONHandleIOError(qemuMonitorPtr mon, virJSONValuePtr data);
......@@ -87,6 +88,7 @@ static qemuEventHandler eventHandlers[] = {
{ "DEVICE_TRAY_MOVED", qemuMonitorJSONHandleTrayChange, },
{ "POWERDOWN", qemuMonitorJSONHandlePowerdown, },
{ "RESET", qemuMonitorJSONHandleReset, },
{ "RESUME", qemuMonitorJSONHandleResume, },
{ "RTC_CHANGE", qemuMonitorJSONHandleRTCChange, },
{ "SHUTDOWN", qemuMonitorJSONHandleShutdown, },
{ "SPICE_CONNECTED", qemuMonitorJSONHandleSPICEConnect, },
......@@ -589,6 +591,11 @@ static void qemuMonitorJSONHandleStop(qemuMonitorPtr mon, virJSONValuePtr data A
qemuMonitorEmitStop(mon);
}
static void qemuMonitorJSONHandleResume(qemuMonitorPtr mon, virJSONValuePtr data ATTRIBUTE_UNUSED)
{
qemuMonitorEmitResume(mon);
}
static void qemuMonitorJSONHandleRTCChange(qemuMonitorPtr mon, virJSONValuePtr data)
{
long long offset = 0;
......
......@@ -735,6 +735,61 @@ unlock:
}
static int
qemuProcessHandleResume(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm)
{
virQEMUDriverPtr driver = qemu_driver;
virDomainEventPtr event = NULL;
virDomainObjLock(vm);
if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
qemuDomainObjPrivatePtr priv = vm->privateData;
if (priv->gotShutdown) {
VIR_DEBUG("Ignoring RESUME event after SHUTDOWN");
goto unlock;
}
VIR_DEBUG("Transitioned guest %s out of paused into resumed state",
vm->def->name);
virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
VIR_DOMAIN_RUNNING_UNPAUSED);
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_RESUMED,
VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
VIR_DEBUG("Using lock state '%s' on resume event", NULLSTR(priv->lockState));
if (virDomainLockProcessResume(driver->lockManager, driver->uri,
vm, priv->lockState) < 0) {
/* Don't free priv->lockState on error, because we need
* to make sure we have state still present if the user
* tries to resume again
*/
goto unlock;
}
VIR_FREE(priv->lockState);
if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0) {
VIR_WARN("Unable to save status on vm %s after state change",
vm->def->name);
}
}
unlock:
virDomainObjUnlock(vm);
if (event) {
qemuDriverLock(driver);
qemuDomainEventQueue(driver, event);
qemuDriverUnlock(driver);
}
return 0;
}
static int
qemuProcessHandleRTCChange(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
virDomainObjPtr vm,
......@@ -1250,6 +1305,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
.diskSecretLookup = qemuProcessFindVolumeQcowPassphrase,
.domainShutdown = qemuProcessHandleShutdown,
.domainStop = qemuProcessHandleStop,
.domainResume = qemuProcessHandleResume,
.domainReset = qemuProcessHandleReset,
.domainRTCChange = qemuProcessHandleRTCChange,
.domainWatchdog = qemuProcessHandleWatchdog,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册