main.c   main.c 
skipping to change at line 53 skipping to change at line 53
#include "sd-messages.h" #include "sd-messages.h"
#include "sd-bus.h" #include "sd-bus.h"
#include "manager.h" #include "manager.h"
#include "log.h" #include "log.h"
#include "load-fragment.h" #include "load-fragment.h"
#include "fdset.h" #include "fdset.h"
#include "special.h" #include "special.h"
#include "conf-parser.h" #include "conf-parser.h"
#include "missing.h" #include "missing.h"
#include "label.h" #include "label.h"
#include "pager.h"
#include "build.h" #include "build.h"
#include "strv.h" #include "strv.h"
#include "def.h" #include "def.h"
#include "virt.h" #include "virt.h"
#include "architecture.h" #include "architecture.h"
#include "watchdog.h" #include "watchdog.h"
#include "path-util.h" #include "path-util.h"
#include "switch-root.h" #include "switch-root.h"
#include "capability.h" #include "capability.h"
#include "killall.h" #include "killall.h"
skipping to change at line 97 skipping to change at line 98
ACTION_DONE ACTION_DONE
} arg_action = ACTION_RUN; } arg_action = ACTION_RUN;
static char *arg_default_unit = NULL; static char *arg_default_unit = NULL;
static SystemdRunningAs arg_running_as = _SYSTEMD_RUNNING_AS_INVALID; static SystemdRunningAs arg_running_as = _SYSTEMD_RUNNING_AS_INVALID;
static bool arg_dump_core = true; static bool arg_dump_core = true;
static bool arg_crash_shell = false; static bool arg_crash_shell = false;
static int arg_crash_chvt = -1; static int arg_crash_chvt = -1;
static bool arg_confirm_spawn = false; static bool arg_confirm_spawn = false;
static ShowStatus arg_show_status = _SHOW_STATUS_UNSET; static ShowStatus arg_show_status = _SHOW_STATUS_UNSET;
static bool arg_switched_root = false; static bool arg_switched_root = false;
static int arg_no_pager = -1;
static char ***arg_join_controllers = NULL; static char ***arg_join_controllers = NULL;
static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL; static ExecOutput arg_default_std_output = EXEC_OUTPUT_JOURNAL;
static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT; static ExecOutput arg_default_std_error = EXEC_OUTPUT_INHERIT;
static usec_t arg_default_restart_usec = DEFAULT_RESTART_USEC; static usec_t arg_default_restart_usec = DEFAULT_RESTART_USEC;
static usec_t arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC; static usec_t arg_default_timeout_start_usec = DEFAULT_TIMEOUT_USEC;
static usec_t arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC; static usec_t arg_default_timeout_stop_usec = DEFAULT_TIMEOUT_USEC;
static usec_t arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERV AL; static usec_t arg_default_start_limit_interval = DEFAULT_START_LIMIT_INTERV AL;
static unsigned arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST; static unsigned arg_default_start_limit_burst = DEFAULT_START_LIMIT_BURST;
static usec_t arg_runtime_watchdog = 0; static usec_t arg_runtime_watchdog = 0;
static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE; static usec_t arg_shutdown_watchdog = 10 * USEC_PER_MINUTE;
static char **arg_default_environment = NULL; static char **arg_default_environment = NULL;
static struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {}; static struct rlimit *arg_default_rlimit[_RLIMIT_MAX] = {};
static uint64_t arg_capability_bounding_set_drop = 0; static uint64_t arg_capability_bounding_set_drop = 0;
static nsec_t arg_timer_slack_nsec = (nsec_t) -1; static nsec_t arg_timer_slack_nsec = NSEC_INFINITY;
static usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE; static usec_t arg_default_timer_accuracy_usec = 1 * USEC_PER_MINUTE;
static Set* arg_syscall_archs = NULL; static Set* arg_syscall_archs = NULL;
static FILE* arg_serialization = NULL; static FILE* arg_serialization = NULL;
static bool arg_default_cpu_accounting = false; static bool arg_default_cpu_accounting = false;
static bool arg_default_blockio_accounting = false; static bool arg_default_blockio_accounting = false;
static bool arg_default_memory_accounting = false; static bool arg_default_memory_accounting = false;
static void nop_handler(int sig) {} static void nop_handler(int sig) {}
static void pager_open_if_enabled(void) {
if (arg_no_pager <= 0)
return;
pager_open(false);
}
noreturn static void crash(int sig) { noreturn static void crash(int sig) {
if (getpid() != 1) if (getpid() != 1)
/* Pass this on immediately, if this is not PID 1 */ /* Pass this on immediately, if this is not PID 1 */
raise(sig); raise(sig);
else if (!arg_dump_core) else if (!arg_dump_core)
log_error("Caught <%s>, not dumping core.", signal_to_strin g(sig)); log_error("Caught <%s>, not dumping core.", signal_to_strin g(sig));
else { else {
struct sigaction sa = { struct sigaction sa = {
.sa_handler = nop_handler, .sa_handler = nop_handler,
skipping to change at line 221 skipping to change at line 231
static void install_crash_handler(void) { static void install_crash_handler(void) {
struct sigaction sa = { struct sigaction sa = {
.sa_handler = crash, .sa_handler = crash,
.sa_flags = SA_NODEFER, .sa_flags = SA_NODEFER,
}; };
sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1); sigaction_many(&sa, SIGNALS_CRASH_HANDLER, -1);
} }
static int console_setup(bool do_reset) { static int console_setup(void) {
int tty_fd, r; _cleanup_close_ int tty_fd = -1;
int r;
/* If we are init, we connect stdin/stdout/stderr to /dev/null
* and make sure we don't have a controlling tty. */
release_terminal();
if (!do_reset)
return 0;
tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC) ; tty_fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC) ;
if (tty_fd < 0) { if (tty_fd < 0) {
log_error("Failed to open /dev/console: %s", strerror(-tty_ fd)); log_error("Failed to open /dev/console: %s", strerror(-tty_ fd));
return -tty_fd; return tty_fd;
} }
/* We don't want to force text mode. /* We don't want to force text mode. plymouth may be showing
* plymouth may be showing pictures already from initrd. */ * pictures already from initrd. */
r = reset_terminal_fd(tty_fd, false); r = reset_terminal_fd(tty_fd, false);
if (r < 0) if (r < 0) {
log_error("Failed to reset /dev/console: %s", strerror(-r)) ; log_error("Failed to reset /dev/console: %s", strerror(-r)) ;
return r;
}
safe_close(tty_fd); return 0;
return r;
} }
static int set_default_unit(const char *u) { static int set_default_unit(const char *u) {
char *c; char *c;
assert(u); assert(u);
c = strdup(u); c = strdup(u);
if (!c) if (!c)
return -ENOMEM; return -ENOMEM;
skipping to change at line 292 skipping to change at line 296
if (streq(key, "systemd.unit") && value) { if (streq(key, "systemd.unit") && value) {
if (!in_initrd()) if (!in_initrd())
return set_default_unit(value); return set_default_unit(value);
} else if (streq(key, "rd.systemd.unit") && value) { } else if (streq(key, "rd.systemd.unit") && value) {
if (in_initrd()) if (in_initrd())
return set_default_unit(value); return set_default_unit(value);
} else if (streq(key, "systemd.log_target") && value) {
if (log_set_target_from_string(value) < 0)
log_warning("Failed to parse log target %s. Ignorin
g.", value);
} else if (streq(key, "systemd.log_level") && value) {
if (log_set_max_level_from_string(value) < 0)
log_warning("Failed to parse log level %s. Ignoring
.", value);
} else if (streq(key, "systemd.log_color") && value) {
if (log_show_color_from_string(value) < 0)
log_warning("Failed to parse log color setting %s.
Ignoring.", value);
} else if (streq(key, "systemd.log_location") && value) {
if (log_show_location_from_string(value) < 0)
log_warning("Failed to parse log location setting %
s. Ignoring.", value);
} else if (streq(key, "systemd.dump_core") && value) { } else if (streq(key, "systemd.dump_core") && value) {
r = parse_boolean(value); r = parse_boolean(value);
if (r < 0) if (r < 0)
log_warning("Failed to parse dump core switch %s. I gnoring.", value); log_warning("Failed to parse dump core switch %s. I gnoring.", value);
else else
arg_dump_core = r; arg_dump_core = r;
} else if (streq(key, "systemd.crash_shell") && value) { } else if (streq(key, "systemd.crash_shell") && value) {
skipping to change at line 387 skipping to change at line 371
} else if (streq(key, "quiet") && !value) { } else if (streq(key, "quiet") && !value) {
log_set_max_level(LOG_NOTICE); log_set_max_level(LOG_NOTICE);
if (arg_show_status == _SHOW_STATUS_UNSET) if (arg_show_status == _SHOW_STATUS_UNSET)
arg_show_status = SHOW_STATUS_AUTO; arg_show_status = SHOW_STATUS_AUTO;
} else if (streq(key, "debug") && !value) { } else if (streq(key, "debug") && !value) {
log_set_max_level(LOG_DEBUG); /* Note that log_parse_environment() handles 'debug'
* too, and sets the log level to LOG_DEBUG. */
if (detect_container(NULL) > 0) if (detect_container(NULL) > 0)
log_set_target(LOG_TARGET_CONSOLE); log_set_target(LOG_TARGET_CONSOLE);
} else if (!in_initrd() && !value) { } else if (!in_initrd() && !value) {
unsigned i; unsigned i;
/* SysV compatibility */ /* SysV compatibility */
for (i = 0; i < ELEMENTSOF(rlmap); i += 2) for (i = 0; i < ELEMENTSOF(rlmap); i += 2)
if (streq(key, rlmap[i])) if (streq(key, rlmap[i]))
skipping to change at line 448 skipping to change at line 433
const char *filename, const char *filename,
unsigned line, unsigned line,
const char *section, const char *section,
unsigned section_line, unsigned section_line,
const char *lvalue, const char *lvalue,
int ltype, int ltype,
const char *rvalue, const char *rvalue,
void *data, void *data,
void *userdata) { void *userdata) {
char *w; const char *word, *state;
size_t l; size_t l;
char *state;
cpu_set_t *c = NULL; cpu_set_t *c = NULL;
unsigned ncpus = 0; unsigned ncpus = 0;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
FOREACH_WORD_QUOTED(w, l, rvalue, state) { FOREACH_WORD_QUOTED(word, l, rvalue, state) {
char *t; char *t;
int r; int r;
unsigned cpu; unsigned cpu;
if (!(t = strndup(w, l))) if (!(t = strndup(word, l)))
return log_oom(); return log_oom();
r = safe_atou(t, &cpu); r = safe_atou(t, &cpu);
free(t); free(t);
if (!c) if (!c)
if (!(c = cpu_set_malloc(&ncpus))) if (!(c = cpu_set_malloc(&ncpus)))
return log_oom(); return log_oom();
if (r < 0 || cpu >= ncpus) { if (r < 0 || cpu >= ncpus) {
log_syntax(unit, LOG_ERR, filename, line, -r, log_syntax(unit, LOG_ERR, filename, line, -r,
"Failed to parse CPU affinity '%s'", rva lue); "Failed to parse CPU affinity '%s'", rva lue);
CPU_FREE(c); CPU_FREE(c);
return -EBADMSG; return -EBADMSG;
} }
CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c); CPU_SET_S(cpu, CPU_ALLOC_SIZE(ncpus), c);
} }
if (!isempty(state))
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Trailing garbage, ignoring.");
if (c) { if (c) {
if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0) if (sched_setaffinity(0, CPU_ALLOC_SIZE(ncpus), c) < 0)
log_warning_unit(unit, "Failed to set CPU affinity: %m"); log_warning_unit(unit, "Failed to set CPU affinity: %m");
CPU_FREE(c); CPU_FREE(c);
} }
return 0; return 0;
} }
skipping to change at line 552 skipping to change at line 539
unsigned line, unsigned line,
const char *section, const char *section,
unsigned section_line, unsigned section_line,
const char *lvalue, const char *lvalue,
int ltype, int ltype,
const char *rvalue, const char *rvalue,
void *data, void *data,
void *userdata) { void *userdata) {
unsigned n = 0; unsigned n = 0;
char *state, *w; const char *word, *state;
size_t length; size_t length;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);
assert(rvalue); assert(rvalue);
free_join_controllers(); free_join_controllers();
FOREACH_WORD_QUOTED(w, length, rvalue, state) { FOREACH_WORD_QUOTED(word, length, rvalue, state) {
char *s, **l; char *s, **l;
s = strndup(w, length); s = strndup(word, length);
if (!s) if (!s)
return log_oom(); return log_oom();
l = strv_split(s, ","); l = strv_split(s, ",");
free(s); free(s);
strv_uniq(l); strv_uniq(l);
if (strv_length(l) <= 1) { if (strv_length(l) <= 1) {
strv_free(l); strv_free(l);
skipping to change at line 630 skipping to change at line 617
t[n++] = c; t[n++] = c;
} }
} }
t[n++] = strv_uniq(l); t[n++] = strv_uniq(l);
strv_free_free(arg_join_controllers); strv_free_free(arg_join_controllers);
arg_join_controllers = t; arg_join_controllers = t;
} }
} }
if (!isempty(state))
log_syntax(unit, LOG_ERR, filename, line, EINVAL,
"Trailing garbage, ignoring.");
return 0; return 0;
} }
static int parse_config_file(void) { static int parse_config_file(void) {
const ConfigTableItem items[] = { const ConfigTableItem items[] = {
{ "Manager", "LogLevel", config_parse_leve l2, 0, NULL }, { "Manager", "LogLevel", config_parse_leve l2, 0, NULL },
{ "Manager", "LogTarget", config_parse_targ et, 0, NULL }, { "Manager", "LogTarget", config_parse_targ et, 0, NULL },
{ "Manager", "LogColor", config_parse_colo r, 0, NULL }, { "Manager", "LogColor", config_parse_colo r, 0, NULL },
skipping to change at line 685 skipping to change at line 675
{ "Manager", "DefaultLimitMSGQUEUE", config_parse_limi t, 0, &arg_default_rlimit[RLIMIT_MSGQUEUE] }, { "Manager", "DefaultLimitMSGQUEUE", config_parse_limi t, 0, &arg_default_rlimit[RLIMIT_MSGQUEUE] },
{ "Manager", "DefaultLimitNICE", config_parse_limi t, 0, &arg_default_rlimit[RLIMIT_NICE] }, { "Manager", "DefaultLimitNICE", config_parse_limi t, 0, &arg_default_rlimit[RLIMIT_NICE] },
{ "Manager", "DefaultLimitRTPRIO", config_parse_limi t, 0, &arg_default_rlimit[RLIMIT_RTPRIO] }, { "Manager", "DefaultLimitRTPRIO", config_parse_limi t, 0, &arg_default_rlimit[RLIMIT_RTPRIO] },
{ "Manager", "DefaultLimitRTTIME", config_parse_limi t, 0, &arg_default_rlimit[RLIMIT_RTTIME] }, { "Manager", "DefaultLimitRTTIME", config_parse_limi t, 0, &arg_default_rlimit[RLIMIT_RTTIME] },
{ "Manager", "DefaultCPUAccounting", config_parse_bool , 0, &arg_default_cpu_accounting }, { "Manager", "DefaultCPUAccounting", config_parse_bool , 0, &arg_default_cpu_accounting },
{ "Manager", "DefaultBlockIOAccounting", config_parse_bool , 0, &arg_default_blockio_accounting }, { "Manager", "DefaultBlockIOAccounting", config_parse_bool , 0, &arg_default_blockio_accounting },
{ "Manager", "DefaultMemoryAccounting", config_parse_bool , 0, &arg_default_memory_accounting }, { "Manager", "DefaultMemoryAccounting", config_parse_bool , 0, &arg_default_memory_accounting },
{} {}
}; };
_cleanup_fclose_ FILE *f;
const char *fn; const char *fn;
int r;
fn = arg_running_as == SYSTEMD_SYSTEM ? PKGSYSCONFDIR "/system.conf " : PKGSYSCONFDIR "/user.conf"; fn = arg_running_as == SYSTEMD_SYSTEM ? PKGSYSCONFDIR "/system.conf " : PKGSYSCONFDIR "/user.conf";
f = fopen(fn, "re"); config_parse(NULL, fn, NULL,
if (!f) { "Manager\0",
if (errno == ENOENT) config_item_table_lookup, items,
return 0; false, false, true, NULL);
log_warning("Failed to open configuration file '%s': %m", f
n);
return 0;
}
r = config_parse(NULL, fn, f, "Manager\0", config_item_table_lookup
, (void*) items, false, false, NULL);
if (r < 0)
log_warning("Failed to parse configuration file: %s", strer
ror(-r));
return 0; return 0;
} }
static int parse_argv(int argc, char *argv[]) { static int parse_argv(int argc, char *argv[]) {
enum { enum {
ARG_LOG_LEVEL = 0x100, ARG_LOG_LEVEL = 0x100,
ARG_LOG_TARGET, ARG_LOG_TARGET,
ARG_LOG_COLOR, ARG_LOG_COLOR,
ARG_LOG_LOCATION, ARG_LOG_LOCATION,
ARG_UNIT, ARG_UNIT,
ARG_SYSTEM, ARG_SYSTEM,
ARG_USER, ARG_USER,
ARG_TEST, ARG_TEST,
ARG_NO_PAGER,
ARG_VERSION, ARG_VERSION,
ARG_DUMP_CONFIGURATION_ITEMS, ARG_DUMP_CONFIGURATION_ITEMS,
ARG_DUMP_CORE, ARG_DUMP_CORE,
ARG_CRASH_SHELL, ARG_CRASH_SHELL,
ARG_CONFIRM_SPAWN, ARG_CONFIRM_SPAWN,
ARG_SHOW_STATUS, ARG_SHOW_STATUS,
ARG_DESERIALIZE, ARG_DESERIALIZE,
ARG_SWITCHED_ROOT, ARG_SWITCHED_ROOT,
ARG_DEFAULT_STD_OUTPUT, ARG_DEFAULT_STD_OUTPUT,
ARG_DEFAULT_STD_ERROR ARG_DEFAULT_STD_ERROR
skipping to change at line 738 skipping to change at line 719
static const struct option options[] = { static const struct option options[] = {
{ "log-level", required_argument, NULL, ARG_ LOG_LEVEL }, { "log-level", required_argument, NULL, ARG_ LOG_LEVEL },
{ "log-target", required_argument, NULL, ARG_ LOG_TARGET }, { "log-target", required_argument, NULL, ARG_ LOG_TARGET },
{ "log-color", optional_argument, NULL, ARG_ LOG_COLOR }, { "log-color", optional_argument, NULL, ARG_ LOG_COLOR },
{ "log-location", optional_argument, NULL, ARG_ LOG_LOCATION }, { "log-location", optional_argument, NULL, ARG_ LOG_LOCATION },
{ "unit", required_argument, NULL, ARG_ UNIT }, { "unit", required_argument, NULL, ARG_ UNIT },
{ "system", no_argument, NULL, ARG_ SYSTEM }, { "system", no_argument, NULL, ARG_ SYSTEM },
{ "user", no_argument, NULL, ARG_ USER }, { "user", no_argument, NULL, ARG_ USER },
{ "test", no_argument, NULL, ARG_ TEST }, { "test", no_argument, NULL, ARG_ TEST },
{ "no-pager", no_argument, NULL, ARG_ NO_PAGER },
{ "help", no_argument, NULL, 'h' }, { "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_ VERSION }, { "version", no_argument, NULL, ARG_ VERSION },
{ "dump-configuration-items", no_argument, NULL, ARG_ DUMP_CONFIGURATION_ITEMS }, { "dump-configuration-items", no_argument, NULL, ARG_ DUMP_CONFIGURATION_ITEMS },
{ "dump-core", optional_argument, NULL, ARG_ DUMP_CORE }, { "dump-core", optional_argument, NULL, ARG_ DUMP_CORE },
{ "crash-shell", optional_argument, NULL, ARG_ CRASH_SHELL }, { "crash-shell", optional_argument, NULL, ARG_ CRASH_SHELL },
{ "confirm-spawn", optional_argument, NULL, ARG_ CONFIRM_SPAWN }, { "confirm-spawn", optional_argument, NULL, ARG_ CONFIRM_SPAWN },
{ "show-status", optional_argument, NULL, ARG_ SHOW_STATUS }, { "show-status", optional_argument, NULL, ARG_ SHOW_STATUS },
{ "deserialize", required_argument, NULL, ARG_ DESERIALIZE }, { "deserialize", required_argument, NULL, ARG_ DESERIALIZE },
{ "switched-root", no_argument, NULL, ARG_ SWITCHED_ROOT }, { "switched-root", no_argument, NULL, ARG_ SWITCHED_ROOT },
{ "default-standard-output", required_argument, NULL, ARG_ DEFAULT_STD_OUTPUT, }, { "default-standard-output", required_argument, NULL, ARG_ DEFAULT_STD_OUTPUT, },
skipping to change at line 845 skipping to change at line 827
case ARG_SYSTEM: case ARG_SYSTEM:
arg_running_as = SYSTEMD_SYSTEM; arg_running_as = SYSTEMD_SYSTEM;
break; break;
case ARG_USER: case ARG_USER:
arg_running_as = SYSTEMD_USER; arg_running_as = SYSTEMD_USER;
break; break;
case ARG_TEST: case ARG_TEST:
arg_action = ACTION_TEST; arg_action = ACTION_TEST;
if (arg_no_pager < 0)
arg_no_pager = true;
break;
case ARG_NO_PAGER:
arg_no_pager = true;
break; break;
case ARG_VERSION: case ARG_VERSION:
arg_action = ACTION_VERSION; arg_action = ACTION_VERSION;
break; break;
case ARG_DUMP_CONFIGURATION_ITEMS: case ARG_DUMP_CONFIGURATION_ITEMS:
arg_action = ACTION_DUMP_CONFIGURATION_ITEMS; arg_action = ACTION_DUMP_CONFIGURATION_ITEMS;
break; break;
skipping to change at line 925 skipping to change at line 913
break; break;
} }
case ARG_SWITCHED_ROOT: case ARG_SWITCHED_ROOT:
arg_switched_root = true; arg_switched_root = true;
break; break;
case 'h': case 'h':
arg_action = ACTION_HELP; arg_action = ACTION_HELP;
if (arg_no_pager < 0)
arg_no_pager = true;
break; break;
case 'D': case 'D':
log_set_max_level(LOG_DEBUG); log_set_max_level(LOG_DEBUG);
break; break;
case 'b': case 'b':
case 's': case 's':
case 'z': case 'z':
/* Just to eat away the sysvinit kernel /* Just to eat away the sysvinit kernel
* cmdline args without getopt() error * cmdline args without getopt() error
* messages that we'll parse in * messages that we'll parse in
* parse_proc_cmdline_word() or ignore. */ * parse_proc_cmdline_word() or ignore. */
case '?': case '?':
default: if (getpid() != 1)
if (getpid() != 1) {
log_error("Unknown option code %c", c);
return -EINVAL; return -EINVAL;
} else
return 0;
break; default:
assert_not_reached("Unhandled option code.");
} }
if (optind < argc && getpid() != 1) { if (optind < argc && getpid() != 1) {
/* Hmm, when we aren't run as init system /* Hmm, when we aren't run as init system
* let's complain about excess arguments */ * let's complain about excess arguments */
log_error("Excess arguments."); log_error("Excess arguments.");
return -EINVAL; return -EINVAL;
} }
if (detect_container(NULL) > 0) {
char **a;
/* All /proc/cmdline arguments the kernel didn't
* understand it passed to us. We're not really
* interested in that usually since /proc/cmdline is
* more interesting and complete. With one exception:
* if we are run in a container /proc/cmdline is not
* relevant for the container, hence we rely on argv[]
* instead. */
for (a = argv; a < argv + argc; a++) {
_cleanup_free_ char *w;
char *value;
w = strdup(*a);
if (!w)
return log_oom();
value = strchr(w, '=');
if (value)
*(value++) = 0;
r = parse_proc_cmdline_item(w, value);
if (r < 0) {
log_error("Failed on cmdline argument %s: %
s", *a, strerror(-r));
return r;
}
}
}
return 0; return 0;
} }
static int help(void) { static int help(void) {
printf("%s [OPTIONS...]\n\n" printf("%s [OPTIONS...]\n\n"
"Starts up and maintains the system or user services.\n\n" "Starts up and maintains the system or user services.\n\n"
" -h --help Show this help\n" " -h --help Show this help\n"
" --test Determine startup sequence , dump it and exit\n" " --test Determine startup sequence , dump it and exit\n"
" --no-pager Do not pipe output into a pager\n"
" --dump-configuration-items Dump understood unit confi guration items\n" " --dump-configuration-items Dump understood unit confi guration items\n"
" --unit=UNIT Set default unit\n" " --unit=UNIT Set default unit\n"
" --system Run a system instance, eve n if PID != 1\n" " --system Run a system instance, eve n if PID != 1\n"
" --user Run a user instance\n" " --user Run a user instance\n"
" --dump-core[=0|1] Dump core on crash\n" " --dump-core[=0|1] Dump core on crash\n"
" --crash-shell[=0|1] Run shell on crash\n" " --crash-shell[=0|1] Run shell on crash\n"
" --confirm-spawn[=0|1] Ask for confirmation when spawning processes\n" " --confirm-spawn[=0|1] Ask for confirmation when spawning processes\n"
" --show-status[=0|1] Show status updates on the console during bootup\n" " --show-status[=0|1] Show status updates on the console during bootup\n"
" --log-target=TARGET Set log target (console, j ournal, syslog, kmsg, journal-or-kmsg, syslog-or-kmsg, null)\n" " --log-target=TARGET Set log target (console, j ournal, kmsg, journal-or-kmsg, null)\n"
" --log-level=LEVEL Set log level (debug, info , notice, warning, err, crit, alert, emerg)\n" " --log-level=LEVEL Set log level (debug, info , notice, warning, err, crit, alert, emerg)\n"
" --log-color[=0|1] Highlight important log me ssages\n" " --log-color[=0|1] Highlight important log me ssages\n"
" --log-location[=0|1] Include code location in l og messages\n" " --log-location[=0|1] Include code location in l og messages\n"
" --default-standard-output= Set default standard outpu t for services\n" " --default-standard-output= Set default standard outpu t for services\n"
" --default-standard-error= Set default standard error output for services\n", " --default-standard-error= Set default standard error output for services\n",
program_invocation_short_name); program_invocation_short_name);
return 0; return 0;
} }
skipping to change at line 1315 skipping to change at line 1275
called 'init'. After a subsequent reexecution we are then called 'init'. After a subsequent reexecution we are then
called 'systemd'. That is confusing, hence let's call us called 'systemd'. That is confusing, hence let's call us
systemd right-away. */ systemd right-away. */
program_invocation_short_name = systemd; program_invocation_short_name = systemd;
prctl(PR_SET_NAME, systemd); prctl(PR_SET_NAME, systemd);
saved_argv = argv; saved_argv = argv;
saved_argc = argc; saved_argc = argc;
log_show_color(isatty(STDERR_FILENO) > 0); log_show_color(isatty(STDERR_FILENO) > 0);
log_set_upgrade_syslog_to_journal(true);
/* Disable the umask logic */ /* Disable the umask logic */
if (getpid() == 1) if (getpid() == 1)
umask(0); umask(0);
if (getpid() == 1 && detect_container(NULL) <= 0) { if (getpid() == 1 && detect_container(NULL) <= 0) {
/* Running outside of a container as PID 1 */ /* Running outside of a container as PID 1 */
arg_running_as = SYSTEMD_SYSTEM; arg_running_as = SYSTEMD_SYSTEM;
make_null_stdio(); make_null_stdio();
skipping to change at line 1350 skipping to change at line 1311
dual_timestamp_get(&security_finish_timestamp); dual_timestamp_get(&security_finish_timestamp);
} }
if (label_init(NULL) < 0) if (label_init(NULL) < 0)
goto finish; goto finish;
if (!skip_setup) { if (!skip_setup) {
if (clock_is_localtime() > 0) { if (clock_is_localtime() > 0) {
int min; int min;
/* The first-time call to settimeofday() do /*
es a time warp in the kernel */ * The very first call of settimeofday() al
so does a time warp in the kernel.
*
* In the rtc-in-local time mode, we set th
e kernel's timezone, and rely on
* external tools to take care of maintaini
ng the RTC and do all adjustments.
* This matches the behavior of Windows, wh
ich leaves the RTC alone if the
* registry tells that the RTC runs in UTC.
*/
r = clock_set_timezone(&min); r = clock_set_timezone(&min);
if (r < 0) if (r < 0)
log_error("Failed to apply local ti me delta, ignoring: %s", strerror(-r)); log_error("Failed to apply local ti me delta, ignoring: %s", strerror(-r));
else else
log_info("RTC configured in localti me, applying delta of %i minutes to system time.", min); log_info("RTC configured in localti me, applying delta of %i minutes to system time.", min);
} else if (!in_initrd()) { } else if (!in_initrd()) {
/* /*
* Do dummy first-time call to seal the ker nel's time warp magic * Do a dummy very first call to seal the k ernel's time warp magic.
* *
* Do not call this this from inside the in itrd. The initrd might not * Do not call this this from inside the in itrd. The initrd might not
* carry /etc/adjtime with LOCAL, but the r eal system could be set up * carry /etc/adjtime with LOCAL, but the r eal system could be set up
* that way. In such case, we need to delay the time-warp or the sealing * that way. In such case, we need to delay the time-warp or the sealing
* until we reach the real system. * until we reach the real system.
*
* Do no set the kernel's timezone. The con
cept of local time cannot
* be supported reliably, the time will jum
p or be incorrect at every daylight
* saving time change. All kernel local tim
e concepts will be treated
* as UTC that way.
*/ */
clock_reset_timezone(); clock_reset_timewarp();
/* Tell the kernel our timezone */
r = clock_set_timezone(NULL);
if (r < 0)
log_error("Failed to set the kernel
's timezone, ignoring: %s", strerror(-r));
} }
} }
/* Set the default for later on, but don't actually /* Set the default for later on, but don't actually
* open the logs like this for now. Note that if we * open the logs like this for now. Note that if we
* are transitioning from the initrd there might still * are transitioning from the initrd there might still
* be journal fd open, and we shouldn't attempt * be journal fd open, and we shouldn't attempt
* opening that before we parsed /proc/cmdline which * opening that before we parsed /proc/cmdline which
* might redirect output elsewhere. */ * might redirect output elsewhere. */
log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
skipping to change at line 1440 skipping to change at line 1408
ignore_signals(SIGNALS_IGNORE, -1); ignore_signals(SIGNALS_IGNORE, -1);
if (parse_config_file() < 0) if (parse_config_file() < 0)
goto finish; goto finish;
if (arg_running_as == SYSTEMD_SYSTEM) if (arg_running_as == SYSTEMD_SYSTEM)
if (parse_proc_cmdline(parse_proc_cmdline_item) < 0) if (parse_proc_cmdline(parse_proc_cmdline_item) < 0)
goto finish; goto finish;
/* Note that this also parses bits from the kernel command
* line, including "debug". */
log_parse_environment(); log_parse_environment();
if (parse_argv(argc, argv) < 0) if (parse_argv(argc, argv) < 0)
goto finish; goto finish;
if (arg_action == ACTION_TEST && if (arg_action == ACTION_TEST &&
geteuid() == 0) { geteuid() == 0) {
log_error("Don't run test mode as root."); log_error("Don't run test mode as root.");
goto finish; goto finish;
} }
skipping to change at line 1465 skipping to change at line 1435
goto finish; goto finish;
} }
if (arg_running_as == SYSTEMD_SYSTEM && if (arg_running_as == SYSTEMD_SYSTEM &&
arg_action == ACTION_RUN && arg_action == ACTION_RUN &&
running_in_chroot() > 0) { running_in_chroot() > 0) {
log_error("Cannot be run in a chroot() environment."); log_error("Cannot be run in a chroot() environment.");
goto finish; goto finish;
} }
if (arg_action == ACTION_TEST)
skip_setup = true;
pager_open_if_enabled();
if (arg_action == ACTION_HELP) { if (arg_action == ACTION_HELP) {
retval = help(); retval = help();
goto finish; goto finish;
} else if (arg_action == ACTION_VERSION) { } else if (arg_action == ACTION_VERSION) {
retval = version(); retval = version();
goto finish; goto finish;
} else if (arg_action == ACTION_DUMP_CONFIGURATION_ITEMS) { } else if (arg_action == ACTION_DUMP_CONFIGURATION_ITEMS) {
unit_dump_config_items(stdout); unit_dump_config_items(stdout);
retval = EXIT_SUCCESS; retval = EXIT_SUCCESS;
goto finish; goto finish;
skipping to change at line 1511 skipping to change at line 1486
if (arg_running_as == SYSTEMD_SYSTEM) if (arg_running_as == SYSTEMD_SYSTEM)
/* Become a session leader if we aren't one yet. */ /* Become a session leader if we aren't one yet. */
setsid(); setsid();
/* Move out of the way, so that we won't block unmounts */ /* Move out of the way, so that we won't block unmounts */
assert_se(chdir("/") == 0); assert_se(chdir("/") == 0);
/* Reset the console, but only if this is really init and we /* Reset the console, but only if this is really init and we
* are freshly booted */ * are freshly booted */
if (arg_running_as == SYSTEMD_SYSTEM && arg_action == ACTION_RUN) if (arg_running_as == SYSTEMD_SYSTEM && arg_action == ACTION_RUN) {
console_setup(getpid() == 1 && !skip_setup);
/* If we are init, we connect stdin/stdout/stderr to
* /dev/null and make sure we don't have a controlling
* tty. */
release_terminal();
if (getpid() == 1 && !skip_setup)
console_setup();
}
/* Open the logging devices, if possible and necessary */ /* Open the logging devices, if possible and necessary */
log_open(); log_open();
if (arg_show_status == _SHOW_STATUS_UNSET) if (arg_show_status == _SHOW_STATUS_UNSET)
arg_show_status = SHOW_STATUS_YES; arg_show_status = SHOW_STATUS_YES;
/* Make sure we leave a core dump without panicing the /* Make sure we leave a core dump without panicing the
* kernel. */ * kernel. */
if (getpid() == 1) { if (getpid() == 1) {
install_crash_handler(); install_crash_handler();
r = mount_cgroup_controllers(arg_join_controllers); r = mount_cgroup_controllers(arg_join_controllers);
if (r < 0) if (r < 0)
goto finish; goto finish;
} }
if (arg_running_as == SYSTEMD_SYSTEM) { if (arg_running_as == SYSTEMD_SYSTEM) {
const char *virtualization = NULL; const char *virtualization = NULL;
log_info(PACKAGE_STRING " running in system mode. (" SYSTEM log_info(PACKAGE_STRING " running in %ssystem mode. (" SYST
D_FEATURES ")"); EMD_FEATURES ")",
arg_action == ACTION_TEST ? "test " : "" );
detect_virtualization(&virtualization); detect_virtualization(&virtualization);
if (virtualization) if (virtualization)
log_info("Detected virtualization '%s'.", virtualiz ation); log_info("Detected virtualization '%s'.", virtualiz ation);
write_container_id(); write_container_id();
log_info("Detected architecture '%s'.", architecture_to_str ing(uname_architecture())); log_info("Detected architecture '%s'.", architecture_to_str ing(uname_architecture()));
if (in_initrd()) if (in_initrd())
log_info("Running in initial RAM disk."); log_info("Running in initial RAM disk.");
empty_etc = dir_is_empty("/etc") > 0; /* Let's check whether /etc is already populated. We
* don't actually really check for that, but use
* /etc/machine-id as flag file. This allows container
* managers and installers to provision a couple of
* files already. If the container manager wants to
* provision the machine ID itself it should pass
* $container_uuid to PID 1.*/
empty_etc = access("/etc/machine-id", F_OK) < 0;
if (empty_etc) if (empty_etc)
log_info("Running with unpopulated /etc."); log_info("Running with unpopulated /etc.");
} else { } else {
_cleanup_free_ char *t; _cleanup_free_ char *t;
t = uid_to_name(getuid()); t = uid_to_name(getuid());
log_debug(PACKAGE_STRING " running in user mode for user "U log_debug(PACKAGE_STRING " running in %suser mode for user
ID_FMT"/%s. (" SYSTEMD_FEATURES ")", getuid(), strna(t)); "UID_FMT"/%s. (" SYSTEMD_FEATURES ")",
arg_action == ACTION_TEST ? " test" : "", getuid(
), t);
} }
if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) { if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) {
if (arg_show_status > 0 || plymouth_running()) if (arg_show_status > 0 || plymouth_running())
status_welcome(); status_welcome();
#ifdef HAVE_KMOD #ifdef HAVE_KMOD
kmod_setup(); kmod_setup();
#endif #endif
hostname_setup(); hostname_setup();
machine_id_setup(NULL); machine_id_setup(NULL);
loopback_setup(); loopback_setup();
test_mtab(); test_mtab();
test_usr(); test_usr();
} }
if (arg_running_as == SYSTEMD_SYSTEM && arg_runtime_watchdog > 0) if (arg_running_as == SYSTEMD_SYSTEM && arg_runtime_watchdog > 0)
watchdog_set_timeout(&arg_runtime_watchdog); watchdog_set_timeout(&arg_runtime_watchdog);
if (arg_timer_slack_nsec != (nsec_t) -1) if (arg_timer_slack_nsec != NSEC_INFINITY)
if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0) if (prctl(PR_SET_TIMERSLACK, arg_timer_slack_nsec) < 0)
log_error("Failed to adjust timer slack: %m"); log_error("Failed to adjust timer slack: %m");
if (arg_capability_bounding_set_drop) { if (arg_capability_bounding_set_drop) {
r = capability_bounding_set_drop_usermode(arg_capability_bo unding_set_drop); r = capability_bounding_set_drop_usermode(arg_capability_bo unding_set_drop);
if (r < 0) { if (r < 0) {
log_error("Failed to drop capability bounding set o f usermode helpers: %s", strerror(-r)); log_error("Failed to drop capability bounding set o f usermode helpers: %s", strerror(-r));
goto finish; goto finish;
} }
r = capability_bounding_set_drop(arg_capability_bounding_se t_drop, true); r = capability_bounding_set_drop(arg_capability_bounding_se t_drop, true);
skipping to change at line 1618 skipping to change at line 1611
if (empty_etc) { if (empty_etc) {
r = unit_file_preset_all(UNIT_FILE_SYSTEM, false, N ULL, UNIT_FILE_PRESET_FULL, false, NULL, 0); r = unit_file_preset_all(UNIT_FILE_SYSTEM, false, N ULL, UNIT_FILE_PRESET_FULL, false, NULL, 0);
if (r < 0) if (r < 0)
log_warning("Failed to populate /etc with p reset unit settings, ignoring: %s", strerror(-r)); log_warning("Failed to populate /etc with p reset unit settings, ignoring: %s", strerror(-r));
else else
log_info("Populated /etc with preset unit s ettings."); log_info("Populated /etc with preset unit s ettings.");
} }
} }
r = manager_new(arg_running_as, &m); r = manager_new(arg_running_as, arg_action == ACTION_TEST, &m);
if (r < 0) { if (r < 0) {
log_error("Failed to allocate manager object: %s", strerror (-r)); log_error("Failed to allocate manager object: %s", strerror (-r));
goto finish; goto finish;
} }
m->confirm_spawn = arg_confirm_spawn; m->confirm_spawn = arg_confirm_spawn;
m->default_timer_accuracy_usec = arg_default_timer_accuracy_usec; m->default_timer_accuracy_usec = arg_default_timer_accuracy_usec;
m->default_std_output = arg_default_std_output; m->default_std_output = arg_default_std_output;
m->default_std_error = arg_default_std_error; m->default_std_error = arg_default_std_error;
m->default_restart_usec = arg_default_restart_usec; m->default_restart_usec = arg_default_restart_usec;
skipping to change at line 1647 skipping to change at line 1640
m->shutdown_watchdog = arg_shutdown_watchdog; m->shutdown_watchdog = arg_shutdown_watchdog;
m->userspace_timestamp = userspace_timestamp; m->userspace_timestamp = userspace_timestamp;
m->kernel_timestamp = kernel_timestamp; m->kernel_timestamp = kernel_timestamp;
m->initrd_timestamp = initrd_timestamp; m->initrd_timestamp = initrd_timestamp;
m->security_start_timestamp = security_start_timestamp; m->security_start_timestamp = security_start_timestamp;
m->security_finish_timestamp = security_finish_timestamp; m->security_finish_timestamp = security_finish_timestamp;
manager_set_default_rlimits(m, arg_default_rlimit); manager_set_default_rlimits(m, arg_default_rlimit);
manager_environment_add(m, NULL, arg_default_environment); manager_environment_add(m, NULL, arg_default_environment);
manager_set_show_status(m, arg_show_status); manager_set_show_status(m, arg_show_status);
manager_set_first_boot(m, empty_etc);
/* Remember whether we should queue the default job */ /* Remember whether we should queue the default job */
queue_default_job = !arg_serialization || arg_switched_root; queue_default_job = !arg_serialization || arg_switched_root;
before_startup = now(CLOCK_MONOTONIC); before_startup = now(CLOCK_MONOTONIC);
r = manager_startup(m, arg_serialization, fds); r = manager_startup(m, arg_serialization, fds);
if (r < 0) if (r < 0)
log_error("Failed to fully start up daemon: %s", strerror(- r)); log_error("Failed to fully start up daemon: %s", strerror(- r));
skipping to change at line 1802 skipping to change at line 1796
log_notice("Shutting down."); log_notice("Shutting down.");
goto finish; goto finish;
} }
default: default:
assert_not_reached("Unknown exit code."); assert_not_reached("Unknown exit code.");
} }
} }
finish: finish:
pager_close();
if (m) { if (m) {
manager_free(m); manager_free(m);
m = NULL; m = NULL;
} }
for (j = 0; j < ELEMENTSOF(arg_default_rlimit); j++) { for (j = 0; j < ELEMENTSOF(arg_default_rlimit); j++) {
free(arg_default_rlimit[j]); free(arg_default_rlimit[j]);
arg_default_rlimit[j] = NULL; arg_default_rlimit[j] = NULL;
} }
 End of changes. 49 change blocks. 
123 lines changed or deleted 117 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/