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>
31 #include "load-fragment.h"
32 #include "load-dropin.h"
34 #include "sd-messages.h"
37 #include "path-util.h"
38 #include "mount-setup.h"
39 #include "unit-name.h"
40 #include "dbus-mount.h"
42 #include "bus-errors.h"
43 #include "exit-status.h"
46 static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
47 [MOUNT_DEAD] = UNIT_INACTIVE,
48 [MOUNT_MOUNTING] = UNIT_ACTIVATING,
49 [MOUNT_MOUNTING_DONE] = UNIT_ACTIVE,
50 [MOUNT_MOUNTED] = UNIT_ACTIVE,
51 [MOUNT_REMOUNTING] = UNIT_RELOADING,
52 [MOUNT_UNMOUNTING] = UNIT_DEACTIVATING,
53 [MOUNT_MOUNTING_SIGTERM] = UNIT_DEACTIVATING,
54 [MOUNT_MOUNTING_SIGKILL] = UNIT_DEACTIVATING,
55 [MOUNT_REMOUNTING_SIGTERM] = UNIT_RELOADING,
56 [MOUNT_REMOUNTING_SIGKILL] = UNIT_RELOADING,
57 [MOUNT_UNMOUNTING_SIGTERM] = UNIT_DEACTIVATING,
58 [MOUNT_UNMOUNTING_SIGKILL] = UNIT_DEACTIVATING,
59 [MOUNT_FAILED] = UNIT_FAILED
62 static void mount_init(Unit *u) {
66 assert(u->load_state == UNIT_STUB);
68 m->timeout_usec = DEFAULT_TIMEOUT_USEC;
69 m->directory_mode = 0755;
71 exec_context_init(&m->exec_context);
73 if (unit_has_name(u, "-.mount")) {
74 /* Don't allow start/stop for root directory */
75 UNIT(m)->refuse_manual_start = true;
76 UNIT(m)->refuse_manual_stop = true;
78 /* The stdio/kmsg bridge socket is on /, in order to avoid a
79 * dep loop, don't use kmsg logging for -.mount */
80 m->exec_context.std_output = u->manager->default_std_output;
81 m->exec_context.std_error = u->manager->default_std_error;
84 kill_context_init(&m->kill_context);
86 /* We need to make sure that /bin/mount is always called in
87 * the same process group as us, so that the autofs kernel
88 * side doesn't send us another mount request while we are
89 * already trying to comply its last one. */
90 m->exec_context.same_pgrp = true;
92 m->timer_watch.type = WATCH_INVALID;
94 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
96 UNIT(m)->ignore_on_isolate = true;
99 static void mount_unwatch_control_pid(Mount *m) {
102 if (m->control_pid <= 0)
105 unit_unwatch_pid(UNIT(m), m->control_pid);
109 static void mount_parameters_done(MountParameters *p) {
116 p->what = p->options = p->fstype = NULL;
119 static void mount_done(Unit *u) {
127 mount_parameters_done(&m->parameters_proc_self_mountinfo);
128 mount_parameters_done(&m->parameters_fragment);
130 exec_context_done(&m->exec_context, manager_is_reloading_or_reexecuting(u->manager));
131 exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
132 m->control_command = NULL;
134 mount_unwatch_control_pid(m);
136 unit_unwatch_timer(u, &m->timer_watch);
139 static MountParameters* get_mount_parameters_fragment(Mount *m) {
142 if (m->from_fragment)
143 return &m->parameters_fragment;
148 static MountParameters* get_mount_parameters(Mount *m) {
151 if (m->from_proc_self_mountinfo)
152 return &m->parameters_proc_self_mountinfo;
154 return get_mount_parameters_fragment(m);
157 static int mount_add_mount_links(Mount *m) {
164 pm = get_mount_parameters_fragment(m);
166 /* Adds in links to other mount points that might lie below or
167 * above us in the hierarchy */
169 LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_MOUNT]) {
170 Mount *n = MOUNT(other);
176 if (UNIT(n)->load_state != UNIT_LOADED)
179 pn = get_mount_parameters_fragment(n);
181 if (path_startswith(m->where, n->where)) {
183 if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0)
187 if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0)
190 } else if (path_startswith(n->where, m->where)) {
192 if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0)
196 if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0)
199 } else if (pm && pm->what && path_startswith(pm->what, n->where)) {
201 if ((r = unit_add_dependency(UNIT(m), UNIT_AFTER, UNIT(n), true)) < 0)
204 if ((r = unit_add_dependency(UNIT(m), UNIT_REQUIRES, UNIT(n), true)) < 0)
207 } else if (pn && pn->what && path_startswith(pn->what, m->where)) {
209 if ((r = unit_add_dependency(UNIT(n), UNIT_AFTER, UNIT(m), true)) < 0)
212 if ((r = unit_add_dependency(UNIT(n), UNIT_REQUIRES, UNIT(m), true)) < 0)
220 static int mount_add_swap_links(Mount *m) {
226 LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SWAP]) {
227 r = swap_add_one_mount_link(SWAP(other), m);
235 static int mount_add_path_links(Mount *m) {
241 LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_PATH]) {
242 r = path_add_one_mount_link(PATH(other), m);
250 static int mount_add_automount_links(Mount *m) {
256 LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_AUTOMOUNT]) {
257 r = automount_add_one_mount_link(AUTOMOUNT(other), m);
265 static int mount_add_socket_links(Mount *m) {
271 LIST_FOREACH(units_by_type, other, UNIT(m)->manager->units_by_type[UNIT_SOCKET]) {
272 r = socket_add_one_mount_link(SOCKET(other), m);
280 static int mount_add_requires_mounts_links(Mount *m) {
286 LIST_FOREACH(has_requires_mounts_for, other, UNIT(m)->manager->has_requires_mounts_for) {
287 r = unit_add_one_mount_link(other, m);
295 static char* mount_test_option(const char *haystack, const char *needle) {
300 /* Like glibc's hasmntopt(), but works on a string, not a
307 me.mnt_opts = (char*) haystack;
309 return hasmntopt(&me, needle);
312 static bool mount_is_network(MountParameters *p) {
315 if (mount_test_option(p->options, "_netdev"))
318 if (p->fstype && fstype_is_network(p->fstype))
324 static bool mount_is_bind(MountParameters *p) {
327 if (mount_test_option(p->options, "bind"))
330 if (p->fstype && streq(p->fstype, "bind"))
333 if (mount_test_option(p->options, "rbind"))
336 if (p->fstype && streq(p->fstype, "rbind"))
342 static bool needs_quota(MountParameters *p) {
345 if (mount_is_network(p))
348 if (mount_is_bind(p))
351 return mount_test_option(p->options, "usrquota") ||
352 mount_test_option(p->options, "grpquota") ||
353 mount_test_option(p->options, "quota") ||
354 mount_test_option(p->options, "usrjquota") ||
355 mount_test_option(p->options, "grpjquota");
358 static int mount_add_device_links(Mount *m) {
364 p = get_mount_parameters_fragment(m);
371 if (mount_is_bind(p))
374 if (!is_device_path(p->what))
377 if (path_equal(m->where, "/"))
380 r = unit_add_node_link(UNIT(m), p->what, false);
385 UNIT(m)->manager->running_as == SYSTEMD_SYSTEM) {
388 /* Let's add in the fsck service */
390 /* aka SPECIAL_FSCK_SERVICE */
391 name = unit_name_from_path_instance("systemd-fsck", p->what, ".service");
395 r = manager_load_unit_prepare(UNIT(m)->manager, name, NULL, NULL, &fsck);
397 log_warning_unit(name,
398 "Failed to prepare unit %s: %s", name, strerror(-r));
404 SERVICE(fsck)->fsck_passno = p->passno;
406 r = unit_add_two_dependencies(UNIT(m), UNIT_AFTER, UNIT_REQUIRES, fsck, true);
414 static int mount_add_quota_links(Mount *m) {
420 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
423 p = get_mount_parameters_fragment(m);
430 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true);
434 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true);
441 static int mount_add_default_dependencies(Mount *m) {
444 const char *after, *setup;
448 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
451 p = get_mount_parameters(m);
456 if (path_equal(m->where, "/"))
459 if (mount_is_network(p)) {
460 after = SPECIAL_REMOTE_FS_PRE_TARGET;
461 setup = SPECIAL_REMOTE_FS_SETUP_TARGET;
463 after = SPECIAL_LOCAL_FS_PRE_TARGET;
467 r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true);
472 r = unit_add_dependency_by_name(UNIT(m), UNIT_WANTS, setup, NULL, true);
477 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
484 static int mount_fix_timeouts(Mount *m) {
486 const char *timeout = NULL;
495 p = get_mount_parameters_fragment(m);
499 /* Allow configuration how long we wait for a device that
500 * backs a mount point to show up. This is useful to support
501 * endless device timeouts for devices that show up only after
502 * user input, like crypto devices. */
504 if ((timeout = mount_test_option(p->options, "comment=systemd.device-timeout")))
506 else if ((timeout = mount_test_option(p->options, "x-systemd.device-timeout")))
511 t = strndup(timeout, strcspn(timeout, ",;" WHITESPACE));
515 r = parse_usec(t, &u);
519 log_warning_unit(UNIT(m)->id,
520 "Failed to parse timeout for %s, ignoring: %s",
525 SET_FOREACH(other, UNIT(m)->dependencies[UNIT_AFTER], i) {
526 if (other->type != UNIT_DEVICE)
529 other->job_timeout = u;
535 static int mount_verify(Mount *m) {
540 if (UNIT(m)->load_state != UNIT_LOADED)
543 if (!m->from_fragment && !m->from_proc_self_mountinfo)
546 if (!(e = unit_name_from_path(m->where, ".mount")))
549 b = unit_has_name(UNIT(m), e);
553 log_error_unit(UNIT(m)->id,
554 "%s's Where setting doesn't match unit name. Refusing.",
559 if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) {
560 log_error_unit(UNIT(m)->id,
561 "Cannot create mount unit for API file system %s. Refusing.",
566 if (UNIT(m)->fragment_path && !m->parameters_fragment.what) {
567 log_error_unit(UNIT(m)->id,
568 "%s's What setting is missing. Refusing.", UNIT(m)->id);
572 if (m->exec_context.pam_name && m->kill_context.kill_mode != KILL_CONTROL_GROUP) {
573 log_error_unit(UNIT(m)->id,
574 "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.",
582 static int mount_add_extras(Mount *m) {
586 if (UNIT(m)->fragment_path)
587 m->from_fragment = true;
590 m->where = unit_name_to_path(u->id);
595 path_kill_slashes(m->where);
597 r = unit_add_exec_dependencies(u, &m->exec_context);
601 if (!UNIT(m)->description) {
602 r = unit_set_description(u, m->where);
607 r = mount_add_device_links(m);
611 r = mount_add_mount_links(m);
615 r = mount_add_socket_links(m);
619 r = mount_add_swap_links(m);
623 r = mount_add_path_links(m);
627 r = mount_add_requires_mounts_links(m);
631 r = mount_add_automount_links(m);
635 r = mount_add_quota_links(m);
639 if (UNIT(m)->default_dependencies) {
640 r = mount_add_default_dependencies(m);
645 r = unit_add_default_cgroups(u);
649 r = mount_fix_timeouts(m);
656 static int mount_load(Unit *u) {
661 assert(u->load_state == UNIT_STUB);
663 if (m->from_proc_self_mountinfo)
664 r = unit_load_fragment_and_dropin_optional(u);
666 r = unit_load_fragment_and_dropin(u);
671 /* This is a new unit? Then let's add in some extras */
672 if (u->load_state == UNIT_LOADED) {
673 r = mount_add_extras(m);
677 r = unit_exec_context_defaults(u, &m->exec_context);
682 return mount_verify(m);
685 static int mount_notify_automount(Mount *m, int status) {
692 SET_FOREACH(p, UNIT(m)->dependencies[UNIT_TRIGGERED_BY], i)
693 if (p->type == UNIT_AUTOMOUNT) {
694 r = automount_send_ready(AUTOMOUNT(p), status);
702 static void mount_set_state(Mount *m, MountState state) {
703 MountState old_state;
706 old_state = m->state;
709 if (state != MOUNT_MOUNTING &&
710 state != MOUNT_MOUNTING_DONE &&
711 state != MOUNT_REMOUNTING &&
712 state != MOUNT_UNMOUNTING &&
713 state != MOUNT_MOUNTING_SIGTERM &&
714 state != MOUNT_MOUNTING_SIGKILL &&
715 state != MOUNT_UNMOUNTING_SIGTERM &&
716 state != MOUNT_UNMOUNTING_SIGKILL &&
717 state != MOUNT_REMOUNTING_SIGTERM &&
718 state != MOUNT_REMOUNTING_SIGKILL) {
719 unit_unwatch_timer(UNIT(m), &m->timer_watch);
720 mount_unwatch_control_pid(m);
721 m->control_command = NULL;
722 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
725 if (state == MOUNT_MOUNTED ||
726 state == MOUNT_REMOUNTING)
727 mount_notify_automount(m, 0);
728 else if (state == MOUNT_DEAD ||
729 state == MOUNT_UNMOUNTING ||
730 state == MOUNT_MOUNTING_SIGTERM ||
731 state == MOUNT_MOUNTING_SIGKILL ||
732 state == MOUNT_REMOUNTING_SIGTERM ||
733 state == MOUNT_REMOUNTING_SIGKILL ||
734 state == MOUNT_UNMOUNTING_SIGTERM ||
735 state == MOUNT_UNMOUNTING_SIGKILL ||
736 state == MOUNT_FAILED) {
737 if (state != old_state)
738 mount_notify_automount(m, -ENODEV);
741 if (state != old_state)
742 log_debug_unit(UNIT(m)->id,
743 "%s changed %s -> %s",
745 mount_state_to_string(old_state),
746 mount_state_to_string(state));
748 unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
749 m->reload_result = MOUNT_SUCCESS;
752 static int mount_coldplug(Unit *u) {
754 MountState new_state = MOUNT_DEAD;
758 assert(m->state == MOUNT_DEAD);
760 if (m->deserialized_state != m->state)
761 new_state = m->deserialized_state;
762 else if (m->from_proc_self_mountinfo)
763 new_state = MOUNT_MOUNTED;
765 if (new_state != m->state) {
767 if (new_state == MOUNT_MOUNTING ||
768 new_state == MOUNT_MOUNTING_DONE ||
769 new_state == MOUNT_REMOUNTING ||
770 new_state == MOUNT_UNMOUNTING ||
771 new_state == MOUNT_MOUNTING_SIGTERM ||
772 new_state == MOUNT_MOUNTING_SIGKILL ||
773 new_state == MOUNT_UNMOUNTING_SIGTERM ||
774 new_state == MOUNT_UNMOUNTING_SIGKILL ||
775 new_state == MOUNT_REMOUNTING_SIGTERM ||
776 new_state == MOUNT_REMOUNTING_SIGKILL) {
778 if (m->control_pid <= 0)
781 r = unit_watch_pid(UNIT(m), m->control_pid);
785 r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
790 mount_set_state(m, new_state);
796 static void mount_dump(Unit *u, FILE *f, const char *prefix) {
803 p = get_mount_parameters(m);
806 "%sMount State: %s\n"
810 "%sFile System Type: %s\n"
812 "%sFrom /proc/self/mountinfo: %s\n"
813 "%sFrom fragment: %s\n"
814 "%sDirectoryMode: %04o\n",
815 prefix, mount_state_to_string(m->state),
816 prefix, mount_result_to_string(m->result),
818 prefix, strna(p->what),
819 prefix, strna(p->fstype),
820 prefix, strna(p->options),
821 prefix, yes_no(m->from_proc_self_mountinfo),
822 prefix, yes_no(m->from_fragment),
823 prefix, m->directory_mode);
825 if (m->control_pid > 0)
827 "%sControl PID: %lu\n",
828 prefix, (unsigned long) m->control_pid);
830 exec_context_dump(&m->exec_context, f, prefix);
831 kill_context_dump(&m->kill_context, f, prefix);
834 static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
842 r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
846 if ((r = exec_spawn(c,
850 UNIT(m)->manager->environment,
854 UNIT(m)->manager->confirm_spawn,
855 UNIT(m)->cgroup_bondings,
856 UNIT(m)->cgroup_attributes,
863 if ((r = unit_watch_pid(UNIT(m), pid)) < 0)
864 /* FIXME: we need to do something here */
872 unit_unwatch_timer(UNIT(m), &m->timer_watch);
877 static void mount_enter_dead(Mount *m, MountResult f) {
880 if (f != MOUNT_SUCCESS)
883 exec_context_tmp_dirs_done(&m->exec_context);
884 mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
887 static void mount_enter_mounted(Mount *m, MountResult f) {
890 if (f != MOUNT_SUCCESS)
893 mount_set_state(m, MOUNT_MOUNTED);
896 static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
901 if (f != MOUNT_SUCCESS)
904 r = unit_kill_context(
907 state != MOUNT_MOUNTING_SIGTERM && state != MOUNT_UNMOUNTING_SIGTERM && state != MOUNT_REMOUNTING_SIGTERM,
915 r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
919 mount_set_state(m, state);
920 } else if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
921 mount_enter_mounted(m, MOUNT_SUCCESS);
923 mount_enter_dead(m, MOUNT_SUCCESS);
928 log_warning_unit(UNIT(m)->id,
929 "%s failed to kill processes: %s", UNIT(m)->id, strerror(-r));
931 if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
932 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
934 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
937 void warn_if_dir_nonempty(const char *unit, const char* where) {
941 if (dir_is_empty(where) > 0)
944 log_struct_unit(LOG_NOTICE,
946 "MESSAGE=%s: Directory %s to mount over is not empty, mounting anyway.",
949 MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
953 static void mount_enter_unmounting(Mount *m) {
958 m->control_command_id = MOUNT_EXEC_UNMOUNT;
959 m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
961 if ((r = exec_command_set(
968 mount_unwatch_control_pid(m);
970 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
973 mount_set_state(m, MOUNT_UNMOUNTING);
978 log_warning_unit(UNIT(m)->id,
979 "%s failed to run 'umount' task: %s",
980 UNIT(m)->id, strerror(-r));
981 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
984 static void mount_enter_mounting(Mount *m) {
990 m->control_command_id = MOUNT_EXEC_MOUNT;
991 m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
993 mkdir_p_label(m->where, m->directory_mode);
995 warn_if_dir_nonempty(m->meta.id, m->where);
997 /* Create the source directory for bind-mounts if needed */
998 p = get_mount_parameters_fragment(m);
999 if (p && mount_is_bind(p))
1000 mkdir_p_label(p->what, m->directory_mode);
1002 if (m->from_fragment)
1003 r = exec_command_set(
1006 m->parameters_fragment.what,
1008 "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
1009 m->parameters_fragment.options ? "-o" : NULL, m->parameters_fragment.options,
1017 mount_unwatch_control_pid(m);
1019 r = mount_spawn(m, m->control_command, &m->control_pid);
1023 mount_set_state(m, MOUNT_MOUNTING);
1028 log_warning_unit(UNIT(m)->id,
1029 "%s failed to run 'mount' task: %s",
1030 UNIT(m)->id, strerror(-r));
1031 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
1034 static void mount_enter_mounting_done(Mount *m) {
1037 mount_set_state(m, MOUNT_MOUNTING_DONE);
1040 static void mount_enter_remounting(Mount *m) {
1045 m->control_command_id = MOUNT_EXEC_REMOUNT;
1046 m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
1048 if (m->from_fragment) {
1052 if (m->parameters_fragment.options) {
1053 if (!(buf = strappend("remount,", m->parameters_fragment.options))) {
1062 r = exec_command_set(
1065 m->parameters_fragment.what,
1067 "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
1078 mount_unwatch_control_pid(m);
1080 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
1083 mount_set_state(m, MOUNT_REMOUNTING);
1088 log_warning_unit(UNIT(m)->id,
1089 "%s failed to run 'remount' task: %s",
1090 UNIT(m)->id, strerror(-r));
1091 m->reload_result = MOUNT_FAILURE_RESOURCES;
1092 mount_enter_mounted(m, MOUNT_SUCCESS);
1095 static int mount_start(Unit *u) {
1096 Mount *m = MOUNT(u);
1100 /* We cannot fulfill this request right now, try again later
1102 if (m->state == MOUNT_UNMOUNTING ||
1103 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1104 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1105 m->state == MOUNT_MOUNTING_SIGTERM ||
1106 m->state == MOUNT_MOUNTING_SIGKILL)
1109 /* Already on it! */
1110 if (m->state == MOUNT_MOUNTING)
1113 assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED);
1115 m->result = MOUNT_SUCCESS;
1116 m->reload_result = MOUNT_SUCCESS;
1118 mount_enter_mounting(m);
1122 static int mount_stop(Unit *u) {
1123 Mount *m = MOUNT(u);
1128 if (m->state == MOUNT_UNMOUNTING ||
1129 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1130 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1131 m->state == MOUNT_MOUNTING_SIGTERM ||
1132 m->state == MOUNT_MOUNTING_SIGKILL)
1135 assert(m->state == MOUNT_MOUNTING ||
1136 m->state == MOUNT_MOUNTING_DONE ||
1137 m->state == MOUNT_MOUNTED ||
1138 m->state == MOUNT_REMOUNTING ||
1139 m->state == MOUNT_REMOUNTING_SIGTERM ||
1140 m->state == MOUNT_REMOUNTING_SIGKILL);
1142 mount_enter_unmounting(m);
1146 static int mount_reload(Unit *u) {
1147 Mount *m = MOUNT(u);
1151 if (m->state == MOUNT_MOUNTING_DONE)
1154 assert(m->state == MOUNT_MOUNTED);
1156 mount_enter_remounting(m);
1160 static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
1161 Mount *m = MOUNT(u);
1167 unit_serialize_item(u, f, "state", mount_state_to_string(m->state));
1168 unit_serialize_item(u, f, "result", mount_result_to_string(m->result));
1169 unit_serialize_item(u, f, "reload-result", mount_result_to_string(m->reload_result));
1171 if (m->control_pid > 0)
1172 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) m->control_pid);
1174 if (m->control_command_id >= 0)
1175 unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id));
1177 exec_context_serialize(&m->exec_context, UNIT(m), f);
1182 static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1183 Mount *m = MOUNT(u);
1190 if (streq(key, "state")) {
1193 if ((state = mount_state_from_string(value)) < 0)
1194 log_debug_unit(u->id, "Failed to parse state value %s", value);
1196 m->deserialized_state = state;
1197 } else if (streq(key, "result")) {
1200 f = mount_result_from_string(value);
1202 log_debug_unit(UNIT(m)->id,
1203 "Failed to parse result value %s", value);
1204 else if (f != MOUNT_SUCCESS)
1207 } else if (streq(key, "reload-result")) {
1210 f = mount_result_from_string(value);
1212 log_debug_unit(UNIT(m)->id,
1213 "Failed to parse reload result value %s", value);
1214 else if (f != MOUNT_SUCCESS)
1215 m->reload_result = f;
1217 } else if (streq(key, "control-pid")) {
1220 if (parse_pid(value, &pid) < 0)
1221 log_debug_unit(UNIT(m)->id,
1222 "Failed to parse control-pid value %s", value);
1224 m->control_pid = pid;
1225 } else if (streq(key, "control-command")) {
1226 MountExecCommand id;
1228 if ((id = mount_exec_command_from_string(value)) < 0)
1229 log_debug_unit(UNIT(m)->id,
1230 "Failed to parse exec-command value %s", value);
1232 m->control_command_id = id;
1233 m->control_command = m->exec_command + id;
1235 } else if (streq(key, "tmp-dir")) {
1242 m->exec_context.tmp_dir = t;
1243 } else if (streq(key, "var-tmp-dir")) {
1250 m->exec_context.var_tmp_dir = t;
1252 log_debug_unit(UNIT(m)->id,
1253 "Unknown serialization key '%s'", key);
1258 static UnitActiveState mount_active_state(Unit *u) {
1261 return state_translation_table[MOUNT(u)->state];
1264 static const char *mount_sub_state_to_string(Unit *u) {
1267 return mount_state_to_string(MOUNT(u)->state);
1270 static bool mount_check_gc(Unit *u) {
1271 Mount *m = MOUNT(u);
1275 return m->from_proc_self_mountinfo;
1278 static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1279 Mount *m = MOUNT(u);
1285 if (pid != m->control_pid)
1290 if (is_clean_exit(code, status, NULL))
1292 else if (code == CLD_EXITED)
1293 f = MOUNT_FAILURE_EXIT_CODE;
1294 else if (code == CLD_KILLED)
1295 f = MOUNT_FAILURE_SIGNAL;
1296 else if (code == CLD_DUMPED)
1297 f = MOUNT_FAILURE_CORE_DUMP;
1299 assert_not_reached("Unknown code");
1301 if (f != MOUNT_SUCCESS)
1304 if (m->control_command) {
1305 exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
1307 m->control_command = NULL;
1308 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
1311 log_full_unit(f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE, u->id,
1312 "%s mount process exited, code=%s status=%i",
1313 u->id, sigchld_code_to_string(code), status);
1315 /* Note that mount(8) returning and the kernel sending us a
1316 * mount table change event might happen out-of-order. If an
1317 * operation succeed we assume the kernel will follow soon too
1318 * and already change into the resulting state. If it fails
1319 * we check if the kernel still knows about the mount. and
1320 * change state accordingly. */
1324 case MOUNT_MOUNTING:
1325 case MOUNT_MOUNTING_DONE:
1326 case MOUNT_MOUNTING_SIGKILL:
1327 case MOUNT_MOUNTING_SIGTERM:
1329 if (f == MOUNT_SUCCESS)
1330 mount_enter_mounted(m, f);
1331 else if (m->from_proc_self_mountinfo)
1332 mount_enter_mounted(m, f);
1334 mount_enter_dead(m, f);
1337 case MOUNT_REMOUNTING:
1338 case MOUNT_REMOUNTING_SIGKILL:
1339 case MOUNT_REMOUNTING_SIGTERM:
1341 m->reload_result = f;
1342 if (m->from_proc_self_mountinfo)
1343 mount_enter_mounted(m, MOUNT_SUCCESS);
1345 mount_enter_dead(m, MOUNT_SUCCESS);
1349 case MOUNT_UNMOUNTING:
1350 case MOUNT_UNMOUNTING_SIGKILL:
1351 case MOUNT_UNMOUNTING_SIGTERM:
1353 if (f == MOUNT_SUCCESS)
1354 mount_enter_dead(m, f);
1355 else if (m->from_proc_self_mountinfo)
1356 mount_enter_mounted(m, f);
1358 mount_enter_dead(m, f);
1362 assert_not_reached("Uh, control process died at wrong time.");
1365 /* Notify clients about changed exit status */
1366 unit_add_to_dbus_queue(u);
1369 static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
1370 Mount *m = MOUNT(u);
1373 assert(elapsed == 1);
1374 assert(w == &m->timer_watch);
1378 case MOUNT_MOUNTING:
1379 case MOUNT_MOUNTING_DONE:
1380 log_warning_unit(u->id,
1381 "%s mounting timed out. Stopping.", u->id);
1382 mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1385 case MOUNT_REMOUNTING:
1386 log_warning_unit(u->id,
1387 "%s remounting timed out. Stopping.", u->id);
1388 m->reload_result = MOUNT_FAILURE_TIMEOUT;
1389 mount_enter_mounted(m, MOUNT_SUCCESS);
1392 case MOUNT_UNMOUNTING:
1393 log_warning_unit(u->id,
1394 "%s unmounting timed out. Stopping.", u->id);
1395 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1398 case MOUNT_MOUNTING_SIGTERM:
1399 if (m->kill_context.send_sigkill) {
1400 log_warning_unit(u->id,
1401 "%s mounting timed out. Killing.", u->id);
1402 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1404 log_warning_unit(u->id,
1405 "%s mounting timed out. Skipping SIGKILL. Ignoring.",
1408 if (m->from_proc_self_mountinfo)
1409 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1411 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1415 case MOUNT_REMOUNTING_SIGTERM:
1416 if (m->kill_context.send_sigkill) {
1417 log_warning_unit(u->id,
1418 "%s remounting timed out. Killing.", u->id);
1419 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1421 log_warning_unit(u->id,
1422 "%s remounting timed out. Skipping SIGKILL. Ignoring.",
1425 if (m->from_proc_self_mountinfo)
1426 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1428 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1432 case MOUNT_UNMOUNTING_SIGTERM:
1433 if (m->kill_context.send_sigkill) {
1434 log_warning_unit(u->id,
1435 "%s unmounting timed out. Killing.", u->id);
1436 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1438 log_warning_unit(u->id,
1439 "%s unmounting timed out. Skipping SIGKILL. Ignoring.",
1442 if (m->from_proc_self_mountinfo)
1443 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1445 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1449 case MOUNT_MOUNTING_SIGKILL:
1450 case MOUNT_REMOUNTING_SIGKILL:
1451 case MOUNT_UNMOUNTING_SIGKILL:
1452 log_warning_unit(u->id,
1453 "%s mount process still around after SIGKILL. Ignoring.",
1456 if (m->from_proc_self_mountinfo)
1457 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1459 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1463 assert_not_reached("Timeout at wrong time.");
1467 static int mount_add_one(
1471 const char *options,
1478 char *e, *w = NULL, *o = NULL, *f = NULL;
1480 bool load_extras = false;
1488 /* Ignore API mount points. They should never be referenced in
1489 * dependencies ever. */
1490 if (mount_point_is_api(where) || mount_point_ignore(where))
1493 if (streq(fstype, "autofs"))
1496 /* probably some kind of swap, ignore */
1497 if (!is_path(where))
1500 e = unit_name_from_path(where, ".mount");
1504 u = manager_get_unit(m, e);
1508 u = unit_new(m, sizeof(Mount));
1514 r = unit_add_name(u, e);
1520 MOUNT(u)->where = strdup(where);
1521 if (!MOUNT(u)->where) {
1526 u->source_path = strdup("/proc/self/mountinfo");
1527 if (!u->source_path) {
1532 r = unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_LOCAL_FS_TARGET, NULL, true);
1536 r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
1540 unit_add_to_load_queue(u);
1545 if (!MOUNT(u)->where) {
1546 MOUNT(u)->where = strdup(where);
1547 if (!MOUNT(u)->where) {
1553 if (u->load_state == UNIT_ERROR) {
1554 u->load_state = UNIT_LOADED;
1557 /* Load in the extras later on, after we
1558 * finished initialization of the unit */
1563 if (!(w = strdup(what)) ||
1564 !(o = strdup(options)) ||
1565 !(f = strdup(fstype))) {
1570 p = &MOUNT(u)->parameters_proc_self_mountinfo;
1572 MOUNT(u)->is_mounted = true;
1573 MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
1574 MOUNT(u)->just_changed = !streq_ptr(p->options, o);
1577 MOUNT(u)->from_proc_self_mountinfo = true;
1591 r = mount_add_extras(MOUNT(u));
1596 unit_add_to_dbus_queue(u);
1611 static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
1614 char *device, *path, *options, *options2, *fstype, *d, *p, *o;
1618 rewind(m->proc_self_mountinfo);
1623 device = path = options = options2 = fstype = d = p = o = NULL;
1625 if ((k = fscanf(m->proc_self_mountinfo,
1626 "%*s " /* (1) mount id */
1627 "%*s " /* (2) parent id */
1628 "%*s " /* (3) major:minor */
1629 "%*s " /* (4) root */
1630 "%ms " /* (5) mount point */
1631 "%ms" /* (6) mount options */
1632 "%*[^-]" /* (7) optional fields */
1633 "- " /* (8) separator */
1634 "%ms " /* (9) file system type */
1635 "%ms" /* (10) mount source */
1636 "%ms" /* (11) mount options 2 */
1637 "%*[^\n]", /* some rubbish at the end */
1647 log_warning("Failed to parse /proc/self/mountinfo:%u.", i);
1651 o = strjoin(options, ",", options2, NULL);
1657 if (!(d = cunescape(device)) ||
1658 !(p = cunescape(path))) {
1663 if ((k = mount_add_one(m, d, p, o, fstype, 0, set_flags)) < 0)
1690 static void mount_shutdown(Manager *m) {
1693 if (m->proc_self_mountinfo) {
1694 fclose(m->proc_self_mountinfo);
1695 m->proc_self_mountinfo = NULL;
1699 static int mount_enumerate(Manager *m) {
1701 struct epoll_event ev;
1704 if (!m->proc_self_mountinfo) {
1705 if (!(m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re")))
1708 m->mount_watch.type = WATCH_MOUNT;
1709 m->mount_watch.fd = fileno(m->proc_self_mountinfo);
1712 ev.events = EPOLLPRI;
1713 ev.data.ptr = &m->mount_watch;
1715 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->mount_watch.fd, &ev) < 0)
1719 if ((r = mount_load_proc_self_mountinfo(m, false)) < 0)
1729 void mount_fd_event(Manager *m, int events) {
1734 assert(events & EPOLLPRI);
1736 /* The manager calls this for every fd event happening on the
1737 * /proc/self/mountinfo file, which informs us about mounting
1740 r = mount_load_proc_self_mountinfo(m, true);
1742 log_error("Failed to reread /proc/self/mountinfo: %s", strerror(-r));
1744 /* Reset flags, just in case, for later calls */
1745 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1746 Mount *mount = MOUNT(u);
1748 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1754 manager_dispatch_load_queue(m);
1756 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1757 Mount *mount = MOUNT(u);
1759 if (!mount->is_mounted) {
1760 /* This has just been unmounted. */
1762 mount->from_proc_self_mountinfo = false;
1764 switch (mount->state) {
1767 mount_enter_dead(mount, MOUNT_SUCCESS);
1771 mount_set_state(mount, mount->state);
1776 } else if (mount->just_mounted || mount->just_changed) {
1778 /* New or changed mount entry */
1780 switch (mount->state) {
1784 mount_enter_mounted(mount, MOUNT_SUCCESS);
1787 case MOUNT_MOUNTING:
1788 mount_enter_mounting_done(mount);
1792 /* Nothing really changed, but let's
1793 * issue an notification call
1794 * nonetheless, in case somebody is
1795 * waiting for this. (e.g. file system
1796 * ro/rw remounts.) */
1797 mount_set_state(mount, mount->state);
1802 /* Reset the flags for later calls */
1803 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1807 static void mount_reset_failed(Unit *u) {
1808 Mount *m = MOUNT(u);
1812 if (m->state == MOUNT_FAILED)
1813 mount_set_state(m, MOUNT_DEAD);
1815 m->result = MOUNT_SUCCESS;
1816 m->reload_result = MOUNT_SUCCESS;
1819 static int mount_kill(Unit *u, KillWho who, int signo, DBusError *error) {
1820 return unit_kill_common(u, who, signo, -1, MOUNT(u)->control_pid, error);
1823 static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
1824 [MOUNT_DEAD] = "dead",
1825 [MOUNT_MOUNTING] = "mounting",
1826 [MOUNT_MOUNTING_DONE] = "mounting-done",
1827 [MOUNT_MOUNTED] = "mounted",
1828 [MOUNT_REMOUNTING] = "remounting",
1829 [MOUNT_UNMOUNTING] = "unmounting",
1830 [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm",
1831 [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill",
1832 [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
1833 [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
1834 [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
1835 [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
1836 [MOUNT_FAILED] = "failed"
1839 DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
1841 static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
1842 [MOUNT_EXEC_MOUNT] = "ExecMount",
1843 [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
1844 [MOUNT_EXEC_REMOUNT] = "ExecRemount",
1847 DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
1849 static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
1850 [MOUNT_SUCCESS] = "success",
1851 [MOUNT_FAILURE_RESOURCES] = "resources",
1852 [MOUNT_FAILURE_TIMEOUT] = "timeout",
1853 [MOUNT_FAILURE_EXIT_CODE] = "exit-code",
1854 [MOUNT_FAILURE_SIGNAL] = "signal",
1855 [MOUNT_FAILURE_CORE_DUMP] = "core-dump"
1858 DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
1860 const UnitVTable mount_vtable = {
1861 .object_size = sizeof(Mount),
1868 .exec_context_offset = offsetof(Mount, exec_context),
1869 .exec_section = "Mount",
1872 .no_instances = true,
1878 .coldplug = mount_coldplug,
1882 .start = mount_start,
1884 .reload = mount_reload,
1888 .serialize = mount_serialize,
1889 .deserialize_item = mount_deserialize_item,
1891 .active_state = mount_active_state,
1892 .sub_state_to_string = mount_sub_state_to_string,
1894 .check_gc = mount_check_gc,
1896 .sigchld_event = mount_sigchld_event,
1897 .timer_event = mount_timer_event,
1899 .reset_failed = mount_reset_failed,
1901 .bus_interface = "org.freedesktop.systemd1.Mount",
1902 .bus_message_handler = bus_mount_message_handler,
1903 .bus_invalidating_properties = bus_mount_invalidating_properties,
1905 .enumerate = mount_enumerate,
1906 .shutdown = mount_shutdown,
1908 .status_message_formats = {
1909 .starting_stopping = {
1910 [0] = "Mounting %s...",
1911 [1] = "Unmounting %s...",
1913 .finished_start_job = {
1914 [JOB_DONE] = "Mounted %s.",
1915 [JOB_FAILED] = "Failed to mount %s.",
1916 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1917 [JOB_TIMEOUT] = "Timed out mounting %s.",
1919 .finished_stop_job = {
1920 [JOB_DONE] = "Unmounted %s.",
1921 [JOB_FAILED] = "Failed unmounting %s.",
1922 [JOB_TIMEOUT] = "Timed out unmounting %s.",