X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fmount.c;h=7a1b411c7b67f48f0221db6e43b4a152062aa66f;hp=03eff9d9edc6b9c3da94d09fd473d5ea47716877;hb=89b1d5e0e49d3b3501e5f3aadcad712290bcd9bf;hpb=71645acac27da55d510f2e4d61cc61b4e5b93035 diff --git a/src/core/mount.c b/src/core/mount.c index 03eff9d9e..7a1b411c7 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -329,6 +329,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 +447,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; @@ -877,56 +884,23 @@ static void mount_enter_mounted(Mount *m, MountResult f) { static void mount_enter_signal(Mount *m, MountState state, MountResult f) { int r; - Set *pid_set = NULL; - bool wait_for_exit = false; assert(m); if (f != MOUNT_SUCCESS) m->result = f; - if (m->kill_context.kill_mode != KILL_NONE) { - int sig = (state == MOUNT_MOUNTING_SIGTERM || - state == MOUNT_UNMOUNTING_SIGTERM || - state == MOUNT_REMOUNTING_SIGTERM) ? m->kill_context.kill_signal : SIGKILL; - - if (m->control_pid > 0) { - if (kill_and_sigcont(m->control_pid, sig) < 0 && errno != ESRCH) - - log_warning_unit(UNIT(m)->id, - "Failed to kill control process %li: %m", - (long) m->control_pid); - else - wait_for_exit = true; - } - - if (m->kill_context.kill_mode == KILL_CONTROL_GROUP) { - - if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) { - r = -ENOMEM; - goto fail; - } - - /* Exclude the control pid from being killed via the cgroup */ - if (m->control_pid > 0) - if ((r = set_put(pid_set, LONG_TO_PTR(m->control_pid))) < 0) - goto fail; - - r = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, sig, true, false, pid_set, NULL); - if (r < 0) { - if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) - log_warning_unit(UNIT(m)->id, - "Failed to kill control group: %s", - strerror(-r)); - } else if (r > 0) - wait_for_exit = true; - - set_free(pid_set); - pid_set = NULL; - } - } + r = unit_kill_context( + UNIT(m), + &m->kill_context, + state != MOUNT_MOUNTING_SIGTERM && state != MOUNT_UNMOUNTING_SIGTERM && state != MOUNT_REMOUNTING_SIGTERM, + -1, + m->control_pid, + false); + if (r < 0) + goto fail; - if (wait_for_exit) { + if (r > 0) { r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch); if (r < 0) goto fail; @@ -947,14 +921,15 @@ fail: mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES); else mount_enter_dead(m, MOUNT_FAILURE_RESOURCES); - - if (pid_set) - set_free(pid_set); } void warn_if_dir_nonempty(const char *unit, const char* where) { + assert(unit); + assert(where); + if (dir_is_empty(where) > 0) return; + log_struct_unit(LOG_NOTICE, unit, "MESSAGE=%s: Directory %s to mount over is not empty, mounting anyway.", @@ -1520,6 +1495,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; @@ -1800,53 +1789,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] = {