1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-21 02:50:18 +03:00

log: skip reading the kernel command line if the process is invoked by a script

CLI tools may be used in a script. E.g., a script for monitoring a
service may use `systemctl`. Previously, if the kernel command line has
e.g. systemd.log-level=debug, then systemctl in the script produces
debugging logs when the script is invoked by a .service unit, but does
not when the script is running in a terminal. Then,
https://github.com/systemd/systemd/pull/18281#discussion_r561697482,
> I expect users to be (negatively) surprised.

In the previous commit, $SYSTEMD_EXEC_PID= is introduced. Then, we can
now detect whether a command is directly invoked by systemd or through
a script. Let's skip reading the kernel command line when a command is
invoked through a script.
This commit is contained in:
Yu Watanabe 2021-01-26 16:12:41 +09:00
parent d754890843
commit 85cf96e3f5

View File

@ -1157,15 +1157,37 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
return 0;
}
static bool should_parse_proc_cmdline(void) {
const char *e;
pid_t p;
/* PID1 always reads the kernel command line. */
if (getpid_cached() == 1)
return true;
/* If the process is directly executed by PID1 (e.g. ExecStart= or generator), systemd-importd,
* or systemd-homed, then $SYSTEMD_EXEC_PID= is set, and read the command line. */
e = getenv("SYSTEMD_EXEC_PID");
if (!e)
return false;
if (streq(e, "*"))
/* For testing. */
return true;
if (parse_pid(e, &p) < 0)
/* We know that systemd sets the variable correctly. Something else must have set it. */
log_debug("Failed to parse \"$SYSTEMD_EXEC_PID=%s\". Ignoring.", e);
return getpid_cached() == p;
}
void log_parse_environment(void) {
const char *e;
/* Do not call from library code. */
if (getpid_cached() == 1 || get_ctty_devnr(0, NULL) < 0)
/* Only try to read the command line in daemons. We assume that anything that has a
* controlling tty is user stuff. For PID1 we do a special check in case it hasn't
* closed the console yet. */
if (should_parse_proc_cmdline())
(void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
e = getenv("SYSTEMD_LOG_TARGET");