forked from pool/libvirt
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:
parent
58776811eb
commit
bb05d1aab0
105
23b51d7b-libxl-disable-death-event.patch
Normal file
105
23b51d7b-libxl-disable-death-event.patch
Normal 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;
|
167
5c5df531-libxl-search-domid-in-thread.patch
Normal file
167
5c5df531-libxl-search-domid-in-thread.patch
Normal 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 */
|
63
a4e6fba0-libxl-rename-threadinfo-struct.patch
Normal file
63
a4e6fba0-libxl-rename-threadinfo-struct.patch
Normal 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) {
|
84
a7a03324-libxl-protect-logger-access.patch
Normal file
84
a7a03324-libxl-protect-logger-access.patch
Normal 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);
|
||||
}
|
140
b9a5faea-libxl-handle-death-thread.patch
Normal file
140
b9a5faea-libxl-handle-death-thread.patch
Normal 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);
|
27
e4f7589a-libxl-shutdown-thread-name.patch
Normal file
27
e4f7589a-libxl-shutdown-thread-name.patch
Normal 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.
|
||||
*/
|
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user