提交 bcf0c144 编写于 作者: C Chen Fan 提交者: Eric Blake

qemu: refactor processWatchdogEvent

Split the code to make the driver workpool more generalized
上级 14e7e0ae
......@@ -170,9 +170,15 @@ struct _qemuDomainObjPrivate {
virCgroupPtr cgroup;
};
struct qemuDomainWatchdogEvent
{
typedef enum {
QEMU_PROCESS_EVENT_WATCHDOG = 0,
QEMU_PROCESS_EVENT_LAST
} qemuProcessEventType;
struct qemuProcessEvent {
virDomainObjPtr vm;
qemuProcessEventType eventType;
int action;
};
......
......@@ -135,7 +135,11 @@
#define QEMU_NB_BANDWIDTH_PARAM 6
static void processWatchdogEvent(void *data, void *opaque);
static void processWatchdogEvent(virQEMUDriverPtr driver,
virDomainObjPtr vm,
int action);
static void qemuProcessEventHandler(void *data, void *opaque);
static int qemuStateCleanup(void);
......@@ -815,7 +819,7 @@ qemuStateInitialize(bool privileged,
qemuDomainManagedSaveLoad,
qemu_driver);
qemu_driver->workerPool = virThreadPoolNew(0, 1, 0, processWatchdogEvent, qemu_driver);
qemu_driver->workerPool = virThreadPoolNew(0, 1, 0, qemuProcessEventHandler, qemu_driver);
if (!qemu_driver->workerPool)
goto error;
......@@ -3561,17 +3565,12 @@ cleanup:
return ret;
}
static void processWatchdogEvent(void *data, void *opaque)
static void processWatchdogEvent(virQEMUDriverPtr driver, virDomainObjPtr vm, int action)
{
int ret;
struct qemuDomainWatchdogEvent *wdEvent = data;
virQEMUDriverPtr driver = opaque;
virQEMUDriverConfigPtr cfg;
virObjectLock(wdEvent->vm);
cfg = virQEMUDriverGetConfig(driver);
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
switch (wdEvent->action) {
switch (action) {
case VIR_DOMAIN_WATCHDOG_ACTION_DUMP:
{
char *dumpfile;
......@@ -3579,19 +3578,19 @@ static void processWatchdogEvent(void *data, void *opaque)
if (virAsprintf(&dumpfile, "%s/%s-%u",
cfg->autoDumpPath,
wdEvent->vm->def->name,
vm->def->name,
(unsigned int)time(NULL)) < 0) {
virReportOOMError();
goto unlock;
goto cleanup;
}
if (qemuDomainObjBeginAsyncJob(driver, wdEvent->vm,
QEMU_ASYNC_JOB_DUMP) < 0) {
if (qemuDomainObjBeginAsyncJob(driver, vm,
QEMU_ASYNC_JOB_DUMP) < 0) {
VIR_FREE(dumpfile);
goto unlock;
goto cleanup;
}
if (!virDomainObjIsActive(wdEvent->vm)) {
if (!virDomainObjIsActive(vm)) {
virReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
VIR_FREE(dumpfile);
......@@ -3599,13 +3598,13 @@ static void processWatchdogEvent(void *data, void *opaque)
}
flags |= cfg->autoDumpBypassCache ? VIR_DUMP_BYPASS_CACHE: 0;
ret = doCoreDump(driver, wdEvent->vm, dumpfile,
ret = doCoreDump(driver, vm, dumpfile,
getCompressionType(driver), flags);
if (ret < 0)
virReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("Dump failed"));
ret = qemuProcessStartCPUs(driver, wdEvent->vm, NULL,
ret = qemuProcessStartCPUs(driver, vm, NULL,
VIR_DOMAIN_RUNNING_UNPAUSED,
QEMU_ASYNC_JOB_DUMP);
......@@ -3617,22 +3616,40 @@ static void processWatchdogEvent(void *data, void *opaque)
}
break;
default:
goto unlock;
goto cleanup;
}
endjob:
/* Safe to ignore value since ref count was incremented in
* qemuProcessHandleWatchdog().
*/
ignore_value(qemuDomainObjEndAsyncJob(driver, wdEvent->vm));
ignore_value(qemuDomainObjEndAsyncJob(driver, vm));
unlock:
virObjectUnlock(wdEvent->vm);
virObjectUnref(wdEvent->vm);
VIR_FREE(wdEvent);
cleanup:
virObjectUnref(cfg);
}
static void qemuProcessEventHandler(void *data, void *opaque)
{
struct qemuProcessEvent *processEvent = data;
virDomainObjPtr vm = processEvent->vm;
virQEMUDriverPtr driver = opaque;
virObjectLock(vm);
switch (processEvent->eventType) {
case QEMU_PROCESS_EVENT_WATCHDOG:
processWatchdogEvent(driver, vm, processEvent->action);
break;
default:
break;
}
if (virObjectUnref(vm))
virObjectUnlock(vm);
VIR_FREE(processEvent);
}
static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver,
virDomainObjPtr vm,
unsigned int nvcpus)
......
......@@ -861,18 +861,19 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
}
if (vm->def->watchdog->action == VIR_DOMAIN_WATCHDOG_ACTION_DUMP) {
struct qemuDomainWatchdogEvent *wdEvent;
if (VIR_ALLOC(wdEvent) == 0) {
wdEvent->action = VIR_DOMAIN_WATCHDOG_ACTION_DUMP;
wdEvent->vm = vm;
struct qemuProcessEvent *processEvent;
if (VIR_ALLOC(processEvent) == 0) {
processEvent->eventType = QEMU_PROCESS_EVENT_WATCHDOG;
processEvent->action = VIR_DOMAIN_WATCHDOG_ACTION_DUMP;
processEvent->vm = vm;
/* Hold an extra reference because we can't allow 'vm' to be
* deleted before handling watchdog event is finished.
*/
virObjectRef(vm);
if (virThreadPoolSendJob(driver->workerPool, 0, wdEvent) < 0) {
if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
if (!virObjectUnref(vm))
vm = NULL;
VIR_FREE(wdEvent);
VIR_FREE(processEvent);
}
} else {
virReportOOMError();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册