mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-20 07:59:00 +00:00
libxl: move domain event handler to libxl_domain
Move the domain event handler and shutdown thread out of the main driver module and into libxl_domain module Signed-off-by: Jim Fehlig <jfehlig@suse.com>
This commit is contained in:
parent
7fb36c7b8d
commit
0a840e23c2
@ -499,6 +499,185 @@ virDomainDefParserConfig libxlDomainDefParserConfig = {
|
|||||||
.devicesPostParseCallback = libxlDomainDeviceDefPostParse,
|
.devicesPostParseCallback = libxlDomainDeviceDefPostParse,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct libxlShutdownThreadInfo
|
||||||
|
{
|
||||||
|
virDomainObjPtr vm;
|
||||||
|
libxl_event *event;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
libxlDomainShutdownThread(void *opaque)
|
||||||
|
{
|
||||||
|
struct libxlShutdownThreadInfo *shutdown_info = opaque;
|
||||||
|
virDomainObjPtr vm = shutdown_info->vm;
|
||||||
|
libxlDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
libxl_event *ev = shutdown_info->event;
|
||||||
|
libxlDriverPrivatePtr driver = priv->driver;
|
||||||
|
libxl_ctx *ctx = priv->ctx;
|
||||||
|
virObjectEventPtr dom_event = NULL;
|
||||||
|
libxl_shutdown_reason xl_reason = ev->u.domain_shutdown.shutdown_reason;
|
||||||
|
virDomainShutoffReason reason = VIR_DOMAIN_SHUTOFF_SHUTDOWN;
|
||||||
|
|
||||||
|
virObjectLock(vm);
|
||||||
|
|
||||||
|
if (xl_reason == LIBXL_SHUTDOWN_REASON_POWEROFF) {
|
||||||
|
dom_event = virDomainEventLifecycleNewFromObj(vm,
|
||||||
|
VIR_DOMAIN_EVENT_STOPPED,
|
||||||
|
VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
|
||||||
|
switch ((enum virDomainLifecycleAction) vm->def->onPoweroff) {
|
||||||
|
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 if (xl_reason == LIBXL_SHUTDOWN_REASON_CRASH) {
|
||||||
|
dom_event = virDomainEventLifecycleNewFromObj(vm,
|
||||||
|
VIR_DOMAIN_EVENT_STOPPED,
|
||||||
|
VIR_DOMAIN_EVENT_STOPPED_CRASHED);
|
||||||
|
switch ((enum virDomainLifecycleCrashAction) vm->def->onCrash) {
|
||||||
|
case VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY:
|
||||||
|
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_LAST:
|
||||||
|
goto cleanup;
|
||||||
|
case VIR_DOMAIN_LIFECYCLE_CRASH_COREDUMP_DESTROY:
|
||||||
|
libxlDomainAutoCoreDump(driver, vm);
|
||||||
|
goto destroy;
|
||||||
|
case VIR_DOMAIN_LIFECYCLE_CRASH_COREDUMP_RESTART:
|
||||||
|
libxlDomainAutoCoreDump(driver, vm);
|
||||||
|
goto restart;
|
||||||
|
}
|
||||||
|
} 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:
|
||||||
|
if (dom_event) {
|
||||||
|
libxlDomainEventQueue(driver, dom_event);
|
||||||
|
dom_event = NULL;
|
||||||
|
}
|
||||||
|
libxl_domain_destroy(ctx, vm->def->id, NULL);
|
||||||
|
if (libxlDomainCleanupJob(driver, vm, reason)) {
|
||||||
|
if (!vm->persistent) {
|
||||||
|
virDomainObjListRemove(driver->domains, vm);
|
||||||
|
vm = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
restart:
|
||||||
|
if (dom_event) {
|
||||||
|
libxlDomainEventQueue(driver, dom_event);
|
||||||
|
dom_event = NULL;
|
||||||
|
}
|
||||||
|
libxl_domain_destroy(ctx, vm->def->id, NULL);
|
||||||
|
libxlDomainCleanupJob(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
|
||||||
|
libxlDomainStart(driver, vm, 0, -1);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (vm)
|
||||||
|
virObjectUnlock(vm);
|
||||||
|
if (dom_event)
|
||||||
|
libxlDomainEventQueue(driver, dom_event);
|
||||||
|
libxl_event_free(ctx, ev);
|
||||||
|
VIR_FREE(shutdown_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle previously registered domain event notification from libxenlight.
|
||||||
|
*
|
||||||
|
* Note: Xen 4.3 removed the const from the event handler signature.
|
||||||
|
* Detect which signature to use based on
|
||||||
|
* LIBXL_HAVE_NONCONST_EVENT_OCCURS_EVENT_ARG.
|
||||||
|
*/
|
||||||
|
#ifdef LIBXL_HAVE_NONCONST_EVENT_OCCURS_EVENT_ARG
|
||||||
|
# define VIR_LIBXL_EVENT_CONST /* empty */
|
||||||
|
#else
|
||||||
|
# define VIR_LIBXL_EVENT_CONST const
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void
|
||||||
|
libxlEventHandler(void *data, VIR_LIBXL_EVENT_CONST libxl_event *event)
|
||||||
|
{
|
||||||
|
virDomainObjPtr vm = data;
|
||||||
|
libxlDomainObjPrivatePtr priv = vm->privateData;
|
||||||
|
libxl_shutdown_reason xl_reason = event->u.domain_shutdown.shutdown_reason;
|
||||||
|
struct libxlShutdownThreadInfo *shutdown_info;
|
||||||
|
virThread thread;
|
||||||
|
|
||||||
|
if (event->type != LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) {
|
||||||
|
VIR_INFO("Unhandled event type %d", event->type);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Similar to the xl implementation, ignore SUSPEND. Any actions needed
|
||||||
|
* after calling libxl_domain_suspend() are handled by it's callers.
|
||||||
|
*/
|
||||||
|
if (xl_reason == LIBXL_SHUTDOWN_REASON_SUSPEND)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start a thread to handle shutdown. We don't want to be tying up
|
||||||
|
* libxl's event machinery by doing a potentially lengthy shutdown.
|
||||||
|
*/
|
||||||
|
if (VIR_ALLOC(shutdown_info) < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
shutdown_info->vm = data;
|
||||||
|
shutdown_info->event = (libxl_event *)event;
|
||||||
|
if (virThreadCreate(&thread, false, libxlDomainShutdownThread,
|
||||||
|
shutdown_info) < 0) {
|
||||||
|
/*
|
||||||
|
* Not much we can do on error here except log it.
|
||||||
|
*/
|
||||||
|
VIR_ERROR(_("Failed to create thread to handle domain shutdown"));
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* libxl_event freed in shutdown thread
|
||||||
|
*/
|
||||||
|
return;
|
||||||
|
|
||||||
|
error:
|
||||||
|
/* Cast away any const */
|
||||||
|
libxl_event_free(priv->ctx, (libxl_event *)event);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct libxl_event_hooks ev_hooks = {
|
||||||
|
.event_occurs_mask = LIBXL_EVENTMASK_ALL,
|
||||||
|
.event_occurs = libxlEventHandler,
|
||||||
|
.disaster = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
static const libxl_childproc_hooks libxl_child_hooks = {
|
static const libxl_childproc_hooks libxl_child_hooks = {
|
||||||
#ifdef LIBXL_HAVE_SIGCHLD_OWNER_SELECTIVE_REAP
|
#ifdef LIBXL_HAVE_SIGCHLD_OWNER_SELECTIVE_REAP
|
||||||
.chldowner = libxl_sigchld_owner_libxl_always_selective_reap,
|
.chldowner = libxl_sigchld_owner_libxl_always_selective_reap,
|
||||||
|
@ -128,185 +128,6 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Handle previously registered event notification from libxenlight.
|
|
||||||
*
|
|
||||||
* Note: Xen 4.3 removed the const from the event handler signature.
|
|
||||||
* Detect which signature to use based on
|
|
||||||
* LIBXL_HAVE_NONCONST_EVENT_OCCURS_EVENT_ARG.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef LIBXL_HAVE_NONCONST_EVENT_OCCURS_EVENT_ARG
|
|
||||||
# define VIR_LIBXL_EVENT_CONST /* empty */
|
|
||||||
#else
|
|
||||||
# define VIR_LIBXL_EVENT_CONST const
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct libxlShutdownThreadInfo
|
|
||||||
{
|
|
||||||
virDomainObjPtr vm;
|
|
||||||
libxl_event *event;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
libxlDomainShutdownThread(void *opaque)
|
|
||||||
{
|
|
||||||
struct libxlShutdownThreadInfo *shutdown_info = opaque;
|
|
||||||
virDomainObjPtr vm = shutdown_info->vm;
|
|
||||||
libxlDomainObjPrivatePtr priv = vm->privateData;
|
|
||||||
libxl_event *ev = shutdown_info->event;
|
|
||||||
libxlDriverPrivatePtr driver = priv->driver;
|
|
||||||
libxl_ctx *ctx = priv->ctx;
|
|
||||||
virObjectEventPtr dom_event = NULL;
|
|
||||||
libxl_shutdown_reason xl_reason = ev->u.domain_shutdown.shutdown_reason;
|
|
||||||
virDomainShutoffReason reason = VIR_DOMAIN_SHUTOFF_SHUTDOWN;
|
|
||||||
|
|
||||||
virObjectLock(vm);
|
|
||||||
|
|
||||||
if (xl_reason == LIBXL_SHUTDOWN_REASON_POWEROFF) {
|
|
||||||
dom_event = virDomainEventLifecycleNewFromObj(vm,
|
|
||||||
VIR_DOMAIN_EVENT_STOPPED,
|
|
||||||
VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
|
|
||||||
switch ((enum virDomainLifecycleAction) vm->def->onPoweroff) {
|
|
||||||
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 if (xl_reason == LIBXL_SHUTDOWN_REASON_CRASH) {
|
|
||||||
dom_event = virDomainEventLifecycleNewFromObj(vm,
|
|
||||||
VIR_DOMAIN_EVENT_STOPPED,
|
|
||||||
VIR_DOMAIN_EVENT_STOPPED_CRASHED);
|
|
||||||
switch ((enum virDomainLifecycleCrashAction) vm->def->onCrash) {
|
|
||||||
case VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY:
|
|
||||||
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_LAST:
|
|
||||||
goto cleanup;
|
|
||||||
case VIR_DOMAIN_LIFECYCLE_CRASH_COREDUMP_DESTROY:
|
|
||||||
libxlDomainAutoCoreDump(driver, vm);
|
|
||||||
goto destroy;
|
|
||||||
case VIR_DOMAIN_LIFECYCLE_CRASH_COREDUMP_RESTART:
|
|
||||||
libxlDomainAutoCoreDump(driver, vm);
|
|
||||||
goto restart;
|
|
||||||
}
|
|
||||||
} 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:
|
|
||||||
if (dom_event) {
|
|
||||||
libxlDomainEventQueue(driver, dom_event);
|
|
||||||
dom_event = NULL;
|
|
||||||
}
|
|
||||||
libxl_domain_destroy(ctx, vm->def->id, NULL);
|
|
||||||
if (libxlDomainCleanupJob(driver, vm, reason)) {
|
|
||||||
if (!vm->persistent) {
|
|
||||||
virDomainObjListRemove(driver->domains, vm);
|
|
||||||
vm = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
restart:
|
|
||||||
if (dom_event) {
|
|
||||||
libxlDomainEventQueue(driver, dom_event);
|
|
||||||
dom_event = NULL;
|
|
||||||
}
|
|
||||||
libxl_domain_destroy(ctx, vm->def->id, NULL);
|
|
||||||
libxlDomainCleanupJob(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN);
|
|
||||||
libxlDomainStart(driver, vm, 0, -1);
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (vm)
|
|
||||||
virObjectUnlock(vm);
|
|
||||||
if (dom_event)
|
|
||||||
libxlDomainEventQueue(driver, dom_event);
|
|
||||||
libxl_event_free(ctx, ev);
|
|
||||||
VIR_FREE(shutdown_info);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
libxlEventHandler(void *data, VIR_LIBXL_EVENT_CONST libxl_event *event)
|
|
||||||
{
|
|
||||||
virDomainObjPtr vm = data;
|
|
||||||
libxlDomainObjPrivatePtr priv = vm->privateData;
|
|
||||||
libxl_shutdown_reason xl_reason = event->u.domain_shutdown.shutdown_reason;
|
|
||||||
struct libxlShutdownThreadInfo *shutdown_info;
|
|
||||||
virThread thread;
|
|
||||||
|
|
||||||
if (event->type != LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) {
|
|
||||||
VIR_INFO("Unhandled event type %d", event->type);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Similar to the xl implementation, ignore SUSPEND. Any actions needed
|
|
||||||
* after calling libxl_domain_suspend() are handled by it's callers.
|
|
||||||
*/
|
|
||||||
if (xl_reason == LIBXL_SHUTDOWN_REASON_SUSPEND)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Start a thread to handle shutdown. We don't want to be tying up
|
|
||||||
* libxl's event machinery by doing a potentially lengthy shutdown.
|
|
||||||
*/
|
|
||||||
if (VIR_ALLOC(shutdown_info) < 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
shutdown_info->vm = data;
|
|
||||||
shutdown_info->event = (libxl_event *)event;
|
|
||||||
if (virThreadCreate(&thread, false, libxlDomainShutdownThread,
|
|
||||||
shutdown_info) < 0) {
|
|
||||||
/*
|
|
||||||
* Not much we can do on error here except log it.
|
|
||||||
*/
|
|
||||||
VIR_ERROR(_("Failed to create thread to handle domain shutdown"));
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* libxl_event freed in shutdown thread
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
/* Cast away any const */
|
|
||||||
libxl_event_free(priv->ctx, (libxl_event *)event);
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct libxl_event_hooks ev_hooks = {
|
|
||||||
.event_occurs_mask = LIBXL_EVENTMASK_ALL,
|
|
||||||
.event_occurs = libxlEventHandler,
|
|
||||||
.disaster = NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reconnect to running domains that were previously started/created
|
* Reconnect to running domains that were previously started/created
|
||||||
* with libxenlight driver.
|
* with libxenlight driver.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user