libxl: honor domain lifecycle event configuration

The libxl driver was ignoring the <on_*> domain event configuration,
causing e.g. a domain to be rebooted even when on_reboot is set to
destroy.

This patch honors the <on_*> configuration in the shutdown event
handler.

Signed-off-by: Jim Fehlig <jfehlig@suse.com>
This commit is contained in:
Jim Fehlig 2014-02-19 15:30:43 -07:00
parent 6fb42d7cdc
commit 51b9b39127

View File

@ -368,42 +368,78 @@ libxlDomainShutdownThread(void *opaque)
libxl_ctx *ctx = priv->ctx; libxl_ctx *ctx = priv->ctx;
virObjectEventPtr dom_event = NULL; virObjectEventPtr dom_event = NULL;
libxl_shutdown_reason xl_reason = ev->u.domain_shutdown.shutdown_reason; libxl_shutdown_reason xl_reason = ev->u.domain_shutdown.shutdown_reason;
virDomainShutoffReason reason; virDomainShutoffReason reason = VIR_DOMAIN_SHUTOFF_SHUTDOWN;
virObjectLock(vm); virObjectLock(vm);
switch (xl_reason) { if (xl_reason == LIBXL_SHUTDOWN_REASON_POWEROFF) {
case LIBXL_SHUTDOWN_REASON_POWEROFF: dom_event = virDomainEventLifecycleNewFromObj(vm,
case LIBXL_SHUTDOWN_REASON_CRASH:
if (xl_reason == LIBXL_SHUTDOWN_REASON_CRASH) {
dom_event = virDomainEventLifecycleNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_CRASHED);
reason = VIR_DOMAIN_SHUTOFF_CRASHED;
} else {
dom_event = virDomainEventLifecycleNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN); VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
reason = VIR_DOMAIN_SHUTOFF_SHUTDOWN; switch ((enum virDomainLifecycleAction) vm->def->onPoweroff) {
} case VIR_DOMAIN_LIFECYCLE_DESTROY:
libxl_domain_destroy(ctx, vm->def->id, NULL); reason = VIR_DOMAIN_SHUTOFF_SHUTDOWN;
if (libxlVmCleanupJob(driver, vm, reason)) { goto destroy;
if (!vm->persistent) { case VIR_DOMAIN_LIFECYCLE_RESTART:
virDomainObjListRemove(driver->domains, vm); case VIR_DOMAIN_LIFECYCLE_RESTART_RENAME:
vm = NULL; goto restart;
} case VIR_DOMAIN_LIFECYCLE_PRESERVE:
} case VIR_DOMAIN_LIFECYCLE_LAST:
break; goto cleanup;
case LIBXL_SHUTDOWN_REASON_REBOOT: }
libxl_domain_destroy(ctx, vm->def->id, NULL); } else if (xl_reason == LIBXL_SHUTDOWN_REASON_CRASH) {
libxlVmCleanupJob(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN); dom_event = virDomainEventLifecycleNewFromObj(vm,
libxlVmStart(driver, vm, 0, -1); VIR_DOMAIN_EVENT_STOPPED,
break; VIR_DOMAIN_EVENT_STOPPED_CRASHED);
default: switch ((enum virDomainLifecycleCrashAction) vm->def->onCrash) {
VIR_INFO("Unhandled shutdown_reason %d", xl_reason); case VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY:
break; reason = VIR_DOMAIN_SHUTOFF_CRASHED;
goto destroy;
case VIR_DOMAIN_LIFECYCLE_CRASH_RESTART:
case VIR_DOMAIN_LIFECYCLE_CRASH_RESTART_RENAME:
goto restart;
case VIR_DOMAIN_LIFECYCLE_CRASH_PRESERVE:
case VIR_DOMAIN_LIFECYCLE_CRASH_COREDUMP_DESTROY:
case VIR_DOMAIN_LIFECYCLE_CRASH_COREDUMP_RESTART:
case VIR_DOMAIN_LIFECYCLE_CRASH_LAST:
goto cleanup;
}
} else if (xl_reason == LIBXL_SHUTDOWN_REASON_REBOOT) {
dom_event = virDomainEventLifecycleNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
switch ((enum virDomainLifecycleAction) vm->def->onReboot) {
case VIR_DOMAIN_LIFECYCLE_DESTROY:
reason = VIR_DOMAIN_SHUTOFF_SHUTDOWN;
goto destroy;
case VIR_DOMAIN_LIFECYCLE_RESTART:
case VIR_DOMAIN_LIFECYCLE_RESTART_RENAME:
goto restart;
case VIR_DOMAIN_LIFECYCLE_PRESERVE:
case VIR_DOMAIN_LIFECYCLE_LAST:
goto cleanup;
}
} else {
VIR_INFO("Unhandled shutdown_reason %d", xl_reason);
goto cleanup;
} }
destroy:
libxl_domain_destroy(ctx, vm->def->id, NULL);
if (libxlVmCleanupJob(driver, vm, reason)) {
if (!vm->persistent) {
virDomainObjListRemove(driver->domains, vm);
vm = NULL;
}
}
goto cleanup;
restart:
libxl_domain_destroy(ctx, vm->def->id, NULL);
libxlVmCleanupJob(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
libxlVmStart(driver, vm, 0, -1);
cleanup:
if (vm) if (vm)
virObjectUnlock(vm); virObjectUnlock(vm);
if (dom_event) if (dom_event)