diff --git a/23b51d7b-libxl-disable-death-event.patch b/23b51d7b-libxl-disable-death-event.patch new file mode 100644 index 0000000..acab70f --- /dev/null +++ b/23b51d7b-libxl-disable-death-event.patch @@ -0,0 +1,105 @@ +commit 23b51d7b8ec885e97a9277cf0a6c2833db4636e8 +Author: Jim Fehlig +Date: Fri Oct 29 14:16:33 2021 -0600 + + libxl: Disable death events after receiving a shutdown event + + The libxl driver will handle all domain destruction and cleanup + when receiving a domain shutdown event from libxl. Commit fa30ee04a2a + introduced the ignoreDeathEvent boolean in the DomainObjPrivate struct + to ignore subsequent death events from libxl. But libxl already provides + a mechanism to disable death events via libxl_evdisable_domain_death. + + This patch partially reverts commit fa30ee04a2a and instead uses + libxl_evdisable_domain_death to disable subsequent death events when + processing a shutdown event. + + Signed-off-by: Jim Fehlig + Reviewed-by: Daniel P. Berrangé + Reviewed-by: Ján Tomko + +Index: libvirt-7.10.0/src/libxl/libxl_domain.c +=================================================================== +--- libvirt-7.10.0.orig/src/libxl/libxl_domain.c ++++ libvirt-7.10.0/src/libxl/libxl_domain.c +@@ -616,12 +616,6 @@ static void + libxlDomainHandleDeath(libxlDriverPrivate *driver, virDomainObj *vm) + { + virObjectEvent *dom_event = NULL; +- libxlDomainObjPrivate *priv = vm->privateData; +- +- if (priv->ignoreDeathEvent) { +- priv->ignoreDeathEvent = false; +- return; +- } + + if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0) + return; +@@ -671,7 +665,6 @@ libxlDomainEventHandler(void *data, libx + } + + if (event->type == LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) { +- libxlDomainObjPrivate *priv = vm->privateData; + struct libxlShutdownThreadInfo *shutdown_info = NULL; + virThread thread; + g_autofree char *name = NULL; +@@ -688,12 +681,9 @@ libxlDomainEventHandler(void *data, libx + name = g_strdup_printf("ev-%d", event->domid); + /* + * Cleanup will be handled by the shutdown thread. +- * Ignore the forthcoming death event from libxl + */ +- priv->ignoreDeathEvent = true; + if (virThreadCreateFull(&thread, false, libxlDomainShutdownThread, + name, false, shutdown_info) < 0) { +- priv->ignoreDeathEvent = false; + /* + * Not much we can do on error here except log it. + */ +@@ -859,18 +849,17 @@ libxlDomainDestroyInternal(libxlDriverPr + libxlDomainObjPrivate *priv = vm->privateData; + int ret = -1; + +- /* Ignore next LIBXL_EVENT_TYPE_DOMAIN_DEATH as the caller will handle +- * domain death appropriately already (having more info, like the reason). +- */ +- priv->ignoreDeathEvent = true; ++ if (priv->deathW) { ++ libxl_evdisable_domain_death(cfg->ctx, priv->deathW); ++ priv->deathW = NULL; ++ } ++ + /* Unlock virDomainObj during destroy, which can take considerable + * time on large memory domains. + */ + virObjectUnlock(vm); + ret = libxl_domain_destroy(cfg->ctx, vm->def->id, NULL); + virObjectLock(vm); +- if (ret) +- priv->ignoreDeathEvent = false; + + return ret; + } +@@ -921,8 +910,6 @@ libxlDomainCleanup(libxlDriverPrivate *d + priv->deathW = NULL; + } + +- priv->ignoreDeathEvent = false; +- + if (!!g_atomic_int_dec_and_test(&driver->nactive) && driver->inhibitCallback) + driver->inhibitCallback(false, driver->inhibitOpaque); + +Index: libvirt-7.10.0/src/libxl/libxl_domain.h +=================================================================== +--- libvirt-7.10.0.orig/src/libxl/libxl_domain.h ++++ libvirt-7.10.0/src/libxl/libxl_domain.h +@@ -54,9 +54,6 @@ struct _libxlDomainObjPrivate { + /* console */ + virChrdevs *devs; + libxl_evgen_domain_death *deathW; +- /* Flag to indicate the upcoming LIBXL_EVENT_TYPE_DOMAIN_DEATH is caused +- * by libvirt and should not be handled separately */ +- bool ignoreDeathEvent; + virThread *migrationDstReceiveThr; + unsigned short migrationPort; + char *lockState; diff --git a/5c5df531-libxl-search-domid-in-thread.patch b/5c5df531-libxl-search-domid-in-thread.patch new file mode 100644 index 0000000..a421d82 --- /dev/null +++ b/5c5df531-libxl-search-domid-in-thread.patch @@ -0,0 +1,167 @@ +commit 5c5df5310f72be4878a71ace47074c54e0d1a27d +Author: Jim Fehlig +Date: Wed Nov 24 11:48:51 2021 -0700 + + libxl: Search for virDomainObj in event handler threads + + libxl can deliver events and invoke callbacks on any application thread + calling into libxl. This can cause deadlock in the libvirt libxl driver + + Thread 19 (Thread 0x7f31411ec700 (LWP 14068) "libvirtd"): + #0 0x00007f318520cc7d in __lll_lock_wait () from /lib64/libpthread.so.0 + #1 0x00007f3185205ed5 in pthread_mutex_lock () from /lib64/libpthread.so.0 + #2 0x00007f3189488015 in virMutexLock (m=) at ../../src/util/virthread.c:79 + #3 0x00007f3189463f3b in virObjectLock (anyobj=) at ../../src/util/virobject.c:433 + #4 0x00007f31894f2f41 in virDomainObjListSearchID (payload=0x7f317400a6d0, name=, data=0x7f31411eaeac) at ../../src/conf/virdomainobjlist.c:105 + #5 0x00007f3189437ac5 in virHashSearch (ctable=0x7f3124025a30, iter=iter@entry=0x7f31894f2f30 , data=data@entry=0x7f31411eaeac, name=name@entry=0x0) at ../../src/util/virhash.c:745 + #6 0x00007f31894f3919 in virDomainObjListFindByID (doms=0x7f3124025430, id=) at ../../src/conf/virdomainobjlist.c:121 + #7 0x00007f3152f292e5 in libxlDomainEventHandler (data=0x7f3124023d80, event=0x7f310c010ae0) at ../../src/libxl/libxl_domain.c:660 + #8 0x00007f3152c6ff5d in egc_run_callbacks (egc=egc@entry=0x7f31411eaf50) at libxl_event.c:1427 + #9 0x00007f3152c718bd in libxl__egc_cleanup (egc=0x7f31411eaf50) at libxl_event.c:1458 + #10 libxl__ao_inprogress (ao=ao@entry=0x7f310c00b8a0, file=file@entry=0x7f3152cce987 "libxl_domain.c", line=line@entry=730, func=func@entry=0x7f3152ccf750 <__func__.22238> "libxl_domain_unpause") at libxl_event.c:2047 + #11 0x00007f3152c8c5b8 in libxl_domain_unpause (ctx=0x7f3124015a40, domid=, ao_how=ao_how@entry=0x0) at libxl_domain.c:730 + #12 0x00007f3152f2a584 in libxl_domain_unpause_0x041200 (domid=, ctx=) at /usr/include/libxl.h:1756 + #13 libxlDomainStart (driver=driver@entry=0x7f3124023d80, vm=vm@entry=0x7f317400a6d0, start_paused=start_paused@entry=false, restore_fd=restore_fd@entry=-1, restore_ver=, restore_ver@entry=2) at ../../src/libxl/libxl_domain.c:1482 + #14 0x00007f3152f2a6e3 in libxlDomainStartNew (driver=driver@entry=0x7f3124023d80, vm=vm@entry=0x7f317400a6d0, start_paused=start_paused@entry=false) at ../../src/libxl/libxl_domain.c:1545 + #15 0x00007f3152f2a789 in libxlDomainShutdownHandleRestart (driver=0x7f3124023d80, vm=0x7f317400a6d0) at ../../src/libxl/libxl_domain.c:464 + #16 0x00007f3152f2a9e4 in libxlDomainShutdownThread (opaque=) at ../../src/libxl/libxl_domain.c:559 + #17 0x00007f3189487ee2 in virThreadHelper (data=) at ../../src/util/virthread.c:196 + #18 0x00007f3185203539 in start_thread () from /lib64/libpthread.so.0 + #19 0x00007f3184f3becf in clone () from /lib64/libc.so.6 + + Frame 16 runs a thread created to handle domain shutdown processing for + domid 28712. In this case the event contained the reboot reason, so the + old domain is destroyed and a new one is created by libxlDomainStart new. + After starting the domain, it is unpaused by calling libxl_domain_unpause + in frame 12. While the thread is running within libxl, libxl takes the + opportunity to deliver a pending domain shutdown event for unrelated domid + 28710. While searching for the associated virDomainObj by ID, a deadlock is + encountered when attempting to lock the virDomainObj for domid 28712, which + is already locked since this thread is processing its shutdown event. + + The deadlock can be avoided by moving the search for a virDomainObj + associated with the event domid to the shutdown thread. The same is done + for the death thread. + + Signed-off-by: Jim Fehlig + Reviewed-by: Daniel P. Berrangé + Reviewed-by: Ján Tomko + +Index: libvirt-7.10.0/src/libxl/libxl_domain.c +=================================================================== +--- libvirt-7.10.0.orig/src/libxl/libxl_domain.c ++++ libvirt-7.10.0/src/libxl/libxl_domain.c +@@ -480,7 +480,6 @@ libxlDomainShutdownHandleRestart(libxlDr + struct libxlEventHandlerThreadInfo + { + libxlDriverPrivate *driver; +- virDomainObj *vm; + libxl_event *event; + }; + +@@ -489,7 +488,7 @@ static void + libxlDomainShutdownThread(void *opaque) + { + struct libxlEventHandlerThreadInfo *shutdown_info = opaque; +- virDomainObj *vm = shutdown_info->vm; ++ virDomainObj *vm = NULL; + libxl_event *ev = shutdown_info->event; + libxlDriverPrivate *driver = shutdown_info->driver; + virObjectEvent *dom_event = NULL; +@@ -499,6 +498,12 @@ libxlDomainShutdownThread(void *opaque) + + libxl_domain_config_init(&d_config); + ++ vm = virDomainObjListFindByID(driver->domains, ev->domid); ++ if (!vm) { ++ /* Nothing to do if we can't find the virDomainObj */ ++ goto cleanup; ++ } ++ + if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0) + goto cleanup; + +@@ -616,12 +621,18 @@ static void + libxlDomainDeathThread(void *opaque) + { + struct libxlEventHandlerThreadInfo *death_info = opaque; +- virDomainObj *vm = death_info->vm; ++ virDomainObj *vm = NULL; + libxl_event *ev = death_info->event; + libxlDriverPrivate *driver = death_info->driver; + virObjectEvent *dom_event = NULL; + g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver); + ++ vm = virDomainObjListFindByID(driver->domains, ev->domid); ++ if (!vm) { ++ /* Nothing to do if we can't find the virDomainObj */ ++ goto cleanup; ++ } ++ + if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0) + goto cleanup; + +@@ -650,7 +661,6 @@ libxlDomainEventHandler(void *data, libx + { + libxlDriverPrivate *driver = data; + 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; +@@ -671,12 +681,6 @@ libxlDomainEventHandler(void *data, libx + if (xl_reason == LIBXL_SHUTDOWN_REASON_SUSPEND) + goto cleanup; + +- vm = virDomainObjListFindByID(driver->domains, event->domid); +- if (!vm) { +- /* Nothing to do if we can't find the virDomainObj */ +- goto cleanup; +- } +- + /* + * Start event-specific threads to handle shutdown and death. + * They are potentially lengthy operations and we don't want to be +@@ -686,7 +690,6 @@ libxlDomainEventHandler(void *data, libx + 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("shutdown-event-%d", event->domid); + /* +@@ -701,15 +704,14 @@ libxlDomainEventHandler(void *data, libx + goto cleanup; + } + /* +- * virDomainObjEndAPI is called in the shutdown thread, where +- * libxlEventHandlerThreadInfo and libxl_event are also freed. ++ * libxlEventHandlerThreadInfo and libxl_event are freed in the ++ * shutdown thread + */ + 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); + /* +@@ -724,14 +726,13 @@ libxlDomainEventHandler(void *data, libx + goto cleanup; + } + /* +- * virDomainObjEndAPI is called in the death thread, where +- * libxlEventHandlerThreadInfo and libxl_event are also freed. ++ * libxlEventHandlerThreadInfo and libxl_event are freed in the ++ * death thread + */ + return; + } + + cleanup: +- virDomainObjEndAPI(&vm); + VIR_FREE(thread_info); + cfg = libxlDriverConfigGet(driver); + /* Cast away any const */ diff --git a/a4e6fba0-libxl-rename-threadinfo-struct.patch b/a4e6fba0-libxl-rename-threadinfo-struct.patch new file mode 100644 index 0000000..a3b43f6 --- /dev/null +++ b/a4e6fba0-libxl-rename-threadinfo-struct.patch @@ -0,0 +1,63 @@ +commit a4e6fba069c0809b8b5dde5e9db62d2efd91b4a0 +Author: Jim Fehlig +Date: Wed Nov 24 11:10:19 2021 -0700 + + libxl: Rename libxlShutdownThreadInfo struct + + An upcoming change will use the struct in a thread created to process + death events. Rename libxlShutdownThreadInfo to libxlEventHandlerThreadInfo + to reflect the more generic usage. + + Signed-off-by: Jim Fehlig + Reviewed-by: Daniel P. Berrangé + Reviewed-by: Ján Tomko + +Index: libvirt-7.10.0/src/libxl/libxl_domain.c +=================================================================== +--- libvirt-7.10.0.orig/src/libxl/libxl_domain.c ++++ libvirt-7.10.0/src/libxl/libxl_domain.c +@@ -477,7 +477,7 @@ libxlDomainShutdownHandleRestart(libxlDr + } + + +-struct libxlShutdownThreadInfo ++struct libxlEventHandlerThreadInfo + { + libxlDriverPrivate *driver; + virDomainObj *vm; +@@ -488,7 +488,7 @@ struct libxlShutdownThreadInfo + static void + libxlDomainShutdownThread(void *opaque) + { +- struct libxlShutdownThreadInfo *shutdown_info = opaque; ++ struct libxlEventHandlerThreadInfo *shutdown_info = opaque; + virDomainObj *vm = shutdown_info->vm; + libxl_event *ev = shutdown_info->event; + libxlDriverPrivate *driver = shutdown_info->driver; +@@ -665,7 +665,7 @@ libxlDomainEventHandler(void *data, libx + } + + if (event->type == LIBXL_EVENT_TYPE_DOMAIN_SHUTDOWN) { +- struct libxlShutdownThreadInfo *shutdown_info = NULL; ++ struct libxlEventHandlerThreadInfo *shutdown_info = NULL; + virThread thread; + g_autofree char *name = NULL; + +@@ -673,7 +673,7 @@ libxlDomainEventHandler(void *data, libx + * 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 libxlShutdownThreadInfo, 1); ++ shutdown_info = g_new0(struct libxlEventHandlerThreadInfo, 1); + + shutdown_info->driver = driver; + shutdown_info->vm = vm; +@@ -693,7 +693,7 @@ libxlDomainEventHandler(void *data, libx + } + /* + * virDomainObjEndAPI is called in the shutdown thread, where +- * libxlShutdownThreadInfo and libxl_event are also freed. ++ * libxlEventHandlerThreadInfo and libxl_event are also freed. + */ + return; + } else if (event->type == LIBXL_EVENT_TYPE_DOMAIN_DEATH) { diff --git a/a7a03324-libxl-protect-logger-access.patch b/a7a03324-libxl-protect-logger-access.patch new file mode 100644 index 0000000..2ee943f --- /dev/null +++ b/a7a03324-libxl-protect-logger-access.patch @@ -0,0 +1,84 @@ +commit a7a03324d86e111f81687b5315b8f296dde84340 +Author: Jim Fehlig +Date: Thu Nov 18 12:03:20 2021 -0700 + + libxl: Protect access to libxlLogger files hash table + + The hash table of log file objects in libxlLogger is not protected against + concurrent access. It is possible for one thread to remove an entry while + another is updating it. Add a mutex to the libxlLogger object and lock it + when accessing the files hash table. + + Signed-off-by: Jim Fehlig + Reviewed-by: Daniel P. Berrangé + Reviewed-by: Ján Tomko + +Index: libvirt-7.10.0/src/libxl/libxl_logger.c +=================================================================== +--- libvirt-7.10.0.orig/src/libxl/libxl_logger.c ++++ libvirt-7.10.0/src/libxl/libxl_logger.c +@@ -28,6 +28,7 @@ + #include "util/virfile.h" + #include "util/virhash.h" + #include "util/virstring.h" ++#include "util/virthread.h" + #include "util/virtime.h" + + #define VIR_FROM_THIS VIR_FROM_LIBXL +@@ -43,6 +44,7 @@ struct xentoollog_logger_libvirt { + + /* map storing the opened fds: "domid" -> FILE* */ + GHashTable *files; ++ virMutex tableLock; + FILE *defaultLogFile; + }; + +@@ -85,7 +87,9 @@ libvirt_vmessage(xentoollog_logger *logg + start = start + 9; + *end = '\0'; + ++ virMutexLock(&lg->tableLock); + domainLogFile = virHashLookup(lg->files, start); ++ virMutexUnlock(&lg->tableLock); + if (domainLogFile) + logFile = domainLogFile; + +@@ -158,6 +162,12 @@ libxlLoggerNew(const char *logDir, virLo + return NULL; + } + ++ if (virMutexInit(&logger.tableLock) < 0) { ++ VIR_FORCE_FCLOSE(logger.defaultLogFile); ++ virHashFree(logger.files); ++ return NULL; ++ } ++ + return XTL_NEW_LOGGER(libvirt, logger); + } + +@@ -168,6 +178,7 @@ libxlLoggerFree(libxlLogger *logger) + if (logger->defaultLogFile) + VIR_FORCE_FCLOSE(logger->defaultLogFile); + virHashFree(logger->files); ++ virMutexDestroy(&logger->tableLock); + xtl_logger_destroy(xtl_logger); + } + +@@ -189,7 +200,9 @@ libxlLoggerOpenFile(libxlLogger *logger, + path, g_strerror(errno)); + return; + } ++ virMutexLock(&logger->tableLock); + ignore_value(virHashAddEntry(logger->files, domidstr, logFile)); ++ virMutexUnlock(&logger->tableLock); + + /* domain_config is non NULL only when starting a new domain */ + if (domain_config) { +@@ -204,5 +217,7 @@ libxlLoggerCloseFile(libxlLogger *logger + g_autofree char *domidstr = NULL; + domidstr = g_strdup_printf("%d", id); + ++ virMutexLock(&logger->tableLock); + ignore_value(virHashRemoveEntry(logger->files, domidstr)); ++ virMutexUnlock(&logger->tableLock); + } diff --git a/b9a5faea-libxl-handle-death-thread.patch b/b9a5faea-libxl-handle-death-thread.patch new file mode 100644 index 0000000..90315f1 --- /dev/null +++ b/b9a5faea-libxl-handle-death-thread.patch @@ -0,0 +1,140 @@ +commit b9a5faea49b7412e26d7389af4c32fc2b3ee80e5 +Author: Jim Fehlig +Date: Wed Nov 24 11:36:55 2021 -0700 + + 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 + Reviewed-by: Daniel P. Berrangé + Reviewed-by: Ján Tomko + +Index: libvirt-7.10.0/src/libxl/libxl_domain.c +=================================================================== +--- libvirt-7.10.0.orig/src/libxl/libxl_domain.c ++++ libvirt-7.10.0/src/libxl/libxl_domain.c +@@ -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(libxlDriverPrivat + 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, libx + 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, libx + 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; +- +- /* +- * 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); ++ thread_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, libx + */ + 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); ++ /* ++ * Cleanup will be handled by the death thread. ++ */ ++ 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; ++ } + /* +- * On death the domain is cleaned up from Xen's perspective. +- * Cleanup on the libvirt side can be done synchronously. ++ * virDomainObjEndAPI is called in the death thread, where ++ * libxlEventHandlerThreadInfo and libxl_event are also freed. + */ +- libxlDomainHandleDeath(driver, vm); ++ return; + } + + cleanup: + virDomainObjEndAPI(&vm); ++ VIR_FREE(thread_info); + cfg = libxlDriverConfigGet(driver); + /* Cast away any const */ + libxl_event_free(cfg->ctx, (libxl_event *)event); diff --git a/e4f7589a-libxl-shutdown-thread-name.patch b/e4f7589a-libxl-shutdown-thread-name.patch new file mode 100644 index 0000000..a44b49e --- /dev/null +++ b/e4f7589a-libxl-shutdown-thread-name.patch @@ -0,0 +1,27 @@ +commit e4f7589a3ec285489618ca04c8c0230cc31f3d99 +Author: Jim Fehlig +Date: Wed Nov 24 11:16:38 2021 -0700 + + libxl: Modify name of shutdown thread + + The current thread name 'ev-' is a bit terse. Change the name + to 'shutdown-event-', allowing it to be distinguished between + thread handling other event types. + + Signed-off-by: Jim Fehlig + Reviewed-by: Daniel P. Berrangé + Reviewed-by: Ján Tomko + +Index: libvirt-7.10.0/src/libxl/libxl_domain.c +=================================================================== +--- libvirt-7.10.0.orig/src/libxl/libxl_domain.c ++++ libvirt-7.10.0/src/libxl/libxl_domain.c +@@ -678,7 +678,7 @@ libxlDomainEventHandler(void *data, libx + shutdown_info->driver = driver; + shutdown_info->vm = vm; + shutdown_info->event = (libxl_event *)event; +- name = g_strdup_printf("ev-%d", event->domid); ++ name = g_strdup_printf("shutdown-event-%d", event->domid); + /* + * Cleanup will be handled by the shutdown thread. + */ diff --git a/libvirt.changes b/libvirt.changes index 8841d1c..2f6b35a 100644 --- a/libvirt.changes +++ b/libvirt.changes @@ -1,3 +1,15 @@ +------------------------------------------------------------------- +Thu Dec 2 22:36:06 UTC 2021 - James Fehlig + +- libxl: Fix libvirtd deadlocks and segfaults + 23b51d7b-libxl-disable-death-event.patch, + a4e6fba0-libxl-rename-threadinfo-struct.patch, + e4f7589a-libxl-shutdown-thread-name.patch, + b9a5faea-libxl-handle-death-thread.patch, + 5c5df531-libxl-search-domid-in-thread.patch, + a7a03324-libxl-protect-logger-access.patch + bsc#1191668, bsc#1192017 + ------------------------------------------------------------------- Thu Dec 2 15:12:31 UTC 2021 - James Fehlig diff --git a/libvirt.spec b/libvirt.spec index df0511c..11e24fe 100644 --- a/libvirt.spec +++ b/libvirt.spec @@ -286,6 +286,12 @@ Source6: libvirtd-relocation-server.xml Source99: baselibs.conf Source100: %{name}-rpmlintrc # Upstream patches +Patch0: 23b51d7b-libxl-disable-death-event.patch +Patch1: a4e6fba0-libxl-rename-threadinfo-struct.patch +Patch2: e4f7589a-libxl-shutdown-thread-name.patch +Patch3: b9a5faea-libxl-handle-death-thread.patch +Patch4: 5c5df531-libxl-search-domid-in-thread.patch +Patch5: a7a03324-libxl-protect-logger-access.patch # Patches pending upstream review Patch100: libxl-dom-reset.patch Patch101: network-don-t-use-dhcp-authoritative-on-static-netwo.patch