mirror of
https://github.com/libvirt/libvirt.git
synced 2025-02-25 18:55:26 -06:00
qemu: refactor processWatchdogEvent
Split the code to make the driver workpool more generalized
This commit is contained in:
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user