#include "mount-setup.h"
#include "loopback-setup.h"
+#ifdef HAVE_KMOD
#include "kmod-setup.h"
+#endif
#include "hostname-setup.h"
#include "machine-id-setup.h"
#include "locale-setup.h"
#include "hwclock.h"
#include "selinux-setup.h"
#include "ima-setup.h"
+#include "sd-daemon.h"
static enum {
ACTION_RUN,
} arg_action = ACTION_RUN;
static char *arg_default_unit = NULL;
-static ManagerRunningAs arg_running_as = _MANAGER_RUNNING_AS_INVALID;
+static SystemdRunningAs arg_running_as = _SYSTEMD_RUNNING_AS_INVALID;
static bool arg_dump_core = true;
static bool arg_crash_shell = false;
const char *fn;
int r;
- fn = arg_running_as == MANAGER_SYSTEM ? SYSTEM_CONFIG_FILE : USER_CONFIG_FILE;
+ fn = arg_running_as == SYSTEMD_SYSTEM ? SYSTEM_CONFIG_FILE : USER_CONFIG_FILE;
f = fopen(fn, "re");
if (!f) {
if (errno == ENOENT)
break;
case ARG_SYSTEM:
- arg_running_as = MANAGER_SYSTEM;
+ arg_running_as = SYSTEMD_SYSTEM;
break;
case ARG_USER:
- arg_running_as = MANAGER_USER;
+ arg_running_as = SYSTEMD_USER;
break;
case ARG_TEST:
int fd;
FILE *f;
- if ((r = safe_atoi(optarg, &fd)) < 0 || fd < 0) {
+ r = safe_atoi(optarg, &fd);
+ if (r < 0 || fd < 0) {
log_error("Failed to parse deserialize option %s.", optarg);
- return r;
+ return r < 0 ? r : -EINVAL;
}
- if (!(f = fdopen(fd, "r"))) {
+ fd_cloexec(fd, true);
+
+ f = fdopen(fd, "r");
+ if (!f) {
log_error("Failed to open serialization fd: %m");
- return r;
+ return -errno;
}
if (serialization)
static int version(void) {
puts(PACKAGE_STRING);
- puts(DISTRIBUTION);
puts(SYSTEMD_FEATURES);
return 0;
sleep(10);
}
+static int initialize_join_controllers(void) {
+ /* By default, mount "cpu" + "cpuacct" together, and "net_cls"
+ * + "net_prio". We'd like to add "cpuset" to the mix, but
+ * "cpuset" does't really work for groups with no initialized
+ * attributes. */
+
+ arg_join_controllers = new(char**, 3);
+ if (!arg_join_controllers)
+ return -ENOMEM;
+
+ arg_join_controllers[0] = strv_new("cpu", "cpuacct", NULL);
+ if (!arg_join_controllers[0])
+ return -ENOMEM;
+
+ arg_join_controllers[1] = strv_new("net_cls", "net_prio", NULL);
+ if (!arg_join_controllers[1])
+ return -ENOMEM;
+
+ arg_join_controllers[2] = NULL;
+ return 0;
+}
+
int main(int argc, char *argv[]) {
Manager *m = NULL;
int r, retval = EXIT_FAILURE;
if (getpid() == 1 && detect_container(NULL) <= 0) {
/* Running outside of a container as PID 1 */
- arg_running_as = MANAGER_SYSTEM;
+ arg_running_as = SYSTEMD_SYSTEM;
make_null_stdio();
log_set_target(LOG_TARGET_KMSG);
log_open();
log_error("Failed to apply local time delta, ignoring: %s", strerror(-r));
else
log_info("RTC configured in localtime, applying delta of %i minutes to system time.", min);
- } else {
- /* Do dummy first-time call to seal the kernel's time warp magic */
+ } else if (!in_initrd()) {
+ /*
+ * Do dummy first-time call to seal the kernel's time warp magic
+ *
+ * Do not call this this from inside the initrd. The initrd might not
+ * carry /etc/adjtime with LOCAL, but the real system could be set up
+ * that way. In such case, we need to delay the time-warp or the sealing
+ * until we reach the real system.
+ */
hwclock_reset_timezone();
/* Tell the kernel our time zone */
} else if (getpid() == 1) {
/* Running inside a container, as PID 1 */
- arg_running_as = MANAGER_SYSTEM;
+ arg_running_as = SYSTEMD_SYSTEM;
log_set_target(LOG_TARGET_CONSOLE);
log_open();
} else {
/* Running as user instance */
- arg_running_as = MANAGER_USER;
+ arg_running_as = SYSTEMD_USER;
log_set_target(LOG_TARGET_AUTO);
log_open();
}
goto finish;
}
- /* By default, mount "cpu" and "cpuacct" together */
- arg_join_controllers = new(char**, 3);
- if (!arg_join_controllers)
- goto finish;
-
- arg_join_controllers[0] = strv_new("cpu", "cpuacct", "cpuset", NULL);
- arg_join_controllers[1] = strv_new("net_cls", "net_prio", NULL);
- arg_join_controllers[2] = NULL;
-
- if (!arg_join_controllers[0])
+ r = initialize_join_controllers();
+ if (r < 0)
goto finish;
/* Mount /proc, /sys and friends, so that /proc/cmdline and
if (parse_config_file() < 0)
goto finish;
- if (arg_running_as == MANAGER_SYSTEM)
+ if (arg_running_as == SYSTEMD_SYSTEM)
if (parse_proc_cmdline() < 0)
goto finish;
if (parse_argv(argc, argv) < 0)
goto finish;
- if (arg_action == ACTION_TEST && geteuid() == 0) {
+ if (arg_action == ACTION_TEST &&
+ geteuid() == 0) {
log_error("Don't run test mode as root.");
goto finish;
}
- if (arg_running_as == MANAGER_SYSTEM &&
+ if (arg_running_as == SYSTEMD_USER &&
+ arg_action == ACTION_RUN &&
+ sd_booted() <= 0) {
+ log_error("Trying to run as user instance, but the system has not been booted with systemd.");
+ goto finish;
+ }
+
+ if (arg_running_as == SYSTEMD_SYSTEM &&
arg_action == ACTION_RUN &&
running_in_chroot() > 0) {
log_error("Cannot be run in a chroot() environment.");
log_close();
/* Remember open file descriptors for later deserialization */
- if (serialization) {
- r = fdset_new_fill(&fds);
- if (r < 0) {
- log_error("Failed to allocate fd set: %s", strerror(-r));
- goto finish;
- }
+ r = fdset_new_fill(&fds);
+ if (r < 0) {
+ log_error("Failed to allocate fd set: %s", strerror(-r));
+ goto finish;
+ } else
+ fdset_cloexec(fds, true);
+ if (serialization)
assert_se(fdset_remove(fds, fileno(serialization)) >= 0);
- } else
- close_all_fds(NULL, 0);
/* Set up PATH unless it is already set */
setenv("PATH",
#else
"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
#endif
- arg_running_as == MANAGER_SYSTEM);
+ arg_running_as == SYSTEMD_SYSTEM);
- if (arg_running_as == MANAGER_SYSTEM) {
+ if (arg_running_as == SYSTEMD_SYSTEM) {
/* Parse the data passed to us. We leave this
* variables set, but the manager later on will not
* pass them on to our children. */
unsetenv("USER");
unsetenv("LOGNAME");
+ /* We suppress the socket activation env vars, as
+ * we'll try to match *any* open fd to units if
+ * possible. */
+ unsetenv("LISTEN_FDS");
+ unsetenv("LISTEN_PID");
+
/* All other variables are left as is, so that clients
* can still read them via /proc/1/environ */
}
/* Move out of the way, so that we won't block unmounts */
assert_se(chdir("/") == 0);
- if (arg_running_as == MANAGER_SYSTEM) {
+ if (arg_running_as == SYSTEMD_SYSTEM) {
/* Become a session leader if we aren't one yet. */
setsid();
/* Reset the console, but only if this is really init and we
* are freshly booted */
- if (arg_running_as == MANAGER_SYSTEM && arg_action == ACTION_RUN)
+ if (arg_running_as == SYSTEMD_SYSTEM && arg_action == ACTION_RUN)
console_setup(getpid() == 1 && !skip_setup);
/* Open the logging devices, if possible and necessary */
goto finish;
}
- if (arg_running_as == MANAGER_SYSTEM) {
+ if (arg_running_as == SYSTEMD_SYSTEM) {
const char *virtualization = NULL;
- log_info(PACKAGE_STRING " running in system mode. (" SYSTEMD_FEATURES "; " DISTRIBUTION ")");
+ log_info(PACKAGE_STRING " running in system mode. (" SYSTEMD_FEATURES ")");
detect_virtualization(&virtualization);
if (virtualization)
log_info("Running in initial RAM disk.");
} else
- log_debug(PACKAGE_STRING " running in user mode. (" SYSTEMD_FEATURES "; " DISTRIBUTION ")");
+ log_debug(PACKAGE_STRING " running in user mode. (" SYSTEMD_FEATURES ")");
- if (arg_running_as == MANAGER_SYSTEM && !skip_setup) {
+ if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) {
locale_setup();
if (arg_show_status || plymouth_running())
status_welcome();
+#ifdef HAVE_KMOD
kmod_setup();
+#endif
hostname_setup();
machine_id_setup();
loopback_setup();
test_cgroups();
}
- if (arg_running_as == MANAGER_SYSTEM && arg_runtime_watchdog > 0)
+ if (arg_running_as == SYSTEMD_SYSTEM && arg_runtime_watchdog > 0)
watchdog_set_timeout(&arg_runtime_watchdog);
if (arg_timer_slack_nsec != (nsec_t) -1)
}
}
- if (arg_running_as == MANAGER_USER) {
+ if (arg_running_as == SYSTEMD_USER) {
/* Become reaper of our children */
if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0) {
log_warning("Failed to make us a subreaper: %m");
}
}
- if (arg_running_as == MANAGER_SYSTEM)
+ if (arg_running_as == SYSTEMD_SYSTEM)
bump_rlimit_nofile(&saved_rlimit_nofile);
r = manager_new(arg_running_as, &m);
/* This will close all file descriptors that were opened, but
* not claimed by any unit. */
- if (fds) {
- fdset_free(fds);
- fds = NULL;
- }
+ fdset_free(fds);
if (serialization) {
fclose(serialization);
args[i++] = SYSTEMD_BINARY_PATH;
if (switch_root_dir)
args[i++] = "--switched-root";
- args[i++] = arg_running_as == MANAGER_SYSTEM ? "--system" : "--user";
+ args[i++] = arg_running_as == SYSTEMD_SYSTEM ? "--system" : "--user";
args[i++] = "--deserialize";
args[i++] = sfd;
args[i++] = NULL;