chiark / gitweb /
event: implement quit handlers
[elogind.git] / src / core / main.c
index 0ba1d15033253379a4240920054545d88284fc2a..fe291f8410e0822c6580b1251e61884a8731a19b 100644 (file)
@@ -64,7 +64,6 @@
 #endif
 #include "hostname-setup.h"
 #include "machine-id-setup.h"
-#include "locale-setup.h"
 #include "selinux-setup.h"
 #include "ima-setup.h"
 #include "fileio.h"
@@ -349,32 +348,21 @@ static int parse_proc_cmdline_word(const char *word) {
                         arg_default_std_error = r;
         } else if (startswith(word, "systemd.setenv=")) {
                 _cleanup_free_ char *cenv = NULL;
-                char *eq;
-                int r;
 
                 cenv = strdup(word + 15);
                 if (!cenv)
                         return -ENOMEM;
 
-                eq = strchr(cenv, '=');
-                if (!eq) {
-                        if (!env_name_is_valid(cenv))
-                                log_warning("Environment variable name '%s' is not valid. Ignoring.", cenv);
-                        else  {
-                                r = unsetenv(cenv);
-                                if (r < 0)
-                                        log_warning("Unsetting environment variable '%s' failed, ignoring: %m", cenv);
-                        }
-                } else {
-                        if (!env_assignment_is_valid(cenv))
-                                log_warning("Environment variable assignment '%s' is not valid. Ignoring.", cenv);
-                        else {
-                                *eq = 0;
-                                r = setenv(cenv, eq + 1, 1);
-                                if (r < 0)
-                                        log_warning("Setting environment variable '%s=%s' failed, ignoring: %m", cenv, eq + 1);
-                        }
-                }
+                if (env_assignment_is_valid(cenv)) {
+                        char **env;
+
+                        env = strv_env_set(arg_default_environment, cenv);
+                        if (env)
+                                arg_default_environment = env;
+                        else
+                                log_warning("Setting environment variable '%s' failed, ignoring: %m", cenv);
+                } else
+                        log_warning("Environment variable name '%s' is not valid. Ignoring.", cenv);
 
         } else if (startswith(word, "systemd.") ||
                    (in_initrd() && startswith(word, "rd.systemd."))) {
@@ -413,9 +401,14 @@ static int parse_proc_cmdline_word(const char *word) {
 
         } else if (streq(word, "quiet"))
                 arg_show_status = false;
-        else if (streq(word, "debug"))
+        else if (streq(word, "debug")) {
+                /* Log to kmsg, the journal socket will fill up before the
+                 * journal is started and tools running during that time
+                 * will block with every log message for for 60 seconds,
+                 * before they give up. */
                 log_set_max_level(LOG_DEBUG);
-        else if (!in_initrd()) {
+                log_set_target(LOG_TARGET_KMSG);
+        } else if (!in_initrd()) {
                 unsigned i;
 
                 /* SysV compatibility */
@@ -1145,25 +1138,6 @@ static int bump_rlimit_nofile(struct rlimit *saved_rlimit) {
         return 0;
 }
 
-static struct dual_timestamp* parse_initrd_timestamp(struct dual_timestamp *t) {
-        const char *e;
-        unsigned long long a, b;
-
-        assert(t);
-
-        e = getenv("RD_TIMESTAMP");
-        if (!e)
-                return NULL;
-
-        if (sscanf(e, "%llu %llu", &a, &b) != 2)
-                return NULL;
-
-        t->realtime = (usec_t) a;
-        t->monotonic = (usec_t) b;
-
-        return t;
-}
-
 static void test_mtab(void) {
         char *p;
 
@@ -1291,6 +1265,10 @@ int main(int argc, char *argv[]) {
 
         log_show_color(isatty(STDERR_FILENO) > 0);
 
+        /* Disable the umask logic */
+        if (getpid() == 1)
+                umask(0);
+
         if (getpid() == 1 && detect_container(NULL) <= 0) {
 
                 /* Running outside of a container as PID 1 */
@@ -1299,18 +1277,8 @@ int main(int argc, char *argv[]) {
                 log_set_target(LOG_TARGET_KMSG);
                 log_open();
 
-                if (in_initrd()) {
-                        char *rd_timestamp = NULL;
-
+                if (in_initrd())
                         initrd_timestamp = userspace_timestamp;
-                        asprintf(&rd_timestamp, "%llu %llu",
-                                 (unsigned long long) initrd_timestamp.realtime,
-                                 (unsigned long long) initrd_timestamp.monotonic);
-                        if (rd_timestamp) {
-                                setenv("RD_TIMESTAMP", rd_timestamp, 1);
-                                free(rd_timestamp);
-                        }
-                }
 
                 if (!skip_setup) {
                         mount_setup_early();
@@ -1474,59 +1442,12 @@ int main(int argc, char *argv[]) {
         if (serialization)
                 assert_se(fdset_remove(fds, fileno(serialization)) >= 0);
 
-        /* Set up PATH unless it is already set */
-        setenv("PATH",
-#ifdef HAVE_SPLIT_USR
-               "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
-#else
-               "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin",
-#endif
-               arg_running_as == SYSTEMD_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. */
-                if (!in_initrd())
-                        parse_initrd_timestamp(&initrd_timestamp);
-
-                /* Unset some environment variables passed in from the
-                 * kernel that don't really make sense for us. */
-                unsetenv("HOME");
-                unsetenv("TERM");
-
-                /* When we are invoked by a shell, these might be set,
-                 * but make little sense to pass on */
-                unsetenv("PWD");
-                unsetenv("SHLVL");
-                unsetenv("_");
-
-                /* When we are invoked by a chroot-like tool such as
-                 * nspawn, these might be set, but make little sense
-                 * to pass on */
-                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 == SYSTEMD_SYSTEM) {
+        if (arg_running_as == SYSTEMD_SYSTEM)
                 /* Become a session leader if we aren't one yet. */
                 setsid();
 
-                /* Disable the umask logic */
-                umask(0);
-        }
+        /* Move out of the way, so that we won't block unmounts */
+        assert_se(chdir("/")  == 0);
 
         /* Make sure D-Bus doesn't fiddle with the SIGPIPE handlers */
         dbus_connection_set_change_sigpipe(FALSE);
@@ -1565,8 +1486,6 @@ int main(int argc, char *argv[]) {
                 log_debug(PACKAGE_STRING " running in user mode. (" SYSTEMD_FEATURES ")");
 
         if (arg_running_as == SYSTEMD_SYSTEM && !skip_setup) {
-                locale_setup();
-
                 if (arg_show_status || plymouth_running())
                         status_welcome();
 
@@ -1590,14 +1509,14 @@ int main(int argc, char *argv[]) {
                         log_error("Failed to adjust timer slack: %m");
 
         if (arg_capability_bounding_set_drop) {
-                r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true);
+                r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop);
                 if (r < 0) {
-                        log_error("Failed to drop capability bounding set: %s", strerror(-r));
+                        log_error("Failed to drop capability bounding set of usermode helpers: %s", strerror(-r));
                         goto finish;
                 }
-                r = capability_bounding_set_drop_usermode(arg_capability_bounding_set_drop);
+                r = capability_bounding_set_drop(arg_capability_bounding_set_drop, true);
                 if (r < 0) {
-                        log_error("Failed to drop capability bounding set of usermode helpers: %s", strerror(-r));
+                        log_error("Failed to drop capability bounding set: %s", strerror(-r));
                         goto finish;
                 }
         }
@@ -1632,7 +1551,7 @@ int main(int argc, char *argv[]) {
         manager_set_default_rlimits(m, arg_default_rlimit);
 
         if (arg_default_environment)
-                manager_set_default_environment(m, arg_default_environment);
+                manager_environment_add(m, arg_default_environment);
 
         manager_set_show_status(m, arg_show_status);
 
@@ -1648,6 +1567,7 @@ int main(int argc, char *argv[]) {
         /* This will close all file descriptors that were opened, but
          * not claimed by any unit. */
         fdset_free(fds);
+        fds = NULL;
 
         if (serialization) {
                 fclose(serialization);
@@ -1862,6 +1782,10 @@ finish:
                         args[i++] = sfd;
                         args[i++] = NULL;
 
+                        /* do not pass along the environment we inherit from the kernel or initrd */
+                        if (switch_root_dir)
+                                clearenv();
+
                         assert(i <= args_size);
                         execv(args[0], (char* const*) args);
                 }