Merge pull request #18375 from yuwata/cli-tools-also-read-kernel-command-line

tree-wide: make CLI tools also read kernel command line when run as service
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2021-02-08 11:45:42 +01:00
committed by GitHub
84 changed files with 210 additions and 106 deletions
+23
View File
@@ -12,6 +12,8 @@
#include "extract-word.h"
#include "macro.h"
#include "parse-util.h"
#include "process-util.h"
#include "stdio-util.h"
#include "string-util.h"
#include "strv.h"
#include "utf8.h"
@@ -749,3 +751,24 @@ int set_unset_env(const char *name, const char *value, bool overwrite) {
return -errno;
return 0;
}
int setenv_systemd_exec_pid(bool update_only) {
char str[DECIMAL_STR_MAX(pid_t)];
const char *e;
/* Update $SYSTEMD_EXEC_PID=pid except when '*' is set for the variable. */
e = secure_getenv("SYSTEMD_EXEC_PID");
if (!e && update_only)
return 0;
if (streq_ptr(e, "*"))
return 0;
xsprintf(str, PID_FMT, getpid_cached());
if (setenv("SYSTEMD_EXEC_PID", str, 1) < 0)
return -errno;
return 1;
}
+2
View File
@@ -55,3 +55,5 @@ int getenv_bool_secure(const char *p);
/* Like setenv, but calls unsetenv if value == NULL. */
int set_unset_env(const char *name, const char *value, bool overwrite);
int setenv_systemd_exec_pid(bool update_only);
+28 -22
View File
@@ -1157,20 +1157,38 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat
return 0;
}
void log_parse_environment(void) {
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. */
(void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
static bool should_parse_proc_cmdline(void) {
const char *e;
pid_t p;
log_parse_environment_cli();
/* 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_cli(void) {
void log_parse_environment(void) {
const char *e;
/* Do not call from library code. */
const char *e;
if (should_parse_proc_cmdline())
(void) proc_cmdline_parse(parse_proc_cmdline_item, NULL, PROC_CMDLINE_STRIP_RD_PREFIX);
e = getenv("SYSTEMD_LOG_TARGET");
if (e && log_set_target_from_string(e) < 0)
@@ -1460,22 +1478,10 @@ int log_dup_console(void) {
return 0;
}
void log_setup_service(void) {
/* Sets up logging the way it is most appropriate for running a program as a service. Note that using this
* doesn't make the binary unsuitable for invocation on the command line, as log output will still go to the
* terminal if invoked interactively. */
void log_setup(void) {
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
(void) log_open();
}
void log_setup_cli(void) {
/* Sets up logging the way it is most appropriate for running a program as a CLI utility. */
log_set_target(LOG_TARGET_AUTO);
log_parse_environment_cli();
(void) log_open();
if (log_on_console() && show_color < 0)
log_show_color(true);
}
+1 -3
View File
@@ -69,7 +69,6 @@ void log_close(void);
void log_forget_fds(void);
void log_parse_environment(void);
void log_parse_environment_cli(void);
int log_dispatch_internal(
int level,
@@ -301,5 +300,4 @@ int log_syntax_invalid_utf8_internal(
#define DEBUG_LOGGING _unlikely_(log_get_max_level() >= LOG_DEBUG)
void log_setup_service(void);
void log_setup_cli(void);
void log_setup(void);