mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-23 22:25:25 +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
|
||||
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;
|
||||
g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver);
|
||||
|
||||
if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0)
|
||||
return;
|
||||
goto cleanup;
|
||||
|
||||
virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_DESTROYED);
|
||||
dom_event = virDomainEventLifecycleNewFromObj(vm,
|
||||
@ -629,6 +634,11 @@ libxlDomainHandleDeath(libxlDriverPrivate *driver, virDomainObj *vm)
|
||||
virDomainObjListRemove(driver->domains, vm);
|
||||
libxlDomainObjEndJob(driver, vm);
|
||||
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;
|
||||
virDomainObj *vm = 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);
|
||||
|
||||
@ -664,31 +677,27 @@ libxlDomainEventHandler(void *data, libxl_event *event)
|
||||
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) {
|
||||
struct libxlEventHandlerThreadInfo *shutdown_info = NULL;
|
||||
virThread thread;
|
||||
g_autofree char *name = NULL;
|
||||
thread_info = g_new0(struct libxlEventHandlerThreadInfo, 1);
|
||||
|
||||
/*
|
||||
* Start a thread to handle shutdown. We don't want to be tying up
|
||||
* libxl's event machinery by doing a potentially lengthy shutdown.
|
||||
*/
|
||||
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);
|
||||
thread_info->driver = driver;
|
||||
thread_info->vm = vm;
|
||||
thread_info->event = (libxl_event *)event;
|
||||
thread_name = g_strdup_printf("shutdown-event-%d", event->domid);
|
||||
/*
|
||||
* Cleanup will be handled by the shutdown thread.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
VIR_ERROR(_("Failed to create thread to handle domain shutdown"));
|
||||
VIR_FREE(shutdown_info);
|
||||
goto cleanup;
|
||||
}
|
||||
/*
|
||||
@ -697,15 +706,33 @@ libxlDomainEventHandler(void *data, libxl_event *event)
|
||||
*/
|
||||
return;
|
||||
} 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 on the libvirt side can be done synchronously.
|
||||
* Cleanup will be handled by the death thread.
|
||||
*/
|
||||
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:
|
||||
virDomainObjEndAPI(&vm);
|
||||
VIR_FREE(thread_info);
|
||||
cfg = libxlDriverConfigGet(driver);
|
||||
/* Cast away any const */
|
||||
libxl_event_free(cfg->ctx, (libxl_event *)event);
|
||||
|
Loading…
Reference in New Issue
Block a user