mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-24 22:55:23 +00:00
libxl: Handle domain death events in a thread
Similar to domain shutdown events, processing domain death events can be a lengthy process and we don't want to block the event handler while the operation completes. Move the death handling function to a thread. Signed-off-by: Jim Fehlig <jfehlig@suse.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
e4f7589a3e
commit
b9a5faea49
@ -613,12 +613,17 @@ libxlDomainShutdownThread(void *opaque)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
libxlDomainHandleDeath(libxlDriverPrivate *driver, virDomainObj *vm)
|
libxlDomainDeathThread(void *opaque)
|
||||||
{
|
{
|
||||||
|
struct libxlEventHandlerThreadInfo *death_info = opaque;
|
||||||
|
virDomainObj *vm = death_info->vm;
|
||||||
|
libxl_event *ev = death_info->event;
|
||||||
|
libxlDriverPrivate *driver = death_info->driver;
|
||||||
virObjectEvent *dom_event = NULL;
|
virObjectEvent *dom_event = NULL;
|
||||||
|
g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver);
|
||||||
|
|
||||||
if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0)
|
if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0)
|
||||||
return;
|
goto cleanup;
|
||||||
|
|
||||||
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_DESTROYED);
|
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_DESTROYED);
|
||||||
dom_event = virDomainEventLifecycleNewFromObj(vm,
|
dom_event = virDomainEventLifecycleNewFromObj(vm,
|
||||||
@ -629,6 +634,11 @@ libxlDomainHandleDeath(libxlDriverPrivate *driver, virDomainObj *vm)
|
|||||||
virDomainObjListRemove(driver->domains, vm);
|
virDomainObjListRemove(driver->domains, vm);
|
||||||
libxlDomainObjEndJob(driver, vm);
|
libxlDomainObjEndJob(driver, vm);
|
||||||
virObjectEventStateQueue(driver->domainEventState, dom_event);
|
virObjectEventStateQueue(driver->domainEventState, dom_event);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
virDomainObjEndAPI(&vm);
|
||||||
|
libxl_event_free(cfg->ctx, ev);
|
||||||
|
VIR_FREE(death_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -642,6 +652,9 @@ libxlDomainEventHandler(void *data, libxl_event *event)
|
|||||||
libxl_shutdown_reason xl_reason = event->u.domain_shutdown.shutdown_reason;
|
libxl_shutdown_reason xl_reason = event->u.domain_shutdown.shutdown_reason;
|
||||||
virDomainObj *vm = NULL;
|
virDomainObj *vm = NULL;
|
||||||
g_autoptr(libxlDriverConfig) cfg = NULL;
|
g_autoptr(libxlDriverConfig) cfg = NULL;
|
||||||
|
struct libxlEventHandlerThreadInfo *thread_info = NULL;
|
||||||
|
virThread thread;
|
||||||
|
g_autofree char *thread_name = NULL;
|
||||||
|
|
||||||
VIR_DEBUG("Received libxl event '%d' for domid '%d'", event->type, event->domid);
|
VIR_DEBUG("Received libxl event '%d' for domid '%d'", event->type, event->domid);
|
||||||
|
|
||||||
@ -664,31 +677,27 @@ libxlDomainEventHandler(void *data, libxl_event *event)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start event-specific threads to handle shutdown and death.
|
||||||
|
* They are potentially lengthy operations and we don't want to be
|
||||||
|
* blocking this event handler while they are in progress.
|
||||||
|
*/
|
||||||
if (event->type == LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) {
|
if (event->type == LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) {
|
||||||
struct libxlEventHandlerThreadInfo *shutdown_info = NULL;
|
thread_info = g_new0(struct libxlEventHandlerThreadInfo, 1);
|
||||||
virThread thread;
|
|
||||||
g_autofree char *name = NULL;
|
|
||||||
|
|
||||||
/*
|
thread_info->driver = driver;
|
||||||
* Start a thread to handle shutdown. We don't want to be tying up
|
thread_info->vm = vm;
|
||||||
* libxl's event machinery by doing a potentially lengthy shutdown.
|
thread_info->event = (libxl_event *)event;
|
||||||
*/
|
thread_name = g_strdup_printf("shutdown-event-%d", event->domid);
|
||||||
shutdown_info = g_new0(struct libxlEventHandlerThreadInfo, 1);
|
|
||||||
|
|
||||||
shutdown_info->driver = driver;
|
|
||||||
shutdown_info->vm = vm;
|
|
||||||
shutdown_info->event = (libxl_event *)event;
|
|
||||||
name = g_strdup_printf("shutdown-event-%d", event->domid);
|
|
||||||
/*
|
/*
|
||||||
* Cleanup will be handled by the shutdown thread.
|
* Cleanup will be handled by the shutdown thread.
|
||||||
*/
|
*/
|
||||||
if (virThreadCreateFull(&thread, false, libxlDomainShutdownThread,
|
if (virThreadCreateFull(&thread, false, libxlDomainShutdownThread,
|
||||||
name, false, shutdown_info) < 0) {
|
thread_name, false, thread_info) < 0) {
|
||||||
/*
|
/*
|
||||||
* Not much we can do on error here except log it.
|
* Not much we can do on error here except log it.
|
||||||
*/
|
*/
|
||||||
VIR_ERROR(_("Failed to create thread to handle domain shutdown"));
|
VIR_ERROR(_("Failed to create thread to handle domain shutdown"));
|
||||||
VIR_FREE(shutdown_info);
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@ -697,15 +706,33 @@ libxlDomainEventHandler(void *data, libxl_event *event)
|
|||||||
*/
|
*/
|
||||||
return;
|
return;
|
||||||
} else if (event->type == LIBXL_EVENT_TYPE_DOMAIN_DEATH) {
|
} else if (event->type == LIBXL_EVENT_TYPE_DOMAIN_DEATH) {
|
||||||
|
thread_info = g_new0(struct libxlEventHandlerThreadInfo, 1);
|
||||||
|
|
||||||
|
thread_info->driver = driver;
|
||||||
|
thread_info->vm = vm;
|
||||||
|
thread_info->event = (libxl_event *)event;
|
||||||
|
thread_name = g_strdup_printf("death-event-%d", event->domid);
|
||||||
/*
|
/*
|
||||||
* On death the domain is cleaned up from Xen's perspective.
|
* Cleanup will be handled by the death thread.
|
||||||
* Cleanup on the libvirt side can be done synchronously.
|
|
||||||
*/
|
*/
|
||||||
libxlDomainHandleDeath(driver, vm);
|
if (virThreadCreateFull(&thread, false, libxlDomainDeathThread,
|
||||||
|
thread_name, false, thread_info) < 0) {
|
||||||
|
/*
|
||||||
|
* Not much we can do on error here except log it.
|
||||||
|
*/
|
||||||
|
VIR_ERROR(_("Failed to create thread to handle domain death"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* virDomainObjEndAPI is called in the death thread, where
|
||||||
|
* libxlEventHandlerThreadInfo and libxl_event are also freed.
|
||||||
|
*/
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
virDomainObjEndAPI(&vm);
|
virDomainObjEndAPI(&vm);
|
||||||
|
VIR_FREE(thread_info);
|
||||||
cfg = libxlDriverConfigGet(driver);
|
cfg = libxlDriverConfigGet(driver);
|
||||||
/* Cast away any const */
|
/* Cast away any const */
|
||||||
libxl_event_free(cfg->ctx, (libxl_event *)event);
|
libxl_event_free(cfg->ctx, (libxl_event *)event);
|
||||||
|
Loading…
Reference in New Issue
Block a user