Accepting request 935299 from home:jfehlig:branches:Virtualization

- 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

OBS-URL: https://build.opensuse.org/request/show/935299
OBS-URL: https://build.opensuse.org/package/show/Virtualization/libvirt?expand=0&rev=914
This commit is contained in:
James Fehlig 2021-12-02 22:43:30 +00:00 committed by Git OBS Bridge
parent 58776811eb
commit bb05d1aab0
8 changed files with 604 additions and 0 deletions

View File

@ -0,0 +1,105 @@
commit 23b51d7b8ec885e97a9277cf0a6c2833db4636e8
Author: Jim Fehlig <jfehlig@suse.com>
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 <jfehlig@suse.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
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;

View File

@ -0,0 +1,167 @@
commit 5c5df5310f72be4878a71ace47074c54e0d1a27d
Author: Jim Fehlig <jfehlig@suse.com>
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=<optimized out>) at ../../src/util/virthread.c:79
#3 0x00007f3189463f3b in virObjectLock (anyobj=<optimized out>) at ../../src/util/virobject.c:433
#4 0x00007f31894f2f41 in virDomainObjListSearchID (payload=0x7f317400a6d0, name=<optimized out>, data=0x7f31411eaeac) at ../../src/conf/virdomainobjlist.c:105
#5 0x00007f3189437ac5 in virHashSearch (ctable=0x7f3124025a30, iter=iter@entry=0x7f31894f2f30 <virDomainObjListSearchID>, data=data@entry=0x7f31411eaeac, name=name@entry=0x0) at ../../src/util/virhash.c:745
#6 0x00007f31894f3919 in virDomainObjListFindByID (doms=0x7f3124025430, id=<optimized out>) 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=<optimized out>, ao_how=ao_how@entry=0x0) at libxl_domain.c:730
#12 0x00007f3152f2a584 in libxl_domain_unpause_0x041200 (domid=<optimized out>, ctx=<optimized out>) 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=<optimized out>, 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=<optimized out>) at ../../src/libxl/libxl_domain.c:559
#17 0x00007f3189487ee2 in virThreadHelper (data=<optimized out>) 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 <jfehlig@suse.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
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 */

View File

@ -0,0 +1,63 @@
commit a4e6fba069c0809b8b5dde5e9db62d2efd91b4a0
Author: Jim Fehlig <jfehlig@suse.com>
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 <jfehlig@suse.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
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) {

View File

@ -0,0 +1,84 @@
commit a7a03324d86e111f81687b5315b8f296dde84340
Author: Jim Fehlig <jfehlig@suse.com>
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 <jfehlig@suse.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
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);
}

View File

@ -0,0 +1,140 @@
commit b9a5faea49b7412e26d7389af4c32fc2b3ee80e5
Author: Jim Fehlig <jfehlig@suse.com>
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 <jfehlig@suse.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
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);

View File

@ -0,0 +1,27 @@
commit e4f7589a3ec285489618ca04c8c0230cc31f3d99
Author: Jim Fehlig <jfehlig@suse.com>
Date: Wed Nov 24 11:16:38 2021 -0700
libxl: Modify name of shutdown thread
The current thread name 'ev-<domid>' is a bit terse. Change the name
to 'shutdown-event-<domid>', allowing it to be distinguished between
thread handling other event types.
Signed-off-by: Jim Fehlig <jfehlig@suse.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
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.
*/

View File

@ -1,3 +1,15 @@
-------------------------------------------------------------------
Thu Dec 2 22:36:06 UTC 2021 - James Fehlig <jfehlig@suse.com>
- 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 <jfehlig@suse.com> Thu Dec 2 15:12:31 UTC 2021 - James Fehlig <jfehlig@suse.com>

View File

@ -286,6 +286,12 @@ Source6: libvirtd-relocation-server.xml
Source99: baselibs.conf Source99: baselibs.conf
Source100: %{name}-rpmlintrc Source100: %{name}-rpmlintrc
# Upstream patches # 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 # Patches pending upstream review
Patch100: libxl-dom-reset.patch Patch100: libxl-dom-reset.patch
Patch101: network-don-t-use-dhcp-authoritative-on-static-netwo.patch Patch101: network-don-t-use-dhcp-authoritative-on-static-netwo.patch