qemu: refactor processWatchdogEvent

Split the code to make the driver workpool more generalized
This commit is contained in:
Chen Fan
2013-06-07 18:23:32 +08:00
committed by Eric Blake
parent 14e7e0ae8d
commit bcf0c14491
3 changed files with 56 additions and 32 deletions

View File

@@ -170,9 +170,15 @@ struct _qemuDomainObjPrivate {
virCgroupPtr cgroup; virCgroupPtr cgroup;
}; };
struct qemuDomainWatchdogEvent typedef enum {
{ QEMU_PROCESS_EVENT_WATCHDOG = 0,
QEMU_PROCESS_EVENT_LAST
} qemuProcessEventType;
struct qemuProcessEvent {
virDomainObjPtr vm; virDomainObjPtr vm;
qemuProcessEventType eventType;
int action; int action;
}; };

View File

@@ -135,7 +135,11 @@
#define QEMU_NB_BANDWIDTH_PARAM 6 #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); static int qemuStateCleanup(void);
@@ -815,7 +819,7 @@ qemuStateInitialize(bool privileged,
qemuDomainManagedSaveLoad, qemuDomainManagedSaveLoad,
qemu_driver); 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) if (!qemu_driver->workerPool)
goto error; goto error;
@@ -3561,17 +3565,12 @@ cleanup:
return ret; return ret;
} }
static void processWatchdogEvent(void *data, void *opaque) static void processWatchdogEvent(virQEMUDriverPtr driver, virDomainObjPtr vm, int action)
{ {
int ret; int ret;
struct qemuDomainWatchdogEvent *wdEvent = data; virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
virQEMUDriverPtr driver = opaque;
virQEMUDriverConfigPtr cfg;
virObjectLock(wdEvent->vm); switch (action) {
cfg = virQEMUDriverGetConfig(driver);
switch (wdEvent->action) {
case VIR_DOMAIN_WATCHDOG_ACTION_DUMP: case VIR_DOMAIN_WATCHDOG_ACTION_DUMP:
{ {
char *dumpfile; char *dumpfile;
@@ -3579,19 +3578,19 @@ static void processWatchdogEvent(void *data, void *opaque)
if (virAsprintf(&dumpfile, "%s/%s-%u", if (virAsprintf(&dumpfile, "%s/%s-%u",
cfg->autoDumpPath, cfg->autoDumpPath,
wdEvent->vm->def->name, vm->def->name,
(unsigned int)time(NULL)) < 0) { (unsigned int)time(NULL)) < 0) {
virReportOOMError(); virReportOOMError();
goto unlock; goto cleanup;
} }
if (qemuDomainObjBeginAsyncJob(driver, wdEvent->vm, if (qemuDomainObjBeginAsyncJob(driver, vm,
QEMU_ASYNC_JOB_DUMP) < 0) { QEMU_ASYNC_JOB_DUMP) < 0) {
VIR_FREE(dumpfile); VIR_FREE(dumpfile);
goto unlock; goto cleanup;
} }
if (!virDomainObjIsActive(wdEvent->vm)) { if (!virDomainObjIsActive(vm)) {
virReportError(VIR_ERR_OPERATION_INVALID, virReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running")); "%s", _("domain is not running"));
VIR_FREE(dumpfile); VIR_FREE(dumpfile);
@@ -3599,13 +3598,13 @@ static void processWatchdogEvent(void *data, void *opaque)
} }
flags |= cfg->autoDumpBypassCache ? VIR_DUMP_BYPASS_CACHE: 0; flags |= cfg->autoDumpBypassCache ? VIR_DUMP_BYPASS_CACHE: 0;
ret = doCoreDump(driver, wdEvent->vm, dumpfile, ret = doCoreDump(driver, vm, dumpfile,
getCompressionType(driver), flags); getCompressionType(driver), flags);
if (ret < 0) if (ret < 0)
virReportError(VIR_ERR_OPERATION_FAILED, virReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("Dump failed")); "%s", _("Dump failed"));
ret = qemuProcessStartCPUs(driver, wdEvent->vm, NULL, ret = qemuProcessStartCPUs(driver, vm, NULL,
VIR_DOMAIN_RUNNING_UNPAUSED, VIR_DOMAIN_RUNNING_UNPAUSED,
QEMU_ASYNC_JOB_DUMP); QEMU_ASYNC_JOB_DUMP);
@@ -3617,22 +3616,40 @@ static void processWatchdogEvent(void *data, void *opaque)
} }
break; break;
default: default:
goto unlock; goto cleanup;
} }
endjob: endjob:
/* Safe to ignore value since ref count was incremented in /* Safe to ignore value since ref count was incremented in
* qemuProcessHandleWatchdog(). * qemuProcessHandleWatchdog().
*/ */
ignore_value(qemuDomainObjEndAsyncJob(driver, wdEvent->vm)); ignore_value(qemuDomainObjEndAsyncJob(driver, vm));
unlock: cleanup:
virObjectUnlock(wdEvent->vm);
virObjectUnref(wdEvent->vm);
VIR_FREE(wdEvent);
virObjectUnref(cfg); 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, static int qemuDomainHotplugVcpus(virQEMUDriverPtr driver,
virDomainObjPtr vm, virDomainObjPtr vm,
unsigned int nvcpus) unsigned int nvcpus)

View File

@@ -861,18 +861,19 @@ qemuProcessHandleWatchdog(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
} }
if (vm->def->watchdog->action == VIR_DOMAIN_WATCHDOG_ACTION_DUMP) { if (vm->def->watchdog->action == VIR_DOMAIN_WATCHDOG_ACTION_DUMP) {
struct qemuDomainWatchdogEvent *wdEvent; struct qemuProcessEvent *processEvent;
if (VIR_ALLOC(wdEvent) == 0) { if (VIR_ALLOC(processEvent) == 0) {
wdEvent->action = VIR_DOMAIN_WATCHDOG_ACTION_DUMP; processEvent->eventType = QEMU_PROCESS_EVENT_WATCHDOG;
wdEvent->vm = vm; processEvent->action = VIR_DOMAIN_WATCHDOG_ACTION_DUMP;
processEvent->vm = vm;
/* Hold an extra reference because we can't allow 'vm' to be /* Hold an extra reference because we can't allow 'vm' to be
* deleted before handling watchdog event is finished. * deleted before handling watchdog event is finished.
*/ */
virObjectRef(vm); virObjectRef(vm);
if (virThreadPoolSendJob(driver->workerPool, 0, wdEvent) < 0) { if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
if (!virObjectUnref(vm)) if (!virObjectUnref(vm))
vm = NULL; vm = NULL;
VIR_FREE(wdEvent); VIR_FREE(processEvent);
} }
} else { } else {
virReportOOMError(); virReportOOMError();