X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fmount.c;h=0adf04e9bf4aaac25c5f256e42a01c9a336f0632;hb=8e70580bb07ae46dc0b0bf377de6333540668acc;hp=2aaf78ceae91b631ac3197dcd3fa7db1f4a60143;hpb=cd2086fe6573df923dc53ef33998c9fff8c2bda5;p=elogind.git diff --git a/src/core/mount.c b/src/core/mount.c index 2aaf78cea..0adf04e9b 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -25,6 +25,7 @@ #include #include +#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] = {