chiark / gitweb /
core: rework how we match mount units against each other
[elogind.git] / src / core / manager.c
index 6c082c96b90d3a13c31a83c4335b790f9a0b3955..bc57e4a1fd31ce1a14293ec5fc770d4afb92b38c 100644 (file)
@@ -55,6 +55,7 @@
 #include "util.h"
 #include "mkdir.h"
 #include "ratelimit.h"
+#include "locale-setup.h"
 #include "mount-setup.h"
 #include "unit-name.h"
 #include "dbus-unit.h"
@@ -69,7 +70,7 @@
 #include "cgroup-util.h"
 #include "path-util.h"
 #include "audit-fd.h"
-#include "efivars.h"
+#include "boot-timestamps.h"
 #include "env-util.h"
 
 /* As soon as 5s passed since a unit was added to our GC queue, make sure to run a gc sweep */
@@ -454,22 +455,31 @@ static int manager_setup_signals(Manager *m) {
         return 0;
 }
 
-static void manager_strip_environment(Manager *m) {
+static int manager_default_environment(Manager *m) {
         assert(m);
 
-        /* Remove variables from the inherited set that are part of
-         * the container interface:
-         * http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface */
-        strv_remove_prefix(m->environment, "container=");
-        strv_remove_prefix(m->environment, "container_");
+        if (m->running_as == SYSTEMD_SYSTEM) {
+                /* The system manager always starts with a clean
+                 * environment for its children. It does not import
+                 * the kernel or the parents exported variables.
+                 *
+                 * The initial passed environ is untouched to keep
+                 * /proc/self/environ valid; it is used for tagging
+                 * the init process inside containers. */
+                m->environment = strv_new("PATH=" DEFAULT_PATH,
+                                          NULL);
+
+                /* Import locale variables LC_*= from configuration */
+                locale_setup(&m->environment);
+        } else
+                /* The user manager passes its own environment
+                 * along to its children. */
+                m->environment = strv_copy(environ);
 
-        /* Remove variables from the inherited set that are part of
-         * the initrd interface:
-         * http://www.freedesktop.org/wiki/Software/systemd/InitrdInterface */
-        strv_remove_prefix(m->environment, "RD_");
+        if (!m->environment)
+                return -ENOMEM;
 
-        /* Drop invalid entries */
-        strv_env_clean(m->environment);
+        return 0;
 }
 
 int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) {
@@ -486,7 +496,7 @@ int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) {
 
 #ifdef ENABLE_EFI
         if (detect_container(NULL) <= 0)
-                efi_get_boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
+                boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp);
 #endif
 
         m->running_as = running_as;
@@ -505,12 +515,10 @@ int manager_new(SystemdRunningAs running_as, bool reexecuting, Manager **_m) {
         m->epoll_fd = m->dev_autofs_fd = -1;
         m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
 
-        m->environment = strv_copy(environ);
-        if (!m->environment)
+        r = manager_default_environment(m);
+        if (r < 0)
                 goto fail;
 
-        manager_strip_environment(m);
-
         if (!(m->units = hashmap_new(string_hash_func, string_compare_func)))
                 goto fail;
 
@@ -762,6 +770,9 @@ void manager_free(Manager *m) {
         for (i = 0; i < RLIMIT_NLIMITS; i++)
                 free(m->rlimit[i]);
 
+        assert(hashmap_isempty(m->units_requiring_mounts_for));
+        hashmap_free(m->units_requiring_mounts_for);
+
         free(m);
 }
 
@@ -774,9 +785,11 @@ int manager_enumerate(Manager *m) {
         /* Let's ask every type to load all units from disk/kernel
          * that it might know */
         for (c = 0; c < _UNIT_TYPE_MAX; c++)
-                if (unit_vtable[c]->enumerate)
-                        if ((q = unit_vtable[c]->enumerate(m)) < 0)
+                if (unit_vtable[c]->enumerate) {
+                        q = unit_vtable[c]->enumerate(m);
+                        if (q < 0)
                                 r = q;
+                }
 
         manager_dispatch_load_queue(m);
         return r;
@@ -2651,7 +2664,7 @@ void manager_undo_generators(Manager *m) {
         remove_generator_dir(m, &m->generator_unit_path_late);
 }
 
-int manager_set_default_environment(Manager *m, char **environment) {
+int manager_environment_add(Manager *m, char **environment) {
 
         char **e = NULL;
         assert(m);
@@ -2756,6 +2769,41 @@ void manager_status_printf(Manager *m, bool ephemeral, const char *status, const
         va_end(ap);
 }
 
+int manager_get_unit_by_path(Manager *m, const char *path, const char *suffix, Unit **_found) {
+        _cleanup_free_ char *p = NULL;
+        Unit *found;
+
+        assert(m);
+        assert(path);
+        assert(suffix);
+        assert(_found);
+
+        p = unit_name_from_path(path, suffix);
+        if (!p)
+                return -ENOMEM;
+
+        found = manager_get_unit(m, p);
+        if (!found) {
+                *_found = NULL;
+                return 0;
+        }
+
+        *_found = found;
+        return 1;
+}
+
+Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) {
+        char p[strlen(path)+1];
+
+        assert(m);
+        assert(path);
+
+        strcpy(p, path);
+        path_kill_slashes(p);
+
+        return hashmap_get(m->units_requiring_mounts_for, streq(p, "/") ? "" : p);
+}
+
 void watch_init(Watch *w) {
         assert(w);