diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 068a4c31ff..92bbe64a74 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -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; }; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 4856f37671..d4396b0e0c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -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; + virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); - virObjectLock(wdEvent->vm); - 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) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index ac5ffcfa04..ee39d5b391 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -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();