X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fcore%2Fmount.c;h=3cc3e65b234a9cd867887c8883a66c127e4f9930;hp=f263d9b9d15461539b164d892ab7f5b97df16e48;hb=c2756a68401102786be343712c0c35acbd73d28d;hpb=20ad4cfd8e5592f634f20468798cbc1055ab9faf diff --git a/src/core/mount.c b/src/core/mount.c index f263d9b9d..3cc3e65b2 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" @@ -81,6 +82,7 @@ static void mount_init(Unit *u) { } kill_context_init(&m->kill_context); + cgroup_context_init(&m->cgroup_context); /* We need to make sure that /bin/mount is always called in * the same process group as us, so that the autofs kernel @@ -126,7 +128,8 @@ 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); + cgroup_context_done(&m->cgroup_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; @@ -135,7 +138,7 @@ static void mount_done(Unit *u) { unit_unwatch_timer(u, &m->timer_watch); } -static MountParameters* get_mount_parameters_fragment(Mount *m) { +_pure_ static MountParameters* get_mount_parameters_fragment(Mount *m) { assert(m); if (m->from_fragment) @@ -144,7 +147,7 @@ static MountParameters* get_mount_parameters_fragment(Mount *m) { return NULL; } -static MountParameters* get_mount_parameters(Mount *m) { +_pure_ static MountParameters* get_mount_parameters(Mount *m) { assert(m); if (m->from_proc_self_mountinfo) @@ -222,9 +225,11 @@ static int mount_add_swap_links(Mount *m) { assert(m); - LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SWAP]) - if ((r = swap_add_one_mount_link(SWAP(other), m)) < 0) + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SWAP]) { + r = swap_add_one_mount_link(SWAP(other), m); + if (r < 0) return r; + } return 0; } @@ -235,9 +240,11 @@ static int mount_add_path_links(Mount *m) { assert(m); - LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_PATH]) - if ((r = path_add_one_mount_link(PATH(other), m)) < 0) + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_PATH]) { + r = path_add_one_mount_link(PATH(other), m); + if (r < 0) return r; + } return 0; } @@ -248,9 +255,11 @@ static int mount_add_automount_links(Mount *m) { assert(m); - LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_AUTOMOUNT]) - if ((r = automount_add_one_mount_link(AUTOMOUNT(other), m)) < 0) + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_AUTOMOUNT]) { + r = automount_add_one_mount_link(AUTOMOUNT(other), m); + if (r < 0) return r; + } return 0; } @@ -261,9 +270,11 @@ static int mount_add_socket_links(Mount *m) { assert(m); - LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SOCKET]) - if ((r = socket_add_one_mount_link(SOCKET(other), m)) < 0) + LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SOCKET]) { + r = socket_add_one_mount_link(SOCKET(other), m); + if (r < 0) return r; + } return 0; } @@ -284,7 +295,7 @@ static int mount_add_requires_mounts_links(Mount *m) { } static char* mount_test_option(const char *haystack, const char *needle) { - struct mntent me; + struct mntent me = { .mnt_opts = (char*) haystack }; assert(needle); @@ -294,9 +305,6 @@ static char* mount_test_option(const char *haystack, const char *needle) { if (!haystack) return NULL; - zero(me); - me.mnt_opts = (char*) haystack; - return hasmntopt(&me, needle); } @@ -321,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; } @@ -379,7 +393,8 @@ static int mount_add_device_links(Mount *m) { r = manager_load_unit_prepare(UNIT(m)->manager, name, NULL, NULL, &fsck); if (r < 0) { - log_warning("Failed to prepare unit %s: %s", name, strerror(-r)); + log_warning_unit(name, + "Failed to prepare unit %s: %s", name, strerror(-r)); free(name); return r; } @@ -423,31 +438,49 @@ static int mount_add_quota_links(Mount *m) { } static int mount_add_default_dependencies(Mount *m) { - int r; + const char *after, *after2, *online; MountParameters *p; - const char *after; + int r; assert(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; if (path_equal(m->where, "/")) return 0; - if (mount_is_network(p)) + if (mount_is_network(p)) { after = SPECIAL_REMOTE_FS_PRE_TARGET; - else + after2 = SPECIAL_NETWORK_TARGET; + online = SPECIAL_NETWORK_ONLINE_TARGET; + } else { after = SPECIAL_LOCAL_FS_PRE_TARGET; + after2 = NULL; + online = NULL; + } - r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, after, NULL, true); + r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true); if (r < 0) return r; + if (after2) { + r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after2, NULL, true); + if (r < 0) + return r; + } + + if (online) { + r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, online, NULL, true); + if (r < 0) + return r; + } + r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); if (r < 0) return r; @@ -486,11 +519,13 @@ static int mount_fix_timeouts(Mount *m) { if (!t) return -ENOMEM; - r = parse_usec(t, &u); + r = parse_sec(t, &u); free(t); if (r < 0) { - log_warning("Failed to parse timeout for %s, ignoring: %s", m->where, timeout); + log_warning_unit(UNIT(m)->id, + "Failed to parse timeout for %s, ignoring: %s", + m->where, timeout); return r; } @@ -522,22 +557,29 @@ static int mount_verify(Mount *m) { free(e); if (!b) { - log_error("%s's Where setting doesn't match unit name. Refusing.", UNIT(m)->id); + log_error_unit(UNIT(m)->id, + "%s's Where setting doesn't match unit name. Refusing.", + UNIT(m)->id); return -EINVAL; } if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) { - log_error("Cannot create mount unit for API file system %s. Refusing.", m->where); + log_error_unit(UNIT(m)->id, + "Cannot create mount unit for API file system %s. Refusing.", + m->where); return -EINVAL; } if (UNIT(m)->fragment_path && !m->parameters_fragment.what) { - log_error("%s's What setting is missing. Refusing.", UNIT(m)->id); + log_error_unit(UNIT(m)->id, + "%s's What setting is missing. Refusing.", UNIT(m)->id); return -EBADMSG; } if (m->exec_context.pam_name && m->kill_context.kill_mode != KILL_CONTROL_GROUP) { - log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(m)->id); + log_error_unit(UNIT(m)->id, + "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.", + UNIT(m)->id); return -EINVAL; } @@ -607,7 +649,7 @@ static int mount_add_extras(Mount *m) { return r; } - r = unit_add_default_cgroups(u); + r = unit_add_default_slice(u); if (r < 0) return r; @@ -699,15 +741,16 @@ static void mount_set_state(Mount *m, MountState state) { state == MOUNT_UNMOUNTING_SIGTERM || state == MOUNT_UNMOUNTING_SIGKILL || state == MOUNT_FAILED) { - if (state != old_state) - mount_notify_automount(m, -ENODEV); - } + if (state != old_state) + mount_notify_automount(m, -ENODEV); + } if (state != old_state) - log_debug("%s changed %s -> %s", - UNIT(m)->id, - mount_state_to_string(old_state), - mount_state_to_string(state)); + log_debug_unit(UNIT(m)->id, + "%s changed %s -> %s", + UNIT(m)->id, + mount_state_to_string(old_state), + mount_state_to_string(state)); unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS); m->reload_result = MOUNT_SUCCESS; @@ -803,28 +846,31 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) { assert(c); assert(_pid); + unit_realize_cgroup(UNIT(m)); + r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch); if (r < 0) goto fail; - if ((r = exec_spawn(c, - NULL, - &m->exec_context, - NULL, 0, - UNIT(m)->manager->environment, - true, - true, - true, - UNIT(m)->manager->confirm_spawn, - UNIT(m)->cgroup_bondings, - UNIT(m)->cgroup_attributes, - NULL, - UNIT(m)->id, - NULL, - &pid)) < 0) + r = exec_spawn(c, + NULL, + &m->exec_context, + NULL, 0, + UNIT(m)->manager->environment, + true, + true, + true, + UNIT(m)->manager->confirm_spawn, + UNIT(m)->cgroup_mask, + UNIT(m)->cgroup_path, + UNIT(m)->id, + NULL, + &pid); + if (r < 0) goto fail; - if ((r = unit_watch_pid(UNIT(m), pid)) < 0) + r = unit_watch_pid(UNIT(m), pid); + if (r < 0) /* FIXME: we need to do something here */ goto fail; @@ -844,6 +890,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); } @@ -858,52 +905,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("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("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; @@ -917,25 +935,27 @@ static void mount_enter_signal(Mount *m, MountState state, MountResult f) { return; fail: - log_warning("%s failed to kill processes: %s", UNIT(m)->id, strerror(-r)); + log_warning_unit(UNIT(m)->id, + "%s failed to kill processes: %s", UNIT(m)->id, strerror(-r)); if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL) 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(LOG_NOTICE, + + log_struct_unit(LOG_NOTICE, + unit, "MESSAGE=%s: Directory %s to mount over is not empty, mounting anyway.", unit, where, "WHERE=%s", where, - "_SYSTEMD_UNIT=%s", unit, MESSAGE_ID(SD_MESSAGE_OVERMOUNTING), NULL); } @@ -965,7 +985,9 @@ static void mount_enter_unmounting(Mount *m) { return; fail: - log_warning("%s failed to run 'umount' task: %s", UNIT(m)->id, strerror(-r)); + log_warning_unit(UNIT(m)->id, + "%s failed to run 'umount' task: %s", + UNIT(m)->id, strerror(-r)); mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES); } @@ -1013,7 +1035,9 @@ static void mount_enter_mounting(Mount *m) { return; fail: - log_warning("%s failed to run 'mount' task: %s", UNIT(m)->id, strerror(-r)); + log_warning_unit(UNIT(m)->id, + "%s failed to run 'mount' task: %s", + UNIT(m)->id, strerror(-r)); mount_enter_dead(m, MOUNT_FAILURE_RESOURCES); } @@ -1071,7 +1095,9 @@ static void mount_enter_remounting(Mount *m) { return; fail: - log_warning("%s failed to run 'remount' task: %s", UNIT(m)->id, strerror(-r)); + log_warning_unit(UNIT(m)->id, + "%s failed to run 'remount' task: %s", + UNIT(m)->id, strerror(-r)); m->reload_result = MOUNT_FAILURE_RESOURCES; mount_enter_mounted(m, MOUNT_SUCCESS); } @@ -1158,6 +1184,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; } @@ -1173,7 +1201,7 @@ static int mount_deserialize_item(Unit *u, const char *key, const char *value, F MountState state; if ((state = mount_state_from_string(value)) < 0) - log_debug("Failed to parse state value %s", value); + log_debug_unit(u->id, "Failed to parse state value %s", value); else m->deserialized_state = state; } else if (streq(key, "result")) { @@ -1181,7 +1209,8 @@ static int mount_deserialize_item(Unit *u, const char *key, const char *value, F f = mount_result_from_string(value); if (f < 0) - log_debug("Failed to parse result value %s", value); + log_debug_unit(UNIT(m)->id, + "Failed to parse result value %s", value); else if (f != MOUNT_SUCCESS) m->result = f; @@ -1190,7 +1219,8 @@ static int mount_deserialize_item(Unit *u, const char *key, const char *value, F f = mount_result_from_string(value); if (f < 0) - log_debug("Failed to parse reload result value %s", value); + log_debug_unit(UNIT(m)->id, + "Failed to parse reload result value %s", value); else if (f != MOUNT_SUCCESS) m->reload_result = f; @@ -1198,38 +1228,56 @@ static int mount_deserialize_item(Unit *u, const char *key, const char *value, F pid_t pid; if (parse_pid(value, &pid) < 0) - log_debug("Failed to parse control-pid value %s", value); + log_debug_unit(UNIT(m)->id, + "Failed to parse control-pid value %s", value); else m->control_pid = pid; } else if (streq(key, "control-command")) { MountExecCommand id; if ((id = mount_exec_command_from_string(value)) < 0) - log_debug("Failed to parse exec-command value %s", value); + log_debug_unit(UNIT(m)->id, + "Failed to parse exec-command value %s", value); else { 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("Unknown serialization key '%s'", key); + log_debug_unit(UNIT(m)->id, + "Unknown serialization key '%s'", key); return 0; } -static UnitActiveState mount_active_state(Unit *u) { +_pure_ static UnitActiveState mount_active_state(Unit *u) { assert(u); return state_translation_table[MOUNT(u)->state]; } -static const char *mount_sub_state_to_string(Unit *u) { +_pure_ static const char *mount_sub_state_to_string(Unit *u) { assert(u); return mount_state_to_string(MOUNT(u)->state); } -static bool mount_check_gc(Unit *u) { +_pure_ static bool mount_check_gc(Unit *u) { Mount *m = MOUNT(u); assert(m); @@ -1270,8 +1318,9 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) { m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID; } - log_full(f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE, - "%s mount process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status); + log_full_unit(f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE, u->id, + "%s mount process exited, code=%s status=%i", + u->id, sigchld_code_to_string(code), status); /* Note that mount(8) returning and the kernel sending us a * mount table change event might happen out-of-order. If an @@ -1338,27 +1387,33 @@ static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) { case MOUNT_MOUNTING: case MOUNT_MOUNTING_DONE: - log_warning("%s mounting timed out. Stopping.", u->id); + log_warning_unit(u->id, + "%s mounting timed out. Stopping.", u->id); mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT); break; case MOUNT_REMOUNTING: - log_warning("%s remounting timed out. Stopping.", u->id); + log_warning_unit(u->id, + "%s remounting timed out. Stopping.", u->id); m->reload_result = MOUNT_FAILURE_TIMEOUT; mount_enter_mounted(m, MOUNT_SUCCESS); break; case MOUNT_UNMOUNTING: - log_warning("%s unmounting timed out. Stopping.", u->id); + log_warning_unit(u->id, + "%s unmounting timed out. Stopping.", u->id); mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT); break; case MOUNT_MOUNTING_SIGTERM: if (m->kill_context.send_sigkill) { - log_warning("%s mounting timed out. Killing.", u->id); + log_warning_unit(u->id, + "%s mounting timed out. Killing.", u->id); mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT); } else { - log_warning("%s mounting timed out. Skipping SIGKILL. Ignoring.", u->id); + log_warning_unit(u->id, + "%s mounting timed out. Skipping SIGKILL. Ignoring.", + u->id); if (m->from_proc_self_mountinfo) mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT); @@ -1369,10 +1424,13 @@ static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) { case MOUNT_REMOUNTING_SIGTERM: if (m->kill_context.send_sigkill) { - log_warning("%s remounting timed out. Killing.", u->id); + log_warning_unit(u->id, + "%s remounting timed out. Killing.", u->id); mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT); } else { - log_warning("%s remounting timed out. Skipping SIGKILL. Ignoring.", u->id); + log_warning_unit(u->id, + "%s remounting timed out. Skipping SIGKILL. Ignoring.", + u->id); if (m->from_proc_self_mountinfo) mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT); @@ -1383,10 +1441,13 @@ static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) { case MOUNT_UNMOUNTING_SIGTERM: if (m->kill_context.send_sigkill) { - log_warning("%s unmounting timed out. Killing.", u->id); + log_warning_unit(u->id, + "%s unmounting timed out. Killing.", u->id); mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT); } else { - log_warning("%s unmounting timed out. Skipping SIGKILL. Ignoring.", u->id); + log_warning_unit(u->id, + "%s unmounting timed out. Skipping SIGKILL. Ignoring.", + u->id); if (m->from_proc_self_mountinfo) mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT); @@ -1398,7 +1459,9 @@ static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) { case MOUNT_MOUNTING_SIGKILL: case MOUNT_REMOUNTING_SIGKILL: case MOUNT_UNMOUNTING_SIGKILL: - log_warning("%s mount process still around after SIGKILL. Ignoring.", u->id); + log_warning_unit(u->id, + "%s mount process still around after SIGKILL. Ignoring.", + u->id); if (m->from_proc_self_mountinfo) mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT); @@ -1470,6 +1533,22 @@ 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; + + if (!path_equal(where, "/")) { + 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; @@ -1483,7 +1562,7 @@ static int mount_add_one( } } - if (u->load_state == UNIT_ERROR) { + if (u->load_state == UNIT_NOT_FOUND) { u->load_state = UNIT_LOADED; u->load_error = 0; @@ -1631,25 +1710,27 @@ static void mount_shutdown(Manager *m) { static int mount_enumerate(Manager *m) { int r; - struct epoll_event ev; assert(m); if (!m->proc_self_mountinfo) { - if (!(m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"))) + struct epoll_event ev = { + .events = EPOLLPRI, + .data.ptr = &m->mount_watch, + }; + + m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); + if (!m->proc_self_mountinfo) return -errno; m->mount_watch.type = WATCH_MOUNT; m->mount_watch.fd = fileno(m->proc_self_mountinfo); - zero(ev); - ev.events = EPOLLPRI; - ev.data.ptr = &m->mount_watch; - if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->mount_watch.fd, &ev) < 0) return -errno; } - if ((r = mount_load_proc_self_mountinfo(m, false)) < 0) + r = mount_load_proc_self_mountinfo(m, false); + if (r < 0) goto fail; return 0; @@ -1670,7 +1751,8 @@ void mount_fd_event(Manager *m, int events) { * /proc/self/mountinfo file, which informs us about mounting * table changes */ - if ((r = mount_load_proc_self_mountinfo(m, true)) < 0) { + r = mount_load_proc_self_mountinfo(m, true); + if (r < 0) { log_error("Failed to reread /proc/self/mountinfo: %s", strerror(-r)); /* Reset flags, just in case, for later calls */ @@ -1749,53 +1831,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] = { @@ -1837,13 +1873,16 @@ DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult); const UnitVTable mount_vtable = { .object_size = sizeof(Mount), - .exec_context_offset = offsetof(Mount, exec_context), .sections = "Unit\0" "Mount\0" "Install\0", + .private_section = "Mount", + .exec_context_offset = offsetof(Mount, exec_context), + .cgroup_context_offset = offsetof(Mount, cgroup_context), + .no_alias = true, .no_instances = true, @@ -1877,6 +1916,8 @@ const UnitVTable mount_vtable = { .bus_interface = "org.freedesktop.systemd1.Mount", .bus_message_handler = bus_mount_message_handler, .bus_invalidating_properties = bus_mount_invalidating_properties, + .bus_set_property = bus_mount_set_property, + .bus_commit_properties = bus_mount_commit_properties, .enumerate = mount_enumerate, .shutdown = mount_shutdown,