1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include <sys/epoll.h>
30 #include "load-fragment.h"
31 #include "load-dropin.h"
35 #include "path-util.h"
36 #include "mount-setup.h"
37 #include "unit-name.h"
38 #include "dbus-mount.h"
40 #include "bus-errors.h"
41 #include "exit-status.h"
44 static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
45 [MOUNT_DEAD] = UNIT_INACTIVE,
46 [MOUNT_MOUNTING] = UNIT_ACTIVATING,
47 [MOUNT_MOUNTING_DONE] = UNIT_ACTIVE,
48 [MOUNT_MOUNTED] = UNIT_ACTIVE,
49 [MOUNT_REMOUNTING] = UNIT_RELOADING,
50 [MOUNT_UNMOUNTING] = UNIT_DEACTIVATING,
51 [MOUNT_MOUNTING_SIGTERM] = UNIT_DEACTIVATING,
52 [MOUNT_MOUNTING_SIGKILL] = UNIT_DEACTIVATING,
53 [MOUNT_REMOUNTING_SIGTERM] = UNIT_RELOADING,
54 [MOUNT_REMOUNTING_SIGKILL] = UNIT_RELOADING,
55 [MOUNT_UNMOUNTING_SIGTERM] = UNIT_DEACTIVATING,
56 [MOUNT_UNMOUNTING_SIGKILL] = UNIT_DEACTIVATING,
57 [MOUNT_FAILED] = UNIT_FAILED
60 static void mount_init(Unit *u) {
64 assert(u->load_state == UNIT_STUB);
66 m->timeout_usec = DEFAULT_TIMEOUT_USEC;
67 m->directory_mode = 0755;
69 exec_context_init(&m->exec_context);
71 if (unit_has_name(u, "-.mount")) {
72 /* Don't allow start/stop for root directory */
73 UNIT(m)->refuse_manual_start = true;
74 UNIT(m)->refuse_manual_stop = true;
76 /* The stdio/kmsg bridge socket is on /, in order to avoid a
77 * dep loop, don't use kmsg logging for -.mount */
78 m->exec_context.std_output = u->manager->default_std_output;
79 m->exec_context.std_error = u->manager->default_std_error;
82 /* We need to make sure that /bin/mount is always called in
83 * the same process group as us, so that the autofs kernel
84 * side doesn't send us another mount request while we are
85 * already trying to comply its last one. */
86 m->exec_context.same_pgrp = true;
88 m->timer_watch.type = WATCH_INVALID;
90 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
92 UNIT(m)->ignore_on_isolate = true;
95 static void mount_unwatch_control_pid(Mount *m) {
98 if (m->control_pid <= 0)
101 unit_unwatch_pid(UNIT(m), m->control_pid);
105 static void mount_parameters_done(MountParameters *p) {
112 p->what = p->options = p->fstype = NULL;
115 static void mount_done(Unit *u) {
123 mount_parameters_done(&m->parameters_proc_self_mountinfo);
124 mount_parameters_done(&m->parameters_fragment);
126 exec_context_done(&m->exec_context);
127 exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
128 m->control_command = NULL;
130 mount_unwatch_control_pid(m);
132 unit_unwatch_timer(u, &m->timer_watch);
135 static MountParameters* get_mount_parameters_fragment(Mount *m) {
138 if (m->from_fragment)
139 return &m->parameters_fragment;
144 static MountParameters* get_mount_parameters(Mount *m) {
147 if (m->from_proc_self_mountinfo)
148 return &m->parameters_proc_self_mountinfo;
150 return get_mount_parameters_fragment(m);
153 static int mount_add_mount_links(Mount *m) {
160 pm = get_mount_parameters_fragment(m);
162 /* Adds in links to other mount points that might lie below or
163 * above us in the hierarchy */
165 LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_MOUNT]) {
166 Mount *n = MOUNT(other);
172 if (UNIT(n)->load_state != UNIT_LOADED)
175 pn = get_mount_parameters_fragment(n);
177 if (path_startswith(m->where, n->where)) {
179 if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0)
183 if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0)
186 } else if (path_startswith(n->where, m->where)) {
188 if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0)
192 if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0)
195 } else if (pm && pm->what && path_startswith(pm->what, n->where)) {
197 if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0)
200 if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0)
203 } else if (pn && pn->what && path_startswith(pn->what, m->where)) {
205 if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0)
208 if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0)
216 static int mount_add_swap_links(Mount *m) {
222 LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SWAP])
223 if ((r = swap_add_one_mount_link(SWAP(other), m)) < 0)
229 static int mount_add_path_links(Mount *m) {
235 LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_PATH])
236 if ((r = path_add_one_mount_link(PATH(other), m)) < 0)
242 static int mount_add_automount_links(Mount *m) {
248 LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_AUTOMOUNT])
249 if ((r = automount_add_one_mount_link(AUTOMOUNT(other), m)) < 0)
255 static int mount_add_socket_links(Mount *m) {
261 LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SOCKET])
262 if ((r = socket_add_one_mount_link(SOCKET(other), m)) < 0)
268 static int mount_add_requires_mounts_links(Mount *m) {
274 LIST_FOREACH(has_requires_mounts_for, other, UNIT(m)->manager->has_requires_mounts_for) {
275 r = unit_add_one_mount_link(other, m);
283 static char* mount_test_option(const char *haystack, const char *needle) {
288 /* Like glibc's hasmntopt(), but works on a string, not a
295 me.mnt_opts = (char*) haystack;
297 return hasmntopt(&me, needle);
300 static bool mount_is_network(MountParameters *p) {
303 if (mount_test_option(p->options, "_netdev"))
306 if (p->fstype && fstype_is_network(p->fstype))
312 static bool mount_is_bind(MountParameters *p) {
315 if (mount_test_option(p->options, "bind"))
318 if (p->fstype && streq(p->fstype, "bind"))
324 static bool needs_quota(MountParameters *p) {
327 if (mount_is_network(p))
330 if (mount_is_bind(p))
333 return mount_test_option(p->options, "usrquota") ||
334 mount_test_option(p->options, "grpquota") ||
335 mount_test_option(p->options, "quota") ||
336 mount_test_option(p->options, "usrjquota") ||
337 mount_test_option(p->options, "grpjquota");
340 static int mount_add_device_links(Mount *m) {
346 p = get_mount_parameters_fragment(m);
353 if (!mount_is_bind(p) &&
354 !path_equal(m->where, "/")) {
355 r = unit_add_node_link(UNIT(m), p->what, false);
362 !path_equal(m->where, "/") &&
363 UNIT(m)->manager->running_as == MANAGER_SYSTEM) {
366 /* Let's add in the fsck service */
368 /* aka SPECIAL_FSCK_SERVICE */
369 name = unit_name_from_path_instance("systemd-fsck", p->what, ".service");
373 r = manager_load_unit_prepare(UNIT(m)->manager, name, NULL, NULL, &fsck);
375 log_warning("Failed to prepare unit %s: %s", name, strerror(-r));
381 SERVICE(fsck)->fsck_passno = p->passno;
383 r = unit_add_two_dependencies(UNIT(m), UNIT_AFTER, UNIT_REQUIRES, fsck, true);
391 static int mount_add_quota_links(Mount *m) {
397 if (UNIT(m)->manager->running_as != MANAGER_SYSTEM)
400 p = get_mount_parameters_fragment(m);
407 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true);
411 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true);
418 static int mount_add_default_dependencies(Mount *m) {
425 if (UNIT(m)->manager->running_as != MANAGER_SYSTEM)
428 p = get_mount_parameters_fragment(m);
432 if (path_equal(m->where, "/"))
435 if (mount_is_network(p))
436 after = SPECIAL_REMOTE_FS_PRE_TARGET;
438 after = SPECIAL_LOCAL_FS_PRE_TARGET;
440 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, after, NULL, true);
444 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
451 static int mount_fix_timeouts(Mount *m) {
453 const char *timeout = NULL;
462 p = get_mount_parameters_fragment(m);
466 /* Allow configuration how long we wait for a device that
467 * backs a mount point to show up. This is useful to support
468 * endless device timeouts for devices that show up only after
469 * user input, like crypto devices. */
471 if ((timeout = mount_test_option(p->options, "comment=systemd.device-timeout")))
473 else if ((timeout = mount_test_option(p->options, "x-systemd.device-timeout")))
478 t = strndup(timeout, strcspn(timeout, ",;" WHITESPACE));
482 r = parse_usec(t, &u);
486 log_warning("Failed to parse timeout for %s, ignoring: %s", m->where, timeout);
490 SET_FOREACH(other, UNIT(m)->dependencies[UNIT_AFTER], i) {
491 if (other->type != UNIT_DEVICE)
494 other->job_timeout = u;
500 static int mount_verify(Mount *m) {
505 if (UNIT(m)->load_state != UNIT_LOADED)
508 if (!m->from_fragment && !m->from_proc_self_mountinfo)
511 if (!(e = unit_name_from_path(m->where, ".mount")))
514 b = unit_has_name(UNIT(m), e);
518 log_error("%s's Where setting doesn't match unit name. Refusing.", UNIT(m)->id);
522 if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) {
523 log_error("Cannot create mount unit for API file system %s. Refusing.", m->where);
527 if (UNIT(m)->fragment_path && !m->parameters_fragment.what) {
528 log_error("%s's What setting is missing. Refusing.", UNIT(m)->id);
532 if (m->exec_context.pam_name && m->exec_context.kill_mode != KILL_CONTROL_GROUP) {
533 log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", UNIT(m)->id);
540 static int mount_add_extras(Mount *m) {
544 r = unit_add_exec_dependencies(u, &m->exec_context);
548 if (UNIT(m)->fragment_path)
549 m->from_fragment = true;
552 m->where = unit_name_to_path(u->id);
557 path_kill_slashes(m->where);
559 if (!UNIT(m)->description) {
560 r = unit_set_description(u, m->where);
565 r = mount_add_device_links(m);
569 r = mount_add_mount_links(m);
573 r = mount_add_socket_links(m);
577 r = mount_add_swap_links(m);
581 r = mount_add_path_links(m);
585 r = mount_add_requires_mounts_links(m);
589 r = mount_add_automount_links(m);
593 r = mount_add_quota_links(m);
597 if (UNIT(m)->default_dependencies) {
598 r = mount_add_default_dependencies(m);
603 r = unit_add_default_cgroups(u);
607 r = mount_fix_timeouts(m);
614 static int mount_load(Unit *u) {
619 assert(u->load_state == UNIT_STUB);
621 r = unit_load_fragment_and_dropin_optional(u);
625 /* This is a new unit? Then let's add in some extras */
626 if (u->load_state == UNIT_LOADED) {
627 r = mount_add_extras(m);
632 return mount_verify(m);
635 static int mount_notify_automount(Mount *m, int status) {
642 SET_FOREACH(p, UNIT(m)->dependencies[UNIT_TRIGGERED_BY], i)
643 if (p->type == UNIT_AUTOMOUNT) {
644 r = automount_send_ready(AUTOMOUNT(p), status);
652 static void mount_set_state(Mount *m, MountState state) {
653 MountState old_state;
656 old_state = m->state;
659 if (state != MOUNT_MOUNTING &&
660 state != MOUNT_MOUNTING_DONE &&
661 state != MOUNT_REMOUNTING &&
662 state != MOUNT_UNMOUNTING &&
663 state != MOUNT_MOUNTING_SIGTERM &&
664 state != MOUNT_MOUNTING_SIGKILL &&
665 state != MOUNT_UNMOUNTING_SIGTERM &&
666 state != MOUNT_UNMOUNTING_SIGKILL &&
667 state != MOUNT_REMOUNTING_SIGTERM &&
668 state != MOUNT_REMOUNTING_SIGKILL) {
669 unit_unwatch_timer(UNIT(m), &m->timer_watch);
670 mount_unwatch_control_pid(m);
671 m->control_command = NULL;
672 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
675 if (state == MOUNT_MOUNTED ||
676 state == MOUNT_REMOUNTING)
677 mount_notify_automount(m, 0);
678 else if (state == MOUNT_DEAD ||
679 state == MOUNT_UNMOUNTING ||
680 state == MOUNT_MOUNTING_SIGTERM ||
681 state == MOUNT_MOUNTING_SIGKILL ||
682 state == MOUNT_REMOUNTING_SIGTERM ||
683 state == MOUNT_REMOUNTING_SIGKILL ||
684 state == MOUNT_UNMOUNTING_SIGTERM ||
685 state == MOUNT_UNMOUNTING_SIGKILL ||
686 state == MOUNT_FAILED)
687 mount_notify_automount(m, -ENODEV);
689 if (state != old_state)
690 log_debug("%s changed %s -> %s",
692 mount_state_to_string(old_state),
693 mount_state_to_string(state));
695 unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
696 m->reload_result = MOUNT_SUCCESS;
699 static int mount_coldplug(Unit *u) {
701 MountState new_state = MOUNT_DEAD;
705 assert(m->state == MOUNT_DEAD);
707 if (m->deserialized_state != m->state)
708 new_state = m->deserialized_state;
709 else if (m->from_proc_self_mountinfo)
710 new_state = MOUNT_MOUNTED;
712 if (new_state != m->state) {
714 if (new_state == MOUNT_MOUNTING ||
715 new_state == MOUNT_MOUNTING_DONE ||
716 new_state == MOUNT_REMOUNTING ||
717 new_state == MOUNT_UNMOUNTING ||
718 new_state == MOUNT_MOUNTING_SIGTERM ||
719 new_state == MOUNT_MOUNTING_SIGKILL ||
720 new_state == MOUNT_UNMOUNTING_SIGTERM ||
721 new_state == MOUNT_UNMOUNTING_SIGKILL ||
722 new_state == MOUNT_REMOUNTING_SIGTERM ||
723 new_state == MOUNT_REMOUNTING_SIGKILL) {
725 if (m->control_pid <= 0)
728 if ((r = unit_watch_pid(UNIT(m), m->control_pid)) < 0)
731 if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0)
735 mount_set_state(m, new_state);
741 static void mount_dump(Unit *u, FILE *f, const char *prefix) {
748 p = get_mount_parameters(m);
751 "%sMount State: %s\n"
755 "%sFile System Type: %s\n"
757 "%sFrom /proc/self/mountinfo: %s\n"
758 "%sFrom fragment: %s\n"
759 "%sDirectoryMode: %04o\n",
760 prefix, mount_state_to_string(m->state),
761 prefix, mount_result_to_string(m->result),
763 prefix, strna(p->what),
764 prefix, strna(p->fstype),
765 prefix, strna(p->options),
766 prefix, yes_no(m->from_proc_self_mountinfo),
767 prefix, yes_no(m->from_fragment),
768 prefix, m->directory_mode);
770 if (m->control_pid > 0)
772 "%sControl PID: %lu\n",
773 prefix, (unsigned long) m->control_pid);
775 exec_context_dump(&m->exec_context, f, prefix);
778 static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
786 if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0)
789 if ((r = exec_spawn(c,
793 UNIT(m)->manager->environment,
797 UNIT(m)->manager->confirm_spawn,
798 UNIT(m)->cgroup_bondings,
799 UNIT(m)->cgroup_attributes,
806 if ((r = unit_watch_pid(UNIT(m), pid)) < 0)
807 /* FIXME: we need to do something here */
815 unit_unwatch_timer(UNIT(m), &m->timer_watch);
820 static void mount_enter_dead(Mount *m, MountResult f) {
823 if (f != MOUNT_SUCCESS)
826 mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
829 static void mount_enter_mounted(Mount *m, MountResult f) {
832 if (f != MOUNT_SUCCESS)
835 mount_set_state(m, MOUNT_MOUNTED);
838 static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
841 bool wait_for_exit = false;
845 if (f != MOUNT_SUCCESS)
848 if (m->exec_context.kill_mode != KILL_NONE) {
849 int sig = (state == MOUNT_MOUNTING_SIGTERM ||
850 state == MOUNT_UNMOUNTING_SIGTERM ||
851 state == MOUNT_REMOUNTING_SIGTERM) ? m->exec_context.kill_signal : SIGKILL;
853 if (m->control_pid > 0) {
854 if (kill_and_sigcont(m->control_pid, sig) < 0 && errno != ESRCH)
856 log_warning("Failed to kill control process %li: %m", (long) m->control_pid);
858 wait_for_exit = true;
861 if (m->exec_context.kill_mode == KILL_CONTROL_GROUP) {
863 if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) {
868 /* Exclude the control pid from being killed via the cgroup */
869 if (m->control_pid > 0)
870 if ((r = set_put(pid_set, LONG_TO_PTR(m->control_pid))) < 0)
873 r = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, sig, true, false, pid_set, NULL);
875 if (r != -EAGAIN && r != -ESRCH && r != -ENOENT)
876 log_warning("Failed to kill control group: %s", strerror(-r));
878 wait_for_exit = true;
886 if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0)
889 mount_set_state(m, state);
890 } else if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
891 mount_enter_mounted(m, MOUNT_SUCCESS);
893 mount_enter_dead(m, MOUNT_SUCCESS);
898 log_warning("%s failed to kill processes: %s", UNIT(m)->id, strerror(-r));
900 if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
901 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
903 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
909 static void mount_enter_unmounting(Mount *m) {
914 m->control_command_id = MOUNT_EXEC_UNMOUNT;
915 m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
917 if ((r = exec_command_set(
924 mount_unwatch_control_pid(m);
926 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
929 mount_set_state(m, MOUNT_UNMOUNTING);
934 log_warning("%s failed to run 'umount' task: %s", UNIT(m)->id, strerror(-r));
935 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
938 static void mount_enter_mounting(Mount *m) {
944 m->control_command_id = MOUNT_EXEC_MOUNT;
945 m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
947 mkdir_p_label(m->where, m->directory_mode);
949 /* Create the source directory for bind-mounts if needed */
950 p = get_mount_parameters_fragment(m);
951 if (p && mount_is_bind(p))
952 mkdir_p_label(p->what, m->directory_mode);
954 if (m->from_fragment)
955 r = exec_command_set(
958 m->parameters_fragment.what,
960 "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
961 m->parameters_fragment.options ? "-o" : NULL, m->parameters_fragment.options,
969 mount_unwatch_control_pid(m);
971 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
974 mount_set_state(m, MOUNT_MOUNTING);
979 log_warning("%s failed to run 'mount' task: %s", UNIT(m)->id, strerror(-r));
980 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
983 static void mount_enter_mounting_done(Mount *m) {
986 mount_set_state(m, MOUNT_MOUNTING_DONE);
989 static void mount_enter_remounting(Mount *m) {
994 m->control_command_id = MOUNT_EXEC_REMOUNT;
995 m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
997 if (m->from_fragment) {
1001 if (m->parameters_fragment.options) {
1002 if (!(buf = strappend("remount,", m->parameters_fragment.options))) {
1011 r = exec_command_set(
1014 m->parameters_fragment.what,
1016 "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
1027 mount_unwatch_control_pid(m);
1029 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
1032 mount_set_state(m, MOUNT_REMOUNTING);
1037 log_warning("%s failed to run 'remount' task: %s", UNIT(m)->id, strerror(-r));
1038 m->reload_result = MOUNT_FAILURE_RESOURCES;
1039 mount_enter_mounted(m, MOUNT_SUCCESS);
1042 static int mount_start(Unit *u) {
1043 Mount *m = MOUNT(u);
1047 /* We cannot fulfill this request right now, try again later
1049 if (m->state == MOUNT_UNMOUNTING ||
1050 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1051 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1052 m->state == MOUNT_MOUNTING_SIGTERM ||
1053 m->state == MOUNT_MOUNTING_SIGKILL)
1056 /* Already on it! */
1057 if (m->state == MOUNT_MOUNTING)
1060 assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED);
1062 m->result = MOUNT_SUCCESS;
1063 m->reload_result = MOUNT_SUCCESS;
1065 mount_enter_mounting(m);
1069 static int mount_stop(Unit *u) {
1070 Mount *m = MOUNT(u);
1075 if (m->state == MOUNT_UNMOUNTING ||
1076 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1077 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1078 m->state == MOUNT_MOUNTING_SIGTERM ||
1079 m->state == MOUNT_MOUNTING_SIGKILL)
1082 assert(m->state == MOUNT_MOUNTING ||
1083 m->state == MOUNT_MOUNTING_DONE ||
1084 m->state == MOUNT_MOUNTED ||
1085 m->state == MOUNT_REMOUNTING ||
1086 m->state == MOUNT_REMOUNTING_SIGTERM ||
1087 m->state == MOUNT_REMOUNTING_SIGKILL);
1089 mount_enter_unmounting(m);
1093 static int mount_reload(Unit *u) {
1094 Mount *m = MOUNT(u);
1098 if (m->state == MOUNT_MOUNTING_DONE)
1101 assert(m->state == MOUNT_MOUNTED);
1103 mount_enter_remounting(m);
1107 static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
1108 Mount *m = MOUNT(u);
1114 unit_serialize_item(u, f, "state", mount_state_to_string(m->state));
1115 unit_serialize_item(u, f, "result", mount_result_to_string(m->result));
1116 unit_serialize_item(u, f, "reload-result", mount_result_to_string(m->reload_result));
1118 if (m->control_pid > 0)
1119 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) m->control_pid);
1121 if (m->control_command_id >= 0)
1122 unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id));
1127 static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1128 Mount *m = MOUNT(u);
1135 if (streq(key, "state")) {
1138 if ((state = mount_state_from_string(value)) < 0)
1139 log_debug("Failed to parse state value %s", value);
1141 m->deserialized_state = state;
1142 } else if (streq(key, "result")) {
1145 f = mount_result_from_string(value);
1147 log_debug("Failed to parse result value %s", value);
1148 else if (f != MOUNT_SUCCESS)
1151 } else if (streq(key, "reload-result")) {
1154 f = mount_result_from_string(value);
1156 log_debug("Failed to parse reload result value %s", value);
1157 else if (f != MOUNT_SUCCESS)
1158 m->reload_result = f;
1160 } else if (streq(key, "control-pid")) {
1163 if (parse_pid(value, &pid) < 0)
1164 log_debug("Failed to parse control-pid value %s", value);
1166 m->control_pid = pid;
1167 } else if (streq(key, "control-command")) {
1168 MountExecCommand id;
1170 if ((id = mount_exec_command_from_string(value)) < 0)
1171 log_debug("Failed to parse exec-command value %s", value);
1173 m->control_command_id = id;
1174 m->control_command = m->exec_command + id;
1178 log_debug("Unknown serialization key '%s'", key);
1183 static UnitActiveState mount_active_state(Unit *u) {
1186 return state_translation_table[MOUNT(u)->state];
1189 static const char *mount_sub_state_to_string(Unit *u) {
1192 return mount_state_to_string(MOUNT(u)->state);
1195 static bool mount_check_gc(Unit *u) {
1196 Mount *m = MOUNT(u);
1200 return m->from_proc_self_mountinfo;
1203 static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1204 Mount *m = MOUNT(u);
1210 if (pid != m->control_pid)
1215 if (is_clean_exit(code, status))
1217 else if (code == CLD_EXITED)
1218 f = MOUNT_FAILURE_EXIT_CODE;
1219 else if (code == CLD_KILLED)
1220 f = MOUNT_FAILURE_SIGNAL;
1221 else if (code == CLD_DUMPED)
1222 f = MOUNT_FAILURE_CORE_DUMP;
1224 assert_not_reached("Unknown code");
1226 if (f != MOUNT_SUCCESS)
1229 if (m->control_command) {
1230 exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
1232 m->control_command = NULL;
1233 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
1236 log_full(f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
1237 "%s mount process exited, code=%s status=%i", u->id, sigchld_code_to_string(code), status);
1239 /* Note that mount(8) returning and the kernel sending us a
1240 * mount table change event might happen out-of-order. If an
1241 * operation succeed we assume the kernel will follow soon too
1242 * and already change into the resulting state. If it fails
1243 * we check if the kernel still knows about the mount. and
1244 * change state accordingly. */
1248 case MOUNT_MOUNTING:
1249 case MOUNT_MOUNTING_DONE:
1250 case MOUNT_MOUNTING_SIGKILL:
1251 case MOUNT_MOUNTING_SIGTERM:
1253 if (f == MOUNT_SUCCESS)
1254 mount_enter_mounted(m, f);
1255 else if (m->from_proc_self_mountinfo)
1256 mount_enter_mounted(m, f);
1258 mount_enter_dead(m, f);
1261 case MOUNT_REMOUNTING:
1262 case MOUNT_REMOUNTING_SIGKILL:
1263 case MOUNT_REMOUNTING_SIGTERM:
1265 m->reload_result = f;
1266 if (m->from_proc_self_mountinfo)
1267 mount_enter_mounted(m, MOUNT_SUCCESS);
1269 mount_enter_dead(m, MOUNT_SUCCESS);
1273 case MOUNT_UNMOUNTING:
1274 case MOUNT_UNMOUNTING_SIGKILL:
1275 case MOUNT_UNMOUNTING_SIGTERM:
1277 if (f == MOUNT_SUCCESS)
1278 mount_enter_dead(m, f);
1279 else if (m->from_proc_self_mountinfo)
1280 mount_enter_mounted(m, f);
1282 mount_enter_dead(m, f);
1286 assert_not_reached("Uh, control process died at wrong time.");
1289 /* Notify clients about changed exit status */
1290 unit_add_to_dbus_queue(u);
1293 static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
1294 Mount *m = MOUNT(u);
1297 assert(elapsed == 1);
1298 assert(w == &m->timer_watch);
1302 case MOUNT_MOUNTING:
1303 case MOUNT_MOUNTING_DONE:
1304 log_warning("%s mounting timed out. Stopping.", u->id);
1305 mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1308 case MOUNT_REMOUNTING:
1309 log_warning("%s remounting timed out. Stopping.", u->id);
1310 m->reload_result = MOUNT_FAILURE_TIMEOUT;
1311 mount_enter_mounted(m, MOUNT_SUCCESS);
1314 case MOUNT_UNMOUNTING:
1315 log_warning("%s unmounting timed out. Stopping.", u->id);
1316 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1319 case MOUNT_MOUNTING_SIGTERM:
1320 if (m->exec_context.send_sigkill) {
1321 log_warning("%s mounting timed out. Killing.", u->id);
1322 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1324 log_warning("%s mounting timed out. Skipping SIGKILL. Ignoring.", u->id);
1326 if (m->from_proc_self_mountinfo)
1327 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1329 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1333 case MOUNT_REMOUNTING_SIGTERM:
1334 if (m->exec_context.send_sigkill) {
1335 log_warning("%s remounting timed out. Killing.", u->id);
1336 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1338 log_warning("%s remounting timed out. Skipping SIGKILL. Ignoring.", u->id);
1340 if (m->from_proc_self_mountinfo)
1341 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1343 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1347 case MOUNT_UNMOUNTING_SIGTERM:
1348 if (m->exec_context.send_sigkill) {
1349 log_warning("%s unmounting timed out. Killing.", u->id);
1350 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1352 log_warning("%s unmounting timed out. Skipping SIGKILL. Ignoring.", u->id);
1354 if (m->from_proc_self_mountinfo)
1355 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1357 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1361 case MOUNT_MOUNTING_SIGKILL:
1362 case MOUNT_REMOUNTING_SIGKILL:
1363 case MOUNT_UNMOUNTING_SIGKILL:
1364 log_warning("%s mount process still around after SIGKILL. Ignoring.", u->id);
1366 if (m->from_proc_self_mountinfo)
1367 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1369 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1373 assert_not_reached("Timeout at wrong time.");
1377 static int mount_add_one(
1381 const char *options,
1388 char *e, *w = NULL, *o = NULL, *f = NULL;
1397 /* Ignore API mount points. They should never be referenced in
1398 * dependencies ever. */
1399 if (mount_point_is_api(where) || mount_point_ignore(where))
1402 if (streq(fstype, "autofs"))
1405 /* probably some kind of swap, ignore */
1406 if (!is_path(where))
1409 e = unit_name_from_path(where, ".mount");
1413 u = manager_get_unit(m, e);
1417 u = unit_new(m, sizeof(Mount));
1423 r = unit_add_name(u, e);
1429 MOUNT(u)->where = strdup(where);
1430 if (!MOUNT(u)->where) {
1435 unit_add_to_load_queue(u);
1441 if (!(w = strdup(what)) ||
1442 !(o = strdup(options)) ||
1443 !(f = strdup(fstype))) {
1448 p = &MOUNT(u)->parameters_proc_self_mountinfo;
1450 MOUNT(u)->is_mounted = true;
1451 MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
1452 MOUNT(u)->just_changed = !streq_ptr(p->options, o);
1455 MOUNT(u)->from_proc_self_mountinfo = true;
1468 unit_add_to_dbus_queue(u);
1483 static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
1486 char *device, *path, *options, *options2, *fstype, *d, *p, *o;
1490 rewind(m->proc_self_mountinfo);
1495 device = path = options = options2 = fstype = d = p = o = NULL;
1497 if ((k = fscanf(m->proc_self_mountinfo,
1498 "%*s " /* (1) mount id */
1499 "%*s " /* (2) parent id */
1500 "%*s " /* (3) major:minor */
1501 "%*s " /* (4) root */
1502 "%ms " /* (5) mount point */
1503 "%ms" /* (6) mount options */
1504 "%*[^-]" /* (7) optional fields */
1505 "- " /* (8) separator */
1506 "%ms " /* (9) file system type */
1507 "%ms" /* (10) mount source */
1508 "%ms" /* (11) mount options 2 */
1509 "%*[^\n]", /* some rubbish at the end */
1519 log_warning("Failed to parse /proc/self/mountinfo:%u.", i);
1523 o = join(options, ",", options2, NULL);
1529 if (!(d = cunescape(device)) ||
1530 !(p = cunescape(path))) {
1535 if ((k = mount_add_one(m, d, p, o, fstype, 0, set_flags)) < 0)
1562 static void mount_shutdown(Manager *m) {
1565 if (m->proc_self_mountinfo) {
1566 fclose(m->proc_self_mountinfo);
1567 m->proc_self_mountinfo = NULL;
1571 static int mount_enumerate(Manager *m) {
1573 struct epoll_event ev;
1576 if (!m->proc_self_mountinfo) {
1577 if (!(m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re")))
1580 m->mount_watch.type = WATCH_MOUNT;
1581 m->mount_watch.fd = fileno(m->proc_self_mountinfo);
1584 ev.events = EPOLLPRI;
1585 ev.data.ptr = &m->mount_watch;
1587 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->mount_watch.fd, &ev) < 0)
1591 if ((r = mount_load_proc_self_mountinfo(m, false)) < 0)
1601 void mount_fd_event(Manager *m, int events) {
1606 assert(events & EPOLLPRI);
1608 /* The manager calls this for every fd event happening on the
1609 * /proc/self/mountinfo file, which informs us about mounting
1612 if ((r = mount_load_proc_self_mountinfo(m, true)) < 0) {
1613 log_error("Failed to reread /proc/self/mountinfo: %s", strerror(-r));
1615 /* Reset flags, just in case, for later calls */
1616 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1617 Mount *mount = MOUNT(u);
1619 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1625 manager_dispatch_load_queue(m);
1627 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1628 Mount *mount = MOUNT(u);
1630 if (!mount->is_mounted) {
1631 /* This has just been unmounted. */
1633 mount->from_proc_self_mountinfo = false;
1635 switch (mount->state) {
1638 mount_enter_dead(mount, MOUNT_SUCCESS);
1642 mount_set_state(mount, mount->state);
1647 } else if (mount->just_mounted || mount->just_changed) {
1649 /* New or changed mount entry */
1651 switch (mount->state) {
1655 mount_enter_mounted(mount, MOUNT_SUCCESS);
1658 case MOUNT_MOUNTING:
1659 mount_enter_mounting_done(mount);
1663 /* Nothing really changed, but let's
1664 * issue an notification call
1665 * nonetheless, in case somebody is
1666 * waiting for this. (e.g. file system
1667 * ro/rw remounts.) */
1668 mount_set_state(mount, mount->state);
1673 /* Reset the flags for later calls */
1674 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1678 static void mount_reset_failed(Unit *u) {
1679 Mount *m = MOUNT(u);
1683 if (m->state == MOUNT_FAILED)
1684 mount_set_state(m, MOUNT_DEAD);
1686 m->result = MOUNT_SUCCESS;
1687 m->reload_result = MOUNT_SUCCESS;
1690 static int mount_kill(Unit *u, KillWho who, KillMode mode, int signo, DBusError *error) {
1691 Mount *m = MOUNT(u);
1693 Set *pid_set = NULL;
1697 if (who == KILL_MAIN) {
1698 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "Mount units have no main processes");
1702 if (m->control_pid <= 0 && who == KILL_CONTROL) {
1703 dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
1707 if (who == KILL_CONTROL || who == KILL_ALL)
1708 if (m->control_pid > 0)
1709 if (kill(m->control_pid, signo) < 0)
1712 if (who == KILL_ALL && mode == KILL_CONTROL_GROUP) {
1715 if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func)))
1718 /* Exclude the control pid from being killed via the cgroup */
1719 if (m->control_pid > 0)
1720 if ((q = set_put(pid_set, LONG_TO_PTR(m->control_pid))) < 0) {
1725 q = cgroup_bonding_kill_list(UNIT(m)->cgroup_bondings, signo, false, false, pid_set, NULL);
1727 if (q != -EAGAIN && q != -ESRCH && q != -ENOENT)
1738 static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
1739 [MOUNT_DEAD] = "dead",
1740 [MOUNT_MOUNTING] = "mounting",
1741 [MOUNT_MOUNTING_DONE] = "mounting-done",
1742 [MOUNT_MOUNTED] = "mounted",
1743 [MOUNT_REMOUNTING] = "remounting",
1744 [MOUNT_UNMOUNTING] = "unmounting",
1745 [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm",
1746 [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill",
1747 [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
1748 [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
1749 [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
1750 [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
1751 [MOUNT_FAILED] = "failed"
1754 DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
1756 static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
1757 [MOUNT_EXEC_MOUNT] = "ExecMount",
1758 [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
1759 [MOUNT_EXEC_REMOUNT] = "ExecRemount",
1762 DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
1764 static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
1765 [MOUNT_SUCCESS] = "success",
1766 [MOUNT_FAILURE_RESOURCES] = "resources",
1767 [MOUNT_FAILURE_TIMEOUT] = "timeout",
1768 [MOUNT_FAILURE_EXIT_CODE] = "exit-code",
1769 [MOUNT_FAILURE_SIGNAL] = "signal",
1770 [MOUNT_FAILURE_CORE_DUMP] = "core-dump"
1773 DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
1775 const UnitVTable mount_vtable = {
1777 .object_size = sizeof(Mount),
1784 .no_instances = true,
1790 .coldplug = mount_coldplug,
1794 .start = mount_start,
1796 .reload = mount_reload,
1800 .serialize = mount_serialize,
1801 .deserialize_item = mount_deserialize_item,
1803 .active_state = mount_active_state,
1804 .sub_state_to_string = mount_sub_state_to_string,
1806 .check_gc = mount_check_gc,
1808 .sigchld_event = mount_sigchld_event,
1809 .timer_event = mount_timer_event,
1811 .reset_failed = mount_reset_failed,
1813 .bus_interface = "org.freedesktop.systemd1.Mount",
1814 .bus_message_handler = bus_mount_message_handler,
1815 .bus_invalidating_properties = bus_mount_invalidating_properties,
1817 .enumerate = mount_enumerate,
1818 .shutdown = mount_shutdown,
1820 .status_message_formats = {
1821 .starting_stopping = {
1822 [0] = "Mounting %s...",
1823 [1] = "Unmounting %s...",
1825 .finished_start_job = {
1826 [JOB_DONE] = "Mounted %s.",
1827 [JOB_FAILED] = "Failed to mount %s.",
1828 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1829 [JOB_TIMEOUT] = "Timed out mounting %s.",
1831 .finished_stop_job = {
1832 [JOB_DONE] = "Unmounted %s.",
1833 [JOB_FAILED] = "Failed unmounting %s.",
1834 [JOB_TIMEOUT] = "Timed out unmounting %s.",