137 lines
3.9 KiB
Diff
137 lines
3.9 KiB
Diff
https://www.redhat.com/archives/libvir-list/2020-August/msg00596.html
|
|
|
|
Doing malloc/free after fork is technically not allowed in POSIX and
|
|
deadlocks[1] with musl libc.
|
|
|
|
[1]: https://gitlab.com/libvirt/libvirt/-/issues/52
|
|
|
|
Signed-off-by: Natanael Copa <ncopa alpinelinux org>
|
|
---
|
|
src/util/vircommand.c | 4 ++--
|
|
src/util/virlog.c | 44 +++++++++++++++++++++++++++++++++----------
|
|
src/util/virlog.h | 1 +
|
|
3 files changed, 37 insertions(+), 12 deletions(-)
|
|
|
|
diff -ur src/util/vircommand.c src/util/vircommand.c
|
|
--- src/util/vircommand.c
|
|
+++ src/util/vircommand.c
|
|
@@ -304,7 +304,7 @@
|
|
/* Make sure any hook logging is sent to stderr, since child
|
|
* process may close the logfile FDs */
|
|
logprio = virLogGetDefaultPriority();
|
|
- virLogReset();
|
|
+ virLogResetWithoutFree();
|
|
virLogSetDefaultPriority(logprio);
|
|
|
|
/* Clear out all signal handlers from parent so nothing
|
|
@@ -897,7 +897,7 @@
|
|
goto fork_error;
|
|
|
|
/* Close logging again to ensure no FDs leak to child */
|
|
- virLogReset();
|
|
+ virLogResetWithoutFree();
|
|
|
|
if (cmd->env)
|
|
execve(binary, cmd->args, cmd->env);
|
|
diff -ur src/util/virlog.h src/util/virlog.h
|
|
--- src/util/virlog.h
|
|
+++ src/util/virlog.h
|
|
@@ -168,6 +168,7 @@
|
|
void virLogLock(void);
|
|
void virLogUnlock(void);
|
|
int virLogReset(void);
|
|
+int virLogResetWithoutFree(void);
|
|
int virLogParseDefaultPriority(const char *priority);
|
|
int virLogPriorityFromSyslog(int priority);
|
|
void virLogMessage(virLogSourcePtr source,
|
|
--- src/util/virlog.c 2021-05-03 11:02:51.455354200 +0200
|
|
+++ src/util/virlog.c 2021-05-08 11:56:58.414314487 +0200
|
|
@@ -108,8 +108,8 @@
|
|
*/
|
|
static virLogPriority virLogDefaultPriority = VIR_LOG_DEFAULT;
|
|
|
|
-static void virLogResetFilters(void);
|
|
-static void virLogResetOutputs(void);
|
|
+static void virLogResetFilters(bool freemem);
|
|
+static void virLogResetOutputs(bool freemem);
|
|
static void virLogOutputToFd(virLogSource *src,
|
|
virLogPriority priority,
|
|
const char *filename,
|
|
@@ -284,8 +284,30 @@
|
|
return -1;
|
|
|
|
virLogLock();
|
|
- virLogResetFilters();
|
|
- virLogResetOutputs();
|
|
+ virLogResetFilters(true);
|
|
+ virLogResetOutputs(true);
|
|
+ virLogDefaultPriority = VIR_LOG_DEFAULT;
|
|
+ virLogUnlock();
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * virLogResetWithoutFree:
|
|
+ *
|
|
+ * Reset the logging module to its default initial state, but avoid doing
|
|
+ * free() so it can be used after fork and before exec.
|
|
+ *
|
|
+ * Returns 0 if successful, and -1 in case or error
|
|
+ */
|
|
+int
|
|
+virLogResetWithoutFree(void)
|
|
+{
|
|
+ if (virLogInitialize() < 0)
|
|
+ return -1;
|
|
+
|
|
+ virLogLock();
|
|
+ virLogResetFilters(false);
|
|
+ virLogResetOutputs(false);
|
|
virLogDefaultPriority = VIR_LOG_DEFAULT;
|
|
virLogUnlock();
|
|
return 0;
|
|
@@ -324,9 +346,10 @@
|
|
* Removes the set of logging filters defined.
|
|
*/
|
|
static void
|
|
-virLogResetFilters(void)
|
|
+virLogResetFilters(bool freemem)
|
|
{
|
|
- virLogFilterListFree(virLogFilters, virLogNbFilters);
|
|
+ if (freemem)
|
|
+ virLogFilterListFree(virLogFilters, virLogNbFilters);
|
|
virLogFilters = NULL;
|
|
virLogNbFilters = 0;
|
|
virLogFiltersSerial++;
|
|
@@ -371,9 +394,10 @@
|
|
* Removes the set of logging output defined.
|
|
*/
|
|
static void
|
|
-virLogResetOutputs(void)
|
|
+virLogResetOutputs(bool freemem)
|
|
{
|
|
- virLogOutputListFree(virLogOutputs, virLogNbOutputs);
|
|
+ if (freemem)
|
|
+ virLogOutputListFree(virLogOutputs, virLogNbOutputs);
|
|
virLogOutputs = NULL;
|
|
virLogNbOutputs = 0;
|
|
}
|
|
@@ -1379,7 +1403,7 @@
|
|
return -1;
|
|
|
|
virLogLock();
|
|
- virLogResetOutputs();
|
|
+ virLogResetOutputs(true);
|
|
|
|
#if WITH_SYSLOG_H
|
|
/* syslog needs to be special-cased, since it keeps the fd in private */
|
|
@@ -1422,7 +1446,7 @@
|
|
return -1;
|
|
|
|
virLogLock();
|
|
- virLogResetFilters();
|
|
+ virLogResetFilters(true);
|
|
virLogFilters = filters;
|
|
virLogNbFilters = nfilters;
|
|
virLogUnlock();
|