chiark / gitweb /
hwclock: do not seal the kernel's time-warp call from inside the initrd
[elogind.git] / src / core / main.c
index 04fc0b3b59fda78108d91920f519b35ab72f5f44..4da8ecb86453d8336e998f1c400b34dc3ab74f54 100644 (file)
@@ -62,6 +62,7 @@
 #include "hwclock.h"
 #include "selinux-setup.h"
 #include "ima-setup.h"
+#include "sd-daemon.h"
 
 static enum {
         ACTION_RUN,
@@ -1227,6 +1228,28 @@ static void test_cgroups(void) {
         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;
@@ -1327,8 +1350,15 @@ int main(int argc, char *argv[]) {
                                         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 */
@@ -1371,16 +1401,8 @@ int main(int argc, char *argv[]) {
                 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
@@ -1409,11 +1431,19 @@ int main(int argc, char *argv[]) {
         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 == 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) {