chiark / gitweb /
core: reuse the same /tmp, /var/tmp and inaccessible dir
[elogind.git] / src / core / mount.c
index 2aaf78ceae91b631ac3197dcd3fa7db1f4a60143..0adf04e9bf4aaac25c5f256e42a01c9a336f0632 100644 (file)
@@ -25,6 +25,7 @@
 #include <sys/epoll.h>
 #include <signal.h>
 
+#include "manager.h"
 #include "unit.h"
 #include "mount.h"
 #include "load-fragment.h"
@@ -126,7 +127,7 @@ static void mount_done(Unit *u) {
         mount_parameters_done(&m->parameters_proc_self_mountinfo);
         mount_parameters_done(&m->parameters_fragment);
 
-        exec_context_done(&m->exec_context);
+        exec_context_done(&m->exec_context, manager_is_reloading_or_reexecuting(u->manager));
         exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
         m->control_command = NULL;
 
@@ -329,6 +330,12 @@ static bool mount_is_bind(MountParameters *p) {
         if (p->fstype && streq(p->fstype, "bind"))
                 return true;
 
+        if (mount_test_option(p->options, "rbind"))
+                return true;
+
+        if (p->fstype && streq(p->fstype, "rbind"))
+                return true;
+
         return false;
 }
 
@@ -441,7 +448,8 @@ static int mount_add_default_dependencies(Mount *m) {
         if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
                 return 0;
 
-        p = get_mount_parameters_fragment(m);
+        p = get_mount_parameters(m);
+
         if (!p)
                 return 0;
 
@@ -863,6 +871,7 @@ static void mount_enter_dead(Mount *m, MountResult f) {
         if (f != MOUNT_SUCCESS)
                 m->result = f;
 
+        exec_context_tmp_dirs_done(&m->exec_context);
         mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
 }
 
@@ -1156,6 +1165,8 @@ static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
         if (m->control_command_id >= 0)
                 unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id));
 
+        exec_context_serialize(&m->exec_context, UNIT(m), f);
+
         return 0;
 }
 
@@ -1212,7 +1223,22 @@ static int mount_deserialize_item(Unit *u, const char *key, const char *value, F
                         m->control_command_id = id;
                         m->control_command = m->exec_command + id;
                 }
+        } else if (streq(key, "tmp-dir")) {
+                char *t;
+
+                t = strdup(value);
+                if (!t)
+                        return log_oom();
+
+                m->exec_context.tmp_dir = t;
+        } else if (streq(key, "var-tmp-dir")) {
+                char *t;
+
+                t = strdup(value);
+                if (!t)
+                        return log_oom();
 
+                m->exec_context.var_tmp_dir = t;
         } else
                 log_debug_unit(UNIT(m)->id,
                                "Unknown serialization key '%s'", key);
@@ -1440,7 +1466,7 @@ static int mount_add_one(
         int r;
         Unit *u;
         bool delete;
-        char *e, *w = NULL, *o = NULL, *s = NULL, *f = NULL;
+        char *e, *w = NULL, *o = NULL, *f = NULL;
         MountParameters *p;
         bool load_extras = false;
 
@@ -1488,6 +1514,20 @@ static int mount_add_one(
                         goto fail;
                 }
 
+                u->source_path = strdup("/proc/self/mountinfo");
+                if (!u->source_path) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
+
+                r = unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_LOCAL_FS_TARGET, NULL, true);
+                if (r < 0)
+                        goto fail;
+
+                r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
+                if (r < 0)
+                        goto fail;
+
                 unit_add_to_load_queue(u);
         } else {
                 delete = false;
@@ -1513,7 +1553,6 @@ static int mount_add_one(
 
         if (!(w = strdup(what)) ||
             !(o = strdup(options)) ||
-            !(s = strdup("/proc/self/mountinfo")) ||
             !(f = strdup(fstype))) {
                 r = -ENOMEM;
                 goto fail;
@@ -1527,8 +1566,6 @@ static int mount_add_one(
         }
 
         MOUNT(u)->from_proc_self_mountinfo = true;
-        free(u->source_path);
-        u->source_path = s;
 
         free(p->what);
         p->what = w;
@@ -1554,7 +1591,6 @@ static int mount_add_one(
 fail:
         free(w);
         free(o);
-        free(s);
         free(f);
 
         if (delete && u)
@@ -1772,53 +1808,7 @@ static void mount_reset_failed(Unit *u) {
 }
 
 static int mount_kill(Unit *u, KillWho who, int signo, DBusError *error) {
-        Mount *m = MOUNT(u);
-        int r = 0;
-        Set *pid_set = NULL;
-
-        assert(m);
-
-        if (who == KILL_MAIN) {
-                dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Mount units have no main processes");
-                return -ESRCH;
-        }
-
-        if (m->control_pid <= 0 && who == KILL_CONTROL) {
-                dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
-                return -ESRCH;
-        }
-
-        if (who == KILL_CONTROL || who == KILL_ALL)
-                if (m->control_pid > 0)
-                        if (kill(m->control_pid, signo) < 0)
-                                r = -errno;
-
-        if (who == KILL_ALL) {
-                int q;
-
-                pid_set = set_new(trivial_hash_func, trivial_compare_func);
-                if (!pid_set)
-                        return -ENOMEM;
-
-                /* Exclude the control pid from being killed via the cgroup */
-                if (m->control_pid > 0) {
-                        q = set_put(pid_set, LONG_TO_PTR(m->control_pid));
-                        if (q < 0) {
-                                r = q;
-                                goto finish;
-                        }
-                }
-
-                q = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, signo, false, false, pid_set, NULL);
-                if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
-                        r = q;
-        }
-
-finish:
-        if (pid_set)
-                set_free(pid_set);
-
-        return r;
+        return unit_kill_common(u, who, signo, -1, MOUNT(u)->control_pid, error);
 }
 
 static const char* const mount_state_table[_MOUNT_STATE_MAX] = {