mirror of
https://gitlab.com/prpl-foundation/prplos/feeds/feed_opensource.git
synced 2025-12-20 01:20:39 +08:00
Patch for problem described in PPW-60 cthulhu: random: container is not properly started
This commit is contained in:
117
packages/utils/lxc/patches/040-LXC-syslog-patch.patch
Normal file
117
packages/utils/lxc/patches/040-LXC-syslog-patch.patch
Normal file
@@ -0,0 +1,117 @@
|
||||
From 06fc7f827ad90ca567f2df5429c6c903aec32acf Mon Sep 17 00:00:00 2001
|
||||
From: Nabil BIZID <nabil.bizid@softathome.com>
|
||||
Date: Tue, 24 Sep 2024 20:02:50 +0200
|
||||
Subject: [PATCH] log: fix random container syslog logging or startup failures
|
||||
on musl libc
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
During the setup/start of an LXC container, the LXC creates multiple
|
||||
forks of the main process for different purposes. Each fork inherits the
|
||||
file descriptors (fds) of the parent process. However, each child
|
||||
process closes the list of inherited file descriptors that it does not
|
||||
need, as these fds are irrelevant to the child process. This cleanup of
|
||||
fds occurs in the lxc_check_inherited().
|
||||
|
||||
If logging to syslog is enabled, the socket used for logging to the
|
||||
syslog daemon (through the syslog device: /dev/log) is also closed,
|
||||
invalidating the corresponding file descriptor. LXC uses the standard
|
||||
syslog() function to log messages to the syslog daemon.
|
||||
|
||||
OpenWrt uses the musl library as its standard C library, and the musl
|
||||
implementation of syslog() is not resilient to the invalidation of
|
||||
previously obtained file descriptors (through calls to syslog() or
|
||||
openlog()). In contrast, the syslog() implementation in glibc and other
|
||||
C libraries is more robust: if an invalid file descriptor is detected,
|
||||
those libraries will automatically reopen the connection to the syslog
|
||||
device, obtaining a new, valid file descriptor to continue logging.
|
||||
|
||||
musl libc, on the other hand, only detects connection loss to the syslog
|
||||
device and does not handle cases where the file descriptor itself
|
||||
becomes invalid. This limitation can be seen in the musl implementation
|
||||
here: https://git.musl-libc.org/cgit/musl/tree/src/misc/syslog.c#n80.
|
||||
musl libc behavior will not change following the answer maintainers:
|
||||
https://www.openwall.com/lists/musl/2024/09/26/2
|
||||
|
||||
As a result of this behavior in musl, when an LXC child process tries to
|
||||
log information using syslog(), it continues to use the invalid file
|
||||
descriptor (which was closed earlier). This primarily results in some
|
||||
missing logs without functional impacts, when no other socket or file
|
||||
opening operation reuses the same file descriptor value. However, if the
|
||||
file descriptor is reused by another process or operation, logs may
|
||||
erroneously be written to that file or socket and can lead to container
|
||||
creation/startup failure.
|
||||
|
||||
This commit aims to prevent forked processes from using invalid syslog
|
||||
file descriptors, which can lead to issues such as missing logs or, in
|
||||
worse cases, random failures in LXC functionality (e.g., when
|
||||
synchronization between LXC processes is disrupted). It also addresses
|
||||
musl's lack of resilience when handling invalid file descriptors.
|
||||
|
||||
The changes work by caching the syslog connection information at the
|
||||
start and reusing it to reopen the syslog connection after child
|
||||
processes close all inherited file descriptors.
|
||||
|
||||
Fixes: #4485
|
||||
Tested-by: Petr Štetiar <petr.stetiar@prplfoundation.org>
|
||||
Signed-off-by: Nabil BIZID <nabil.bizid@softathome.com>
|
||||
---
|
||||
src/lxc/log.c | 20 ++++++++++++++++++++
|
||||
1 file changed, 20 insertions(+)
|
||||
|
||||
diff --git a/src/lxc/log.c b/src/lxc/log.c
|
||||
index cdd11ff1c..08c9c959c 100644
|
||||
--- a/src/lxc/log.c
|
||||
+++ b/src/lxc/log.c
|
||||
@@ -51,6 +51,9 @@ static char log_prefix[LXC_LOG_PREFIX_SIZE] = "lxc";
|
||||
static char *log_fname = NULL;
|
||||
static char *log_vmname = NULL;
|
||||
|
||||
+static bool syslog_initialized = false;
|
||||
+static int syslog_facility = -EINVAL;
|
||||
+
|
||||
lxc_log_define(log, lxc);
|
||||
|
||||
static int lxc_log_priority_to_syslog(int priority)
|
||||
@@ -746,6 +749,8 @@ int lxc_log_syslog(int facility)
|
||||
struct lxc_log_appender *appender;
|
||||
|
||||
openlog(log_prefix, LOG_PID, facility);
|
||||
+ syslog_initialized = true;
|
||||
+ syslog_facility = facility;
|
||||
if (!lxc_log_category_lxc.appender) {
|
||||
lxc_log_category_lxc.appender = &log_appender_syslog;
|
||||
return 0;
|
||||
@@ -768,13 +773,28 @@ int lxc_log_syslog(int facility)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static void lxc_reconnect_syslog(void)
|
||||
+{
|
||||
+ if (syslog_initialized)
|
||||
+ openlog(log_prefix, LOG_PID, syslog_facility);
|
||||
+}
|
||||
+
|
||||
+static void lxc_force_close_syslog(void)
|
||||
+{
|
||||
+ if (syslog_initialized)
|
||||
+ closelog();
|
||||
+}
|
||||
+
|
||||
+
|
||||
void lxc_log_syslog_enable(void)
|
||||
{
|
||||
+ lxc_reconnect_syslog();
|
||||
wants_syslog = true;
|
||||
}
|
||||
|
||||
void lxc_log_syslog_disable(void)
|
||||
{
|
||||
+ lxc_force_close_syslog();
|
||||
wants_syslog = false;
|
||||
}
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
Reference in New Issue
Block a user