提交 b060d2e5 编写于 作者: W Wen Congyang

enhance processWatchdogEvent()

This patch does the following two things:
1. hold an extra reference while handling watchdog event
   If the domain is not persistent, and qemu quits unexpectedly before
   calling processWatchdogEvent(), vm will be freed and the function
   processWatchdogEvent() will be dangerous.

2. unlock qemu driver and vm before returning from processWatchdogEvent()
   When the function processWatchdogEvent() failed, we only free wdEvent,
   but forget to unlock qemu driver and vm, free dumpfile.
上级 847efb32
......@@ -2442,6 +2442,9 @@ static void processWatchdogEvent(void *data, void *opaque)
struct qemuDomainWatchdogEvent *wdEvent = data;
struct qemud_driver *driver = opaque;
qemuDriverLock(driver);
virDomainObjLock(wdEvent->vm);
switch (wdEvent->action) {
case VIR_DOMAIN_WATCHDOG_ACTION_DUMP:
{
......@@ -2452,19 +2455,19 @@ static void processWatchdogEvent(void *data, void *opaque)
wdEvent->vm->def->name,
(unsigned int)time(NULL)) < 0) {
virReportOOMError();
break;
goto unlock;
}
qemuDriverLock(driver);
virDomainObjLock(wdEvent->vm);
if (qemuDomainObjBeginJobWithDriver(driver, wdEvent->vm) < 0)
break;
if (qemuDomainObjBeginJobWithDriver(driver, wdEvent->vm) < 0) {
VIR_FREE(dumpfile);
goto unlock;
}
if (!virDomainObjIsActive(wdEvent->vm)) {
qemuReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
break;
VIR_FREE(dumpfile);
goto endjob;
}
ret = doCoreDump(driver,
......@@ -2481,16 +2484,23 @@ static void processWatchdogEvent(void *data, void *opaque)
qemuReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("Resuming after dump failed"));
if (qemuDomainObjEndJob(wdEvent->vm) > 0)
virDomainObjUnlock(wdEvent->vm);
qemuDriverUnlock(driver);
VIR_FREE(dumpfile);
}
break;
default:
goto unlock;
}
endjob:
/* Safe to ignore value since ref count was incremented in
* qemuProcessHandleWatchdog().
*/
ignore_value(qemuDomainObjEndJob(wdEvent->vm));
unlock:
if (virDomainObjUnref(wdEvent->vm) > 0)
virDomainObjUnlock(wdEvent->vm);
qemuDriverUnlock(driver);
VIR_FREE(wdEvent);
}
......
......@@ -428,7 +428,14 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
if (VIR_ALLOC(wdEvent) == 0) {
wdEvent->action = VIR_DOMAIN_WATCHDOG_ACTION_DUMP;
wdEvent->vm = vm;
ignore_value(virThreadPoolSendJob(driver->workerPool, wdEvent));
/* Hold an extra reference because we can't allow 'vm' to be
* deleted before handling watchdog event is finished.
*/
virDomainObjRef(vm);
if (virThreadPoolSendJob(driver->workerPool, wdEvent) < 0) {
virDomainObjUnref(vm);
VIR_FREE(wdEvent);
}
} else
virReportOOMError();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册