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 _pure_ static MountParameters* get_mount_parameters_fragment(Mount *m) {
142 if (m->from_fragment)
143 return &m->parameters_fragment;
148 _pure_ 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) {
296 struct mntent me = { .mnt_opts = (char*) haystack };
300 /* Like glibc's hasmntopt(), but works on a string, not a
306 return hasmntopt(&me, needle);
309 static bool mount_is_network(MountParameters *p) {
312 if (mount_test_option(p->options, "_netdev"))
315 if (p->fstype && fstype_is_network(p->fstype))
321 static bool mount_is_bind(MountParameters *p) {
324 if (mount_test_option(p->options, "bind"))
327 if (p->fstype && streq(p->fstype, "bind"))
330 if (mount_test_option(p->options, "rbind"))
333 if (p->fstype && streq(p->fstype, "rbind"))
339 static bool needs_quota(MountParameters *p) {
342 if (mount_is_network(p))
345 if (mount_is_bind(p))
348 return mount_test_option(p->options, "usrquota") ||
349 mount_test_option(p->options, "grpquota") ||
350 mount_test_option(p->options, "quota") ||
351 mount_test_option(p->options, "usrjquota") ||
352 mount_test_option(p->options, "grpjquota");
355 static int mount_add_device_links(Mount *m) {
361 p = get_mount_parameters_fragment(m);
368 if (mount_is_bind(p))
371 if (!is_device_path(p->what))
374 if (path_equal(m->where, "/"))
377 r = unit_add_node_link(UNIT(m), p->what, false);
382 UNIT(m)->manager->running_as == SYSTEMD_SYSTEM) {
385 /* Let's add in the fsck service */
387 /* aka SPECIAL_FSCK_SERVICE */
388 name = unit_name_from_path_instance("systemd-fsck", p->what, ".service");
392 r = manager_load_unit_prepare(UNIT(m)->manager, name, NULL, NULL, &fsck);
394 log_warning_unit(name,
395 "Failed to prepare unit %s: %s", name, strerror(-r));
401 SERVICE(fsck)->fsck_passno = p->passno;
403 r = unit_add_two_dependencies(UNIT(m), UNIT_AFTER, UNIT_REQUIRES, fsck, true);
411 static int mount_add_quota_links(Mount *m) {
417 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
420 p = get_mount_parameters_fragment(m);
427 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true);
431 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true);
438 static int mount_add_default_dependencies(Mount *m) {
439 const char *after, *after2, *online;
445 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
448 p = get_mount_parameters(m);
453 if (path_equal(m->where, "/"))
456 if (mount_is_network(p)) {
457 after = SPECIAL_REMOTE_FS_PRE_TARGET;
458 after2 = SPECIAL_NETWORK_TARGET;
459 online = SPECIAL_NETWORK_ONLINE_TARGET;
461 after = SPECIAL_LOCAL_FS_PRE_TARGET;
466 r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true);
471 r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after2, NULL, true);
477 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, online, NULL, true);
482 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
489 static int mount_fix_timeouts(Mount *m) {
491 const char *timeout = NULL;
500 p = get_mount_parameters_fragment(m);
504 /* Allow configuration how long we wait for a device that
505 * backs a mount point to show up. This is useful to support
506 * endless device timeouts for devices that show up only after
507 * user input, like crypto devices. */
509 if ((timeout = mount_test_option(p->options, "comment=systemd.device-timeout")))
511 else if ((timeout = mount_test_option(p->options, "x-systemd.device-timeout")))
516 t = strndup(timeout, strcspn(timeout, ",;" WHITESPACE));
520 r = parse_sec(t, &u);
524 log_warning_unit(UNIT(m)->id,
525 "Failed to parse timeout for %s, ignoring: %s",
530 SET_FOREACH(other, UNIT(m)->dependencies[UNIT_AFTER], i) {
531 if (other->type != UNIT_DEVICE)
534 other->job_timeout = u;
540 static int mount_verify(Mount *m) {
545 if (UNIT(m)->load_state != UNIT_LOADED)
548 if (!m->from_fragment && !m->from_proc_self_mountinfo)
551 if (!(e = unit_name_from_path(m->where, ".mount")))
554 b = unit_has_name(UNIT(m), e);
558 log_error_unit(UNIT(m)->id,
559 "%s's Where setting doesn't match unit name. Refusing.",
564 if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) {
565 log_error_unit(UNIT(m)->id,
566 "Cannot create mount unit for API file system %s. Refusing.",
571 if (UNIT(m)->fragment_path && !m->parameters_fragment.what) {
572 log_error_unit(UNIT(m)->id,
573 "%s's What setting is missing. Refusing.", UNIT(m)->id);
577 if (m->exec_context.pam_name && m->kill_context.kill_mode != KILL_CONTROL_GROUP) {
578 log_error_unit(UNIT(m)->id,
579 "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.",
587 static int mount_add_extras(Mount *m) {
591 if (UNIT(m)->fragment_path)
592 m->from_fragment = true;
595 m->where = unit_name_to_path(u->id);
600 path_kill_slashes(m->where);
602 r = unit_add_exec_dependencies(u, &m->exec_context);
606 if (!UNIT(m)->description) {
607 r = unit_set_description(u, m->where);
612 r = mount_add_device_links(m);
616 r = mount_add_mount_links(m);
620 r = mount_add_socket_links(m);
624 r = mount_add_swap_links(m);
628 r = mount_add_path_links(m);
632 r = mount_add_requires_mounts_links(m);
636 r = mount_add_automount_links(m);
640 r = mount_add_quota_links(m);
644 if (UNIT(m)->default_dependencies) {
645 r = mount_add_default_dependencies(m);
650 r = unit_add_default_slice(u);
654 r = unit_add_default_cgroups(u);
658 r = mount_fix_timeouts(m);
665 static int mount_load(Unit *u) {
670 assert(u->load_state == UNIT_STUB);
672 if (m->from_proc_self_mountinfo)
673 r = unit_load_fragment_and_dropin_optional(u);
675 r = unit_load_fragment_and_dropin(u);
680 /* This is a new unit? Then let's add in some extras */
681 if (u->load_state == UNIT_LOADED) {
682 r = mount_add_extras(m);
686 r = unit_exec_context_defaults(u, &m->exec_context);
691 return mount_verify(m);
694 static int mount_notify_automount(Mount *m, int status) {
701 SET_FOREACH(p, UNIT(m)->dependencies[UNIT_TRIGGERED_BY], i)
702 if (p->type == UNIT_AUTOMOUNT) {
703 r = automount_send_ready(AUTOMOUNT(p), status);
711 static void mount_set_state(Mount *m, MountState state) {
712 MountState old_state;
715 old_state = m->state;
718 if (state != MOUNT_MOUNTING &&
719 state != MOUNT_MOUNTING_DONE &&
720 state != MOUNT_REMOUNTING &&
721 state != MOUNT_UNMOUNTING &&
722 state != MOUNT_MOUNTING_SIGTERM &&
723 state != MOUNT_MOUNTING_SIGKILL &&
724 state != MOUNT_UNMOUNTING_SIGTERM &&
725 state != MOUNT_UNMOUNTING_SIGKILL &&
726 state != MOUNT_REMOUNTING_SIGTERM &&
727 state != MOUNT_REMOUNTING_SIGKILL) {
728 unit_unwatch_timer(UNIT(m), &m->timer_watch);
729 mount_unwatch_control_pid(m);
730 m->control_command = NULL;
731 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
734 if (state == MOUNT_MOUNTED ||
735 state == MOUNT_REMOUNTING)
736 mount_notify_automount(m, 0);
737 else if (state == MOUNT_DEAD ||
738 state == MOUNT_UNMOUNTING ||
739 state == MOUNT_MOUNTING_SIGTERM ||
740 state == MOUNT_MOUNTING_SIGKILL ||
741 state == MOUNT_REMOUNTING_SIGTERM ||
742 state == MOUNT_REMOUNTING_SIGKILL ||
743 state == MOUNT_UNMOUNTING_SIGTERM ||
744 state == MOUNT_UNMOUNTING_SIGKILL ||
745 state == MOUNT_FAILED) {
746 if (state != old_state)
747 mount_notify_automount(m, -ENODEV);
750 if (state != old_state)
751 log_debug_unit(UNIT(m)->id,
752 "%s changed %s -> %s",
754 mount_state_to_string(old_state),
755 mount_state_to_string(state));
757 unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
758 m->reload_result = MOUNT_SUCCESS;
761 static int mount_coldplug(Unit *u) {
763 MountState new_state = MOUNT_DEAD;
767 assert(m->state == MOUNT_DEAD);
769 if (m->deserialized_state != m->state)
770 new_state = m->deserialized_state;
771 else if (m->from_proc_self_mountinfo)
772 new_state = MOUNT_MOUNTED;
774 if (new_state != m->state) {
776 if (new_state == MOUNT_MOUNTING ||
777 new_state == MOUNT_MOUNTING_DONE ||
778 new_state == MOUNT_REMOUNTING ||
779 new_state == MOUNT_UNMOUNTING ||
780 new_state == MOUNT_MOUNTING_SIGTERM ||
781 new_state == MOUNT_MOUNTING_SIGKILL ||
782 new_state == MOUNT_UNMOUNTING_SIGTERM ||
783 new_state == MOUNT_UNMOUNTING_SIGKILL ||
784 new_state == MOUNT_REMOUNTING_SIGTERM ||
785 new_state == MOUNT_REMOUNTING_SIGKILL) {
787 if (m->control_pid <= 0)
790 r = unit_watch_pid(UNIT(m), m->control_pid);
794 r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
799 mount_set_state(m, new_state);
805 static void mount_dump(Unit *u, FILE *f, const char *prefix) {
812 p = get_mount_parameters(m);
815 "%sMount State: %s\n"
819 "%sFile System Type: %s\n"
821 "%sFrom /proc/self/mountinfo: %s\n"
822 "%sFrom fragment: %s\n"
823 "%sDirectoryMode: %04o\n",
824 prefix, mount_state_to_string(m->state),
825 prefix, mount_result_to_string(m->result),
827 prefix, strna(p->what),
828 prefix, strna(p->fstype),
829 prefix, strna(p->options),
830 prefix, yes_no(m->from_proc_self_mountinfo),
831 prefix, yes_no(m->from_fragment),
832 prefix, m->directory_mode);
834 if (m->control_pid > 0)
836 "%sControl PID: %lu\n",
837 prefix, (unsigned long) m->control_pid);
839 exec_context_dump(&m->exec_context, f, prefix);
840 kill_context_dump(&m->kill_context, f, prefix);
843 static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
851 r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
855 if ((r = exec_spawn(c,
859 UNIT(m)->manager->environment,
863 UNIT(m)->manager->confirm_spawn,
864 UNIT(m)->cgroup_bondings,
865 UNIT(m)->cgroup_attributes,
872 if ((r = unit_watch_pid(UNIT(m), pid)) < 0)
873 /* FIXME: we need to do something here */
881 unit_unwatch_timer(UNIT(m), &m->timer_watch);
886 static void mount_enter_dead(Mount *m, MountResult f) {
889 if (f != MOUNT_SUCCESS)
892 exec_context_tmp_dirs_done(&m->exec_context);
893 mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
896 static void mount_enter_mounted(Mount *m, MountResult f) {
899 if (f != MOUNT_SUCCESS)
902 mount_set_state(m, MOUNT_MOUNTED);
905 static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
910 if (f != MOUNT_SUCCESS)
913 r = unit_kill_context(
916 state != MOUNT_MOUNTING_SIGTERM && state != MOUNT_UNMOUNTING_SIGTERM && state != MOUNT_REMOUNTING_SIGTERM,
924 r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
928 mount_set_state(m, state);
929 } else if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
930 mount_enter_mounted(m, MOUNT_SUCCESS);
932 mount_enter_dead(m, MOUNT_SUCCESS);
937 log_warning_unit(UNIT(m)->id,
938 "%s failed to kill processes: %s", UNIT(m)->id, strerror(-r));
940 if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
941 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
943 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
946 void warn_if_dir_nonempty(const char *unit, const char* where) {
950 if (dir_is_empty(where) > 0)
953 log_struct_unit(LOG_NOTICE,
955 "MESSAGE=%s: Directory %s to mount over is not empty, mounting anyway.",
958 MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
962 static void mount_enter_unmounting(Mount *m) {
967 m->control_command_id = MOUNT_EXEC_UNMOUNT;
968 m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
970 if ((r = exec_command_set(
977 mount_unwatch_control_pid(m);
979 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
982 mount_set_state(m, MOUNT_UNMOUNTING);
987 log_warning_unit(UNIT(m)->id,
988 "%s failed to run 'umount' task: %s",
989 UNIT(m)->id, strerror(-r));
990 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
993 static void mount_enter_mounting(Mount *m) {
999 m->control_command_id = MOUNT_EXEC_MOUNT;
1000 m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
1002 mkdir_p_label(m->where, m->directory_mode);
1004 warn_if_dir_nonempty(m->meta.id, m->where);
1006 /* Create the source directory for bind-mounts if needed */
1007 p = get_mount_parameters_fragment(m);
1008 if (p && mount_is_bind(p))
1009 mkdir_p_label(p->what, m->directory_mode);
1011 if (m->from_fragment)
1012 r = exec_command_set(
1015 m->parameters_fragment.what,
1017 "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
1018 m->parameters_fragment.options ? "-o" : NULL, m->parameters_fragment.options,
1026 mount_unwatch_control_pid(m);
1028 r = mount_spawn(m, m->control_command, &m->control_pid);
1032 mount_set_state(m, MOUNT_MOUNTING);
1037 log_warning_unit(UNIT(m)->id,
1038 "%s failed to run 'mount' task: %s",
1039 UNIT(m)->id, strerror(-r));
1040 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
1043 static void mount_enter_mounting_done(Mount *m) {
1046 mount_set_state(m, MOUNT_MOUNTING_DONE);
1049 static void mount_enter_remounting(Mount *m) {
1054 m->control_command_id = MOUNT_EXEC_REMOUNT;
1055 m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
1057 if (m->from_fragment) {
1061 if (m->parameters_fragment.options) {
1062 if (!(buf = strappend("remount,", m->parameters_fragment.options))) {
1071 r = exec_command_set(
1074 m->parameters_fragment.what,
1076 "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
1087 mount_unwatch_control_pid(m);
1089 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
1092 mount_set_state(m, MOUNT_REMOUNTING);
1097 log_warning_unit(UNIT(m)->id,
1098 "%s failed to run 'remount' task: %s",
1099 UNIT(m)->id, strerror(-r));
1100 m->reload_result = MOUNT_FAILURE_RESOURCES;
1101 mount_enter_mounted(m, MOUNT_SUCCESS);
1104 static int mount_start(Unit *u) {
1105 Mount *m = MOUNT(u);
1109 /* We cannot fulfill this request right now, try again later
1111 if (m->state == MOUNT_UNMOUNTING ||
1112 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1113 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1114 m->state == MOUNT_MOUNTING_SIGTERM ||
1115 m->state == MOUNT_MOUNTING_SIGKILL)
1118 /* Already on it! */
1119 if (m->state == MOUNT_MOUNTING)
1122 assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED);
1124 m->result = MOUNT_SUCCESS;
1125 m->reload_result = MOUNT_SUCCESS;
1127 mount_enter_mounting(m);
1131 static int mount_stop(Unit *u) {
1132 Mount *m = MOUNT(u);
1137 if (m->state == MOUNT_UNMOUNTING ||
1138 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1139 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1140 m->state == MOUNT_MOUNTING_SIGTERM ||
1141 m->state == MOUNT_MOUNTING_SIGKILL)
1144 assert(m->state == MOUNT_MOUNTING ||
1145 m->state == MOUNT_MOUNTING_DONE ||
1146 m->state == MOUNT_MOUNTED ||
1147 m->state == MOUNT_REMOUNTING ||
1148 m->state == MOUNT_REMOUNTING_SIGTERM ||
1149 m->state == MOUNT_REMOUNTING_SIGKILL);
1151 mount_enter_unmounting(m);
1155 static int mount_reload(Unit *u) {
1156 Mount *m = MOUNT(u);
1160 if (m->state == MOUNT_MOUNTING_DONE)
1163 assert(m->state == MOUNT_MOUNTED);
1165 mount_enter_remounting(m);
1169 static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
1170 Mount *m = MOUNT(u);
1176 unit_serialize_item(u, f, "state", mount_state_to_string(m->state));
1177 unit_serialize_item(u, f, "result", mount_result_to_string(m->result));
1178 unit_serialize_item(u, f, "reload-result", mount_result_to_string(m->reload_result));
1180 if (m->control_pid > 0)
1181 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) m->control_pid);
1183 if (m->control_command_id >= 0)
1184 unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id));
1186 exec_context_serialize(&m->exec_context, UNIT(m), f);
1191 static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1192 Mount *m = MOUNT(u);
1199 if (streq(key, "state")) {
1202 if ((state = mount_state_from_string(value)) < 0)
1203 log_debug_unit(u->id, "Failed to parse state value %s", value);
1205 m->deserialized_state = state;
1206 } else if (streq(key, "result")) {
1209 f = mount_result_from_string(value);
1211 log_debug_unit(UNIT(m)->id,
1212 "Failed to parse result value %s", value);
1213 else if (f != MOUNT_SUCCESS)
1216 } else if (streq(key, "reload-result")) {
1219 f = mount_result_from_string(value);
1221 log_debug_unit(UNIT(m)->id,
1222 "Failed to parse reload result value %s", value);
1223 else if (f != MOUNT_SUCCESS)
1224 m->reload_result = f;
1226 } else if (streq(key, "control-pid")) {
1229 if (parse_pid(value, &pid) < 0)
1230 log_debug_unit(UNIT(m)->id,
1231 "Failed to parse control-pid value %s", value);
1233 m->control_pid = pid;
1234 } else if (streq(key, "control-command")) {
1235 MountExecCommand id;
1237 if ((id = mount_exec_command_from_string(value)) < 0)
1238 log_debug_unit(UNIT(m)->id,
1239 "Failed to parse exec-command value %s", value);
1241 m->control_command_id = id;
1242 m->control_command = m->exec_command + id;
1244 } else if (streq(key, "tmp-dir")) {
1251 m->exec_context.tmp_dir = t;
1252 } else if (streq(key, "var-tmp-dir")) {
1259 m->exec_context.var_tmp_dir = t;
1261 log_debug_unit(UNIT(m)->id,
1262 "Unknown serialization key '%s'", key);
1267 _pure_ static UnitActiveState mount_active_state(Unit *u) {
1270 return state_translation_table[MOUNT(u)->state];
1273 _pure_ static const char *mount_sub_state_to_string(Unit *u) {
1276 return mount_state_to_string(MOUNT(u)->state);
1279 _pure_ static bool mount_check_gc(Unit *u) {
1280 Mount *m = MOUNT(u);
1284 return m->from_proc_self_mountinfo;
1287 static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1288 Mount *m = MOUNT(u);
1294 if (pid != m->control_pid)
1299 if (is_clean_exit(code, status, NULL))
1301 else if (code == CLD_EXITED)
1302 f = MOUNT_FAILURE_EXIT_CODE;
1303 else if (code == CLD_KILLED)
1304 f = MOUNT_FAILURE_SIGNAL;
1305 else if (code == CLD_DUMPED)
1306 f = MOUNT_FAILURE_CORE_DUMP;
1308 assert_not_reached("Unknown code");
1310 if (f != MOUNT_SUCCESS)
1313 if (m->control_command) {
1314 exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
1316 m->control_command = NULL;
1317 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
1320 log_full_unit(f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE, u->id,
1321 "%s mount process exited, code=%s status=%i",
1322 u->id, sigchld_code_to_string(code), status);
1324 /* Note that mount(8) returning and the kernel sending us a
1325 * mount table change event might happen out-of-order. If an
1326 * operation succeed we assume the kernel will follow soon too
1327 * and already change into the resulting state. If it fails
1328 * we check if the kernel still knows about the mount. and
1329 * change state accordingly. */
1333 case MOUNT_MOUNTING:
1334 case MOUNT_MOUNTING_DONE:
1335 case MOUNT_MOUNTING_SIGKILL:
1336 case MOUNT_MOUNTING_SIGTERM:
1338 if (f == MOUNT_SUCCESS)
1339 mount_enter_mounted(m, f);
1340 else if (m->from_proc_self_mountinfo)
1341 mount_enter_mounted(m, f);
1343 mount_enter_dead(m, f);
1346 case MOUNT_REMOUNTING:
1347 case MOUNT_REMOUNTING_SIGKILL:
1348 case MOUNT_REMOUNTING_SIGTERM:
1350 m->reload_result = f;
1351 if (m->from_proc_self_mountinfo)
1352 mount_enter_mounted(m, MOUNT_SUCCESS);
1354 mount_enter_dead(m, MOUNT_SUCCESS);
1358 case MOUNT_UNMOUNTING:
1359 case MOUNT_UNMOUNTING_SIGKILL:
1360 case MOUNT_UNMOUNTING_SIGTERM:
1362 if (f == MOUNT_SUCCESS)
1363 mount_enter_dead(m, f);
1364 else if (m->from_proc_self_mountinfo)
1365 mount_enter_mounted(m, f);
1367 mount_enter_dead(m, f);
1371 assert_not_reached("Uh, control process died at wrong time.");
1374 /* Notify clients about changed exit status */
1375 unit_add_to_dbus_queue(u);
1378 static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
1379 Mount *m = MOUNT(u);
1382 assert(elapsed == 1);
1383 assert(w == &m->timer_watch);
1387 case MOUNT_MOUNTING:
1388 case MOUNT_MOUNTING_DONE:
1389 log_warning_unit(u->id,
1390 "%s mounting timed out. Stopping.", u->id);
1391 mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1394 case MOUNT_REMOUNTING:
1395 log_warning_unit(u->id,
1396 "%s remounting timed out. Stopping.", u->id);
1397 m->reload_result = MOUNT_FAILURE_TIMEOUT;
1398 mount_enter_mounted(m, MOUNT_SUCCESS);
1401 case MOUNT_UNMOUNTING:
1402 log_warning_unit(u->id,
1403 "%s unmounting timed out. Stopping.", u->id);
1404 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1407 case MOUNT_MOUNTING_SIGTERM:
1408 if (m->kill_context.send_sigkill) {
1409 log_warning_unit(u->id,
1410 "%s mounting timed out. Killing.", u->id);
1411 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1413 log_warning_unit(u->id,
1414 "%s mounting timed out. Skipping SIGKILL. Ignoring.",
1417 if (m->from_proc_self_mountinfo)
1418 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1420 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1424 case MOUNT_REMOUNTING_SIGTERM:
1425 if (m->kill_context.send_sigkill) {
1426 log_warning_unit(u->id,
1427 "%s remounting timed out. Killing.", u->id);
1428 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1430 log_warning_unit(u->id,
1431 "%s remounting timed out. Skipping SIGKILL. Ignoring.",
1434 if (m->from_proc_self_mountinfo)
1435 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1437 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1441 case MOUNT_UNMOUNTING_SIGTERM:
1442 if (m->kill_context.send_sigkill) {
1443 log_warning_unit(u->id,
1444 "%s unmounting timed out. Killing.", u->id);
1445 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1447 log_warning_unit(u->id,
1448 "%s unmounting timed out. Skipping SIGKILL. Ignoring.",
1451 if (m->from_proc_self_mountinfo)
1452 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1454 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1458 case MOUNT_MOUNTING_SIGKILL:
1459 case MOUNT_REMOUNTING_SIGKILL:
1460 case MOUNT_UNMOUNTING_SIGKILL:
1461 log_warning_unit(u->id,
1462 "%s mount process still around after SIGKILL. Ignoring.",
1465 if (m->from_proc_self_mountinfo)
1466 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1468 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1472 assert_not_reached("Timeout at wrong time.");
1476 static int mount_add_one(
1480 const char *options,
1487 char *e, *w = NULL, *o = NULL, *f = NULL;
1489 bool load_extras = false;
1497 /* Ignore API mount points. They should never be referenced in
1498 * dependencies ever. */
1499 if (mount_point_is_api(where) || mount_point_ignore(where))
1502 if (streq(fstype, "autofs"))
1505 /* probably some kind of swap, ignore */
1506 if (!is_path(where))
1509 e = unit_name_from_path(where, ".mount");
1513 u = manager_get_unit(m, e);
1517 u = unit_new(m, sizeof(Mount));
1523 r = unit_add_name(u, e);
1529 MOUNT(u)->where = strdup(where);
1530 if (!MOUNT(u)->where) {
1535 u->source_path = strdup("/proc/self/mountinfo");
1536 if (!u->source_path) {
1541 r = unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_LOCAL_FS_TARGET, NULL, true);
1545 if (!path_equal(where, "/")) {
1546 r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
1551 unit_add_to_load_queue(u);
1556 if (!MOUNT(u)->where) {
1557 MOUNT(u)->where = strdup(where);
1558 if (!MOUNT(u)->where) {
1564 if (u->load_state == UNIT_ERROR) {
1565 u->load_state = UNIT_LOADED;
1568 /* Load in the extras later on, after we
1569 * finished initialization of the unit */
1574 if (!(w = strdup(what)) ||
1575 !(o = strdup(options)) ||
1576 !(f = strdup(fstype))) {
1581 p = &MOUNT(u)->parameters_proc_self_mountinfo;
1583 MOUNT(u)->is_mounted = true;
1584 MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
1585 MOUNT(u)->just_changed = !streq_ptr(p->options, o);
1588 MOUNT(u)->from_proc_self_mountinfo = true;
1602 r = mount_add_extras(MOUNT(u));
1607 unit_add_to_dbus_queue(u);
1622 static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
1625 char *device, *path, *options, *options2, *fstype, *d, *p, *o;
1629 rewind(m->proc_self_mountinfo);
1634 device = path = options = options2 = fstype = d = p = o = NULL;
1636 if ((k = fscanf(m->proc_self_mountinfo,
1637 "%*s " /* (1) mount id */
1638 "%*s " /* (2) parent id */
1639 "%*s " /* (3) major:minor */
1640 "%*s " /* (4) root */
1641 "%ms " /* (5) mount point */
1642 "%ms" /* (6) mount options */
1643 "%*[^-]" /* (7) optional fields */
1644 "- " /* (8) separator */
1645 "%ms " /* (9) file system type */
1646 "%ms" /* (10) mount source */
1647 "%ms" /* (11) mount options 2 */
1648 "%*[^\n]", /* some rubbish at the end */
1658 log_warning("Failed to parse /proc/self/mountinfo:%u.", i);
1662 o = strjoin(options, ",", options2, NULL);
1668 if (!(d = cunescape(device)) ||
1669 !(p = cunescape(path))) {
1674 if ((k = mount_add_one(m, d, p, o, fstype, 0, set_flags)) < 0)
1701 static void mount_shutdown(Manager *m) {
1704 if (m->proc_self_mountinfo) {
1705 fclose(m->proc_self_mountinfo);
1706 m->proc_self_mountinfo = NULL;
1710 static int mount_enumerate(Manager *m) {
1714 if (!m->proc_self_mountinfo) {
1715 struct epoll_event ev = {
1717 .data.ptr = &m->mount_watch,
1720 m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
1721 if (!m->proc_self_mountinfo)
1724 m->mount_watch.type = WATCH_MOUNT;
1725 m->mount_watch.fd = fileno(m->proc_self_mountinfo);
1727 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->mount_watch.fd, &ev) < 0)
1731 r = mount_load_proc_self_mountinfo(m, false);
1742 void mount_fd_event(Manager *m, int events) {
1747 assert(events & EPOLLPRI);
1749 /* The manager calls this for every fd event happening on the
1750 * /proc/self/mountinfo file, which informs us about mounting
1753 r = mount_load_proc_self_mountinfo(m, true);
1755 log_error("Failed to reread /proc/self/mountinfo: %s", strerror(-r));
1757 /* Reset flags, just in case, for later calls */
1758 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1759 Mount *mount = MOUNT(u);
1761 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1767 manager_dispatch_load_queue(m);
1769 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1770 Mount *mount = MOUNT(u);
1772 if (!mount->is_mounted) {
1773 /* This has just been unmounted. */
1775 mount->from_proc_self_mountinfo = false;
1777 switch (mount->state) {
1780 mount_enter_dead(mount, MOUNT_SUCCESS);
1784 mount_set_state(mount, mount->state);
1789 } else if (mount->just_mounted || mount->just_changed) {
1791 /* New or changed mount entry */
1793 switch (mount->state) {
1797 mount_enter_mounted(mount, MOUNT_SUCCESS);
1800 case MOUNT_MOUNTING:
1801 mount_enter_mounting_done(mount);
1805 /* Nothing really changed, but let's
1806 * issue an notification call
1807 * nonetheless, in case somebody is
1808 * waiting for this. (e.g. file system
1809 * ro/rw remounts.) */
1810 mount_set_state(mount, mount->state);
1815 /* Reset the flags for later calls */
1816 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1820 static void mount_reset_failed(Unit *u) {
1821 Mount *m = MOUNT(u);
1825 if (m->state == MOUNT_FAILED)
1826 mount_set_state(m, MOUNT_DEAD);
1828 m->result = MOUNT_SUCCESS;
1829 m->reload_result = MOUNT_SUCCESS;
1832 static int mount_kill(Unit *u, KillWho who, int signo, DBusError *error) {
1833 return unit_kill_common(u, who, signo, -1, MOUNT(u)->control_pid, error);
1836 static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
1837 [MOUNT_DEAD] = "dead",
1838 [MOUNT_MOUNTING] = "mounting",
1839 [MOUNT_MOUNTING_DONE] = "mounting-done",
1840 [MOUNT_MOUNTED] = "mounted",
1841 [MOUNT_REMOUNTING] = "remounting",
1842 [MOUNT_UNMOUNTING] = "unmounting",
1843 [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm",
1844 [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill",
1845 [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
1846 [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
1847 [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
1848 [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
1849 [MOUNT_FAILED] = "failed"
1852 DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
1854 static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
1855 [MOUNT_EXEC_MOUNT] = "ExecMount",
1856 [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
1857 [MOUNT_EXEC_REMOUNT] = "ExecRemount",
1860 DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
1862 static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
1863 [MOUNT_SUCCESS] = "success",
1864 [MOUNT_FAILURE_RESOURCES] = "resources",
1865 [MOUNT_FAILURE_TIMEOUT] = "timeout",
1866 [MOUNT_FAILURE_EXIT_CODE] = "exit-code",
1867 [MOUNT_FAILURE_SIGNAL] = "signal",
1868 [MOUNT_FAILURE_CORE_DUMP] = "core-dump"
1871 DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
1873 const UnitVTable mount_vtable = {
1874 .object_size = sizeof(Mount),
1881 .exec_context_offset = offsetof(Mount, exec_context),
1882 .exec_section = "Mount",
1885 .no_instances = true,
1891 .coldplug = mount_coldplug,
1895 .start = mount_start,
1897 .reload = mount_reload,
1901 .serialize = mount_serialize,
1902 .deserialize_item = mount_deserialize_item,
1904 .active_state = mount_active_state,
1905 .sub_state_to_string = mount_sub_state_to_string,
1907 .check_gc = mount_check_gc,
1909 .sigchld_event = mount_sigchld_event,
1910 .timer_event = mount_timer_event,
1912 .reset_failed = mount_reset_failed,
1914 .bus_interface = "org.freedesktop.systemd1.Mount",
1915 .bus_message_handler = bus_mount_message_handler,
1916 .bus_invalidating_properties = bus_mount_invalidating_properties,
1918 .enumerate = mount_enumerate,
1919 .shutdown = mount_shutdown,
1921 .status_message_formats = {
1922 .starting_stopping = {
1923 [0] = "Mounting %s...",
1924 [1] = "Unmounting %s...",
1926 .finished_start_job = {
1927 [JOB_DONE] = "Mounted %s.",
1928 [JOB_FAILED] = "Failed to mount %s.",
1929 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1930 [JOB_TIMEOUT] = "Timed out mounting %s.",
1932 .finished_stop_job = {
1933 [JOB_DONE] = "Unmounted %s.",
1934 [JOB_FAILED] = "Failed unmounting %s.",
1935 [JOB_TIMEOUT] = "Timed out unmounting %s.",