1
0
mirror of https://gitlab.com/libvirt/libvirt.git synced 2024-12-22 17:34:18 +03:00

util: Check for errors in virLogSetFromEnv

And make callers check the return value as well.  This helps error out early for
invalid environment variables.

That is desirable because it could lead to deadlocks.  This can happen when
resetting logging after fork() reports translated errors because gettext
functions are not reentrant.  Well, it is not limited to resetting logging after
fork(), it can be any translation at that phase, but parsing environment
variables is easy to make fail on purpose to show the result, it can also happen
just due to a typo.

Before this commit it is possible to deadlock the daemon on startup
with something like:

LIBVIRT_LOG_FILTERS='1:*' LIBVIRT_LOG_OUTPUTS=1:stdout libvirtd

where filters are used to enable more logging and hence make the race less rare
and outputs are set to invalid

Combined with the previous patches this changes
the following from:

...
<deadlock>

to:

...
libvirtd: initialisation failed

The error message is improved in future commits and is also possible thanks to
this patch.

Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
This commit is contained in:
Martin Kletzander 2021-12-15 16:34:16 +01:00
parent a873924e36
commit 9f6749dea0
10 changed files with 36 additions and 17 deletions

View File

@ -55,7 +55,8 @@ virAdmGlobalInit(void)
if (virErrorInitialize() < 0)
goto error;
virLogSetFromEnv();
if (virLogSetFromEnv() < 0)
goto error;
#ifdef WITH_LIBINTL_H
if (!bindtextdomain(PACKAGE, LOCALEDIR))

View File

@ -232,7 +232,8 @@ virGlobalInit(void)
goto error;
}
virLogSetFromEnv();
if (virLogSetFromEnv() < 0)
goto error;
virNetTLSInit();

View File

@ -2503,7 +2503,8 @@ int main(int argc, char *argv[])
}
/* Initialize logging */
virLogSetFromEnv();
if (virLogSetFromEnv() < 0)
exit(EXIT_FAILURE);
while (1) {
int c;

View File

@ -402,7 +402,8 @@ int main(int argc, char **argv)
virFileActivateDirOverrideForProg(argv[0]);
/* Initialize the log system */
virLogSetFromEnv();
if (virLogSetFromEnv() < 0)
exit(EXIT_FAILURE);
uri_str = argv[1];
VIR_DEBUG("Using URI %s", uri_str);

View File

@ -1449,7 +1449,8 @@ main(int argc, char **argv)
virFileActivateDirOverrideForProg(argv[0]);
/* Initialize the log system */
virLogSetFromEnv();
if (virLogSetFromEnv() < 0)
exit(EXIT_FAILURE);
/* clear the environment */
environ = NULL;

View File

@ -751,7 +751,8 @@ virExec(virCommand *cmd)
VIR_FORCE_CLOSE(null);
/* Initialize full logging for a while */
virLogSetFromEnv();
if (virLogSetFromEnv() < 0)
goto fork_error;
if (cmd->pidfile &&
virPipe(pipesync) < 0)

View File

@ -183,7 +183,8 @@ virDaemonSetupLogging(const char *daemon_name,
return -1;
/* If there are some environment variables defined, use those instead */
virLogSetFromEnv();
if (virLogSetFromEnv() < 0)
return -1;
/*
* Command line override for --verbose

View File

@ -1200,24 +1200,34 @@ virLogParseDefaultPriority(const char *priority)
*
* Sets virLogDefaultPriority, virLogFilters and virLogOutputs based on
* environment variables.
*
* This function might fail which should also make the caller fail.
*/
void
int
virLogSetFromEnv(void)
{
const char *debugEnv;
if (virLogInitialize() < 0)
return;
return -1;
debugEnv = getenv("LIBVIRT_DEBUG");
if (debugEnv && *debugEnv)
virLogSetDefaultPriority(virLogParseDefaultPriority(debugEnv));
if (debugEnv && *debugEnv) {
int priority = virLogParseDefaultPriority(debugEnv);
if (priority < 0 ||
virLogSetDefaultPriority(priority) < 0)
return -1;
}
debugEnv = getenv("LIBVIRT_LOG_FILTERS");
if (debugEnv && *debugEnv)
virLogSetFilters(debugEnv);
if (debugEnv && *debugEnv &&
virLogSetFilters(debugEnv))
return -1;
debugEnv = getenv("LIBVIRT_LOG_OUTPUTS");
if (debugEnv && *debugEnv)
virLogSetOutputs(debugEnv);
if (debugEnv && *debugEnv &&
virLogSetOutputs(debugEnv))
return -1;
return 0;
}

View File

@ -146,7 +146,7 @@ char *virLogGetFilters(void);
char *virLogGetOutputs(void);
virLogPriority virLogGetDefaultPriority(void);
int virLogSetDefaultPriority(virLogPriority priority);
void virLogSetFromEnv(void);
int virLogSetFromEnv(void) G_GNUC_WARN_UNUSED_RESULT;
void virLogOutputFree(virLogOutput *output);
void virLogOutputListFree(virLogOutput **list, int count);
void virLogFilterFree(virLogFilter *filter);

View File

@ -835,7 +835,9 @@ int virTestMain(int argc,
if (virErrorInitialize() < 0)
return EXIT_FAILURE;
virLogSetFromEnv();
if (virLogSetFromEnv() < 0)
return EXIT_FAILURE;
if (!getenv("LIBVIRT_DEBUG") && !virLogGetNbOutputs()) {
if (!(output = virLogOutputNew(virtTestLogOutput, virtTestLogClose,
&testLog, VIR_LOG_DEBUG,