chiark / gitweb /
unit-printf: add specifiers for the host name, machine id, boot id
[elogind.git] / src / core / main.c
index 6e8f21a290b33d50017cf33c6056226dbbf6fa5b..9d2d55154c46c7cf425063f2d8bbeb07a65caa23 100644 (file)
@@ -727,12 +727,13 @@ static int parse_proc_cmdline(void) {
                 }
 
                 r = parse_proc_cmdline_word(word);
-                free(word);
-
                 if (r < 0) {
                         log_error("Failed on cmdline argument %s: %s", word, strerror(-r));
+                        free(word);
                         goto finish;
                 }
+
+                free(word);
         }
 
         r = 0;
@@ -1124,6 +1125,42 @@ fail:
         return r;
 }
 
+static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
+        struct rlimit nl;
+        int r;
+
+        assert(saved_rlimit);
+
+        /* Save the original RLIMIT_NOFILE so that we can reset it
+         * later when transitioning from the initrd to the main
+         * systemd or suchlike. */
+        if (getrlimit(RLIMIT_NOFILE, saved_rlimit) < 0) {
+                log_error("Reading RLIMIT_NOFILE failed: %m");
+                return -errno;
+        }
+
+        /* Make sure forked processes get the default kernel setting */
+        if (!arg_default_rlimit[RLIMIT_NOFILE]) {
+                struct rlimit *rl;
+
+                rl = newdup(struct rlimit, saved_rlimit, 1);
+                if (!rl)
+                        return log_oom();
+
+                arg_default_rlimit[RLIMIT_NOFILE] = rl;
+        }
+
+        /* Bump up the resource limit for ourselves substantially */
+        nl.rlim_cur = nl.rlim_max = 64*1024;
+        r = setrlimit_closest(RLIMIT_NOFILE, &nl);
+        if (r < 0) {
+                log_error("Setting RLIMIT_NOFILE failed: %s", strerror(-r));
+                return r;
+        }
+
+        return 0;
+}
+
 static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) {
         const char *e;
         unsigned long long a, b;
@@ -1206,6 +1243,7 @@ int main(int argc, char *argv[]) {
         bool arm_reboot_watchdog = false;
         bool queue_default_job = false;
         char *switch_root_dir = NULL, *switch_root_init = NULL;
+        static struct rlimit saved_rlimit_nofile = { 0, 0 };
 
 #ifdef HAVE_SYSV_COMPAT
         if (getpid() != 1 && strstr(program_invocation_short_name, "init")) {
@@ -1247,10 +1285,15 @@ int main(int argc, char *argv[]) {
         saved_argc = argc;
 
         log_show_color(isatty(STDERR_FILENO) > 0);
-        log_show_location(false);
-        log_set_max_level(LOG_INFO);
 
-        if (getpid() == 1) {
+        if (getpid() == 1 && detect_container(NULL) <= 0) {
+
+                /* Running outside of a container as PID 1 */
+                arg_running_as = MANAGER_SYSTEM;
+                make_null_stdio();
+                log_set_target(LOG_TARGET_KMSG);
+                log_open();
+
                 if (in_initrd()) {
                         char *rd_timestamp = NULL;
 
@@ -1264,9 +1307,6 @@ int main(int argc, char *argv[]) {
                         }
                 }
 
-                arg_running_as = MANAGER_SYSTEM;
-                log_set_target(detect_container(NULL) > 0 ? LOG_TARGET_JOURNAL : LOG_TARGET_JOURNAL_OR_KMSG);
-
                 if (!skip_setup) {
                         if (selinux_setup(&loaded_policy) < 0)
                                 goto finish;
@@ -1274,23 +1314,51 @@ int main(int argc, char *argv[]) {
                                 goto finish;
                 }
 
-                log_open();
-
                 if (label_init(NULL) < 0)
                         goto finish;
 
-                if (!skip_setup)
+                if (!skip_setup) {
                         if (hwclock_is_localtime() > 0) {
                                 int min;
 
-                                r = hwclock_apply_localtime_delta(&min);
+                                /* The first-time call to settimeofday() does a time warp in the kernel */
+                                r = hwclock_set_timezone(&min);
                                 if (r < 0)
                                         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 */
+                                hwclock_reset_timezone();
+
+                                /* Tell the kernel our time zone */
+                                r = hwclock_set_timezone(NULL);
+                                if (r < 0)
+                                        log_error("Failed to set the kernel's time zone, ignoring: %s", strerror(-r));
                         }
+                }
+
+                /* Set the default for later on, but don't actually
+                 * open the logs like this for now. Note that if we
+                 * are transitioning from the initrd there might still
+                 * be journal fd open, and we shouldn't attempt
+                 * opening that before we parsed /proc/cmdline which
+                 * might redirect output elsewhere. */
+                log_set_target(LOG_TARGET_JOURNAL_OR_KMSG);
+
+        } else if (getpid() == 1) {
+
+                /* Running inside a container, as PID 1 */
+                arg_running_as = MANAGER_SYSTEM;
+                log_set_target(LOG_TARGET_CONSOLE);
+                log_open();
+
+                /* For the later on, see above... */
+                log_set_target(LOG_TARGET_JOURNAL);
 
         } else {
+
+                /* Running as user instance */
                 arg_running_as = MANAGER_USER;
                 log_set_target(LOG_TARGET_AUTO);
                 log_open();
@@ -1304,12 +1372,13 @@ int main(int argc, char *argv[]) {
         }
 
         /* By default, mount "cpu" and "cpuacct" together */
-        arg_join_controllers = new(char**, 2);
+        arg_join_controllers = new(char**, 3);
         if (!arg_join_controllers)
                 goto finish;
 
-        arg_join_controllers[0] = strv_new("cpu", "cpuacct", NULL);
-        arg_join_controllers[1] = NULL;
+        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])
                 goto finish;
@@ -1437,10 +1506,8 @@ int main(int argc, char *argv[]) {
 
         /* 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 == MANAGER_SYSTEM && arg_action == ACTION_RUN)
                 console_setup(getpid() == 1 && !skip_setup);
-                make_null_stdio();
-        }
 
         /* Open the logging devices, if possible and necessary */
         log_open();
@@ -1512,10 +1579,13 @@ int main(int argc, char *argv[]) {
                 if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0) {
                         log_warning("Failed to make us a subreaper: %m");
                         if (errno == EINVAL)
-                                log_info("Perhaps the kernel version is too old (< 3.3?)");
+                                log_info("Perhaps the kernel version is too old (< 3.4?)");
                 }
         }
 
+        if (arg_running_as == MANAGER_SYSTEM)
+                bump_rlimit_nofile(&saved_rlimit_nofile);
+
         r = manager_new(arg_running_as, &m);
         if (r < 0) {
                 log_error("Failed to allocate manager object: %s", strerror(-r));
@@ -1694,7 +1764,7 @@ finish:
                 manager_free(m);
 
         for (j = 0; j < RLIMIT_NLIMITS; j++)
-                free (arg_default_rlimit[j]);
+                free(arg_default_rlimit[j]);
 
         free(arg_default_unit);
         strv_free(arg_default_controllers);
@@ -1712,6 +1782,12 @@ finish:
                  * rebooted while we do that */
                 watchdog_close(true);
 
+                /* Reset the RLIMIT_NOFILE to the kernel default, so
+                 * that the new systemd can pass the kernel default to
+                 * its child processes */
+                if (saved_rlimit_nofile.rlim_cur > 0)
+                        setrlimit(RLIMIT_NOFILE, &saved_rlimit_nofile);
+
                 if (switch_root_dir) {
                         /* Kill all remaining processes from the
                          * initrd, but don't wait for them, so that we