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) {
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_cgroups(u);
654 r = mount_fix_timeouts(m);
661 static int mount_load(Unit *u) {
666 assert(u->load_state == UNIT_STUB);
668 if (m->from_proc_self_mountinfo)
669 r = unit_load_fragment_and_dropin_optional(u);
671 r = unit_load_fragment_and_dropin(u);
676 /* This is a new unit? Then let's add in some extras */
677 if (u->load_state == UNIT_LOADED) {
678 r = mount_add_extras(m);
682 r = unit_exec_context_defaults(u, &m->exec_context);
687 return mount_verify(m);
690 static int mount_notify_automount(Mount *m, int status) {
697 SET_FOREACH(p, UNIT(m)->dependencies[UNIT_TRIGGERED_BY], i)
698 if (p->type == UNIT_AUTOMOUNT) {
699 r = automount_send_ready(AUTOMOUNT(p), status);
707 static void mount_set_state(Mount *m, MountState state) {
708 MountState old_state;
711 old_state = m->state;
714 if (state != MOUNT_MOUNTING &&
715 state != MOUNT_MOUNTING_DONE &&
716 state != MOUNT_REMOUNTING &&
717 state != MOUNT_UNMOUNTING &&
718 state != MOUNT_MOUNTING_SIGTERM &&
719 state != MOUNT_MOUNTING_SIGKILL &&
720 state != MOUNT_UNMOUNTING_SIGTERM &&
721 state != MOUNT_UNMOUNTING_SIGKILL &&
722 state != MOUNT_REMOUNTING_SIGTERM &&
723 state != MOUNT_REMOUNTING_SIGKILL) {
724 unit_unwatch_timer(UNIT(m), &m->timer_watch);
725 mount_unwatch_control_pid(m);
726 m->control_command = NULL;
727 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
730 if (state == MOUNT_MOUNTED ||
731 state == MOUNT_REMOUNTING)
732 mount_notify_automount(m, 0);
733 else if (state == MOUNT_DEAD ||
734 state == MOUNT_UNMOUNTING ||
735 state == MOUNT_MOUNTING_SIGTERM ||
736 state == MOUNT_MOUNTING_SIGKILL ||
737 state == MOUNT_REMOUNTING_SIGTERM ||
738 state == MOUNT_REMOUNTING_SIGKILL ||
739 state == MOUNT_UNMOUNTING_SIGTERM ||
740 state == MOUNT_UNMOUNTING_SIGKILL ||
741 state == MOUNT_FAILED) {
742 if (state != old_state)
743 mount_notify_automount(m, -ENODEV);
746 if (state != old_state)
747 log_debug_unit(UNIT(m)->id,
748 "%s changed %s -> %s",
750 mount_state_to_string(old_state),
751 mount_state_to_string(state));
753 unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
754 m->reload_result = MOUNT_SUCCESS;
757 static int mount_coldplug(Unit *u) {
759 MountState new_state = MOUNT_DEAD;
763 assert(m->state == MOUNT_DEAD);
765 if (m->deserialized_state != m->state)
766 new_state = m->deserialized_state;
767 else if (m->from_proc_self_mountinfo)
768 new_state = MOUNT_MOUNTED;
770 if (new_state != m->state) {
772 if (new_state == MOUNT_MOUNTING ||
773 new_state == MOUNT_MOUNTING_DONE ||
774 new_state == MOUNT_REMOUNTING ||
775 new_state == MOUNT_UNMOUNTING ||
776 new_state == MOUNT_MOUNTING_SIGTERM ||
777 new_state == MOUNT_MOUNTING_SIGKILL ||
778 new_state == MOUNT_UNMOUNTING_SIGTERM ||
779 new_state == MOUNT_UNMOUNTING_SIGKILL ||
780 new_state == MOUNT_REMOUNTING_SIGTERM ||
781 new_state == MOUNT_REMOUNTING_SIGKILL) {
783 if (m->control_pid <= 0)
786 r = unit_watch_pid(UNIT(m), m->control_pid);
790 r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
795 mount_set_state(m, new_state);
801 static void mount_dump(Unit *u, FILE *f, const char *prefix) {
808 p = get_mount_parameters(m);
811 "%sMount State: %s\n"
815 "%sFile System Type: %s\n"
817 "%sFrom /proc/self/mountinfo: %s\n"
818 "%sFrom fragment: %s\n"
819 "%sDirectoryMode: %04o\n",
820 prefix, mount_state_to_string(m->state),
821 prefix, mount_result_to_string(m->result),
823 prefix, strna(p->what),
824 prefix, strna(p->fstype),
825 prefix, strna(p->options),
826 prefix, yes_no(m->from_proc_self_mountinfo),
827 prefix, yes_no(m->from_fragment),
828 prefix, m->directory_mode);
830 if (m->control_pid > 0)
832 "%sControl PID: %lu\n",
833 prefix, (unsigned long) m->control_pid);
835 exec_context_dump(&m->exec_context, f, prefix);
836 kill_context_dump(&m->kill_context, f, prefix);
839 static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
847 r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
851 if ((r = exec_spawn(c,
855 UNIT(m)->manager->environment,
859 UNIT(m)->manager->confirm_spawn,
860 UNIT(m)->cgroup_bondings,
861 UNIT(m)->cgroup_attributes,
868 if ((r = unit_watch_pid(UNIT(m), pid)) < 0)
869 /* FIXME: we need to do something here */
877 unit_unwatch_timer(UNIT(m), &m->timer_watch);
882 static void mount_enter_dead(Mount *m, MountResult f) {
885 if (f != MOUNT_SUCCESS)
888 exec_context_tmp_dirs_done(&m->exec_context);
889 mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
892 static void mount_enter_mounted(Mount *m, MountResult f) {
895 if (f != MOUNT_SUCCESS)
898 mount_set_state(m, MOUNT_MOUNTED);
901 static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
906 if (f != MOUNT_SUCCESS)
909 r = unit_kill_context(
912 state != MOUNT_MOUNTING_SIGTERM && state != MOUNT_UNMOUNTING_SIGTERM && state != MOUNT_REMOUNTING_SIGTERM,
920 r = unit_watch_timer(UNIT(m), CLOCK_MONOTONIC, true, m->timeout_usec, &m->timer_watch);
924 mount_set_state(m, state);
925 } else if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
926 mount_enter_mounted(m, MOUNT_SUCCESS);
928 mount_enter_dead(m, MOUNT_SUCCESS);
933 log_warning_unit(UNIT(m)->id,
934 "%s failed to kill processes: %s", UNIT(m)->id, strerror(-r));
936 if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
937 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
939 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
942 void warn_if_dir_nonempty(const char *unit, const char* where) {
946 if (dir_is_empty(where) > 0)
949 log_struct_unit(LOG_NOTICE,
951 "MESSAGE=%s: Directory %s to mount over is not empty, mounting anyway.",
954 MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
958 static void mount_enter_unmounting(Mount *m) {
963 m->control_command_id = MOUNT_EXEC_UNMOUNT;
964 m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
966 if ((r = exec_command_set(
973 mount_unwatch_control_pid(m);
975 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
978 mount_set_state(m, MOUNT_UNMOUNTING);
983 log_warning_unit(UNIT(m)->id,
984 "%s failed to run 'umount' task: %s",
985 UNIT(m)->id, strerror(-r));
986 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
989 static void mount_enter_mounting(Mount *m) {
995 m->control_command_id = MOUNT_EXEC_MOUNT;
996 m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
998 mkdir_p_label(m->where, m->directory_mode);
1000 warn_if_dir_nonempty(m->meta.id, m->where);
1002 /* Create the source directory for bind-mounts if needed */
1003 p = get_mount_parameters_fragment(m);
1004 if (p && mount_is_bind(p))
1005 mkdir_p_label(p->what, m->directory_mode);
1007 if (m->from_fragment)
1008 r = exec_command_set(
1011 m->parameters_fragment.what,
1013 "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
1014 m->parameters_fragment.options ? "-o" : NULL, m->parameters_fragment.options,
1022 mount_unwatch_control_pid(m);
1024 r = mount_spawn(m, m->control_command, &m->control_pid);
1028 mount_set_state(m, MOUNT_MOUNTING);
1033 log_warning_unit(UNIT(m)->id,
1034 "%s failed to run 'mount' task: %s",
1035 UNIT(m)->id, strerror(-r));
1036 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
1039 static void mount_enter_mounting_done(Mount *m) {
1042 mount_set_state(m, MOUNT_MOUNTING_DONE);
1045 static void mount_enter_remounting(Mount *m) {
1050 m->control_command_id = MOUNT_EXEC_REMOUNT;
1051 m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
1053 if (m->from_fragment) {
1057 if (m->parameters_fragment.options) {
1058 if (!(buf = strappend("remount,", m->parameters_fragment.options))) {
1067 r = exec_command_set(
1070 m->parameters_fragment.what,
1072 "-t", m->parameters_fragment.fstype ? m->parameters_fragment.fstype : "auto",
1083 mount_unwatch_control_pid(m);
1085 if ((r = mount_spawn(m, m->control_command, &m->control_pid)) < 0)
1088 mount_set_state(m, MOUNT_REMOUNTING);
1093 log_warning_unit(UNIT(m)->id,
1094 "%s failed to run 'remount' task: %s",
1095 UNIT(m)->id, strerror(-r));
1096 m->reload_result = MOUNT_FAILURE_RESOURCES;
1097 mount_enter_mounted(m, MOUNT_SUCCESS);
1100 static int mount_start(Unit *u) {
1101 Mount *m = MOUNT(u);
1105 /* We cannot fulfill this request right now, try again later
1107 if (m->state == MOUNT_UNMOUNTING ||
1108 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1109 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1110 m->state == MOUNT_MOUNTING_SIGTERM ||
1111 m->state == MOUNT_MOUNTING_SIGKILL)
1114 /* Already on it! */
1115 if (m->state == MOUNT_MOUNTING)
1118 assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED);
1120 m->result = MOUNT_SUCCESS;
1121 m->reload_result = MOUNT_SUCCESS;
1123 mount_enter_mounting(m);
1127 static int mount_stop(Unit *u) {
1128 Mount *m = MOUNT(u);
1133 if (m->state == MOUNT_UNMOUNTING ||
1134 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1135 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1136 m->state == MOUNT_MOUNTING_SIGTERM ||
1137 m->state == MOUNT_MOUNTING_SIGKILL)
1140 assert(m->state == MOUNT_MOUNTING ||
1141 m->state == MOUNT_MOUNTING_DONE ||
1142 m->state == MOUNT_MOUNTED ||
1143 m->state == MOUNT_REMOUNTING ||
1144 m->state == MOUNT_REMOUNTING_SIGTERM ||
1145 m->state == MOUNT_REMOUNTING_SIGKILL);
1147 mount_enter_unmounting(m);
1151 static int mount_reload(Unit *u) {
1152 Mount *m = MOUNT(u);
1156 if (m->state == MOUNT_MOUNTING_DONE)
1159 assert(m->state == MOUNT_MOUNTED);
1161 mount_enter_remounting(m);
1165 static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
1166 Mount *m = MOUNT(u);
1172 unit_serialize_item(u, f, "state", mount_state_to_string(m->state));
1173 unit_serialize_item(u, f, "result", mount_result_to_string(m->result));
1174 unit_serialize_item(u, f, "reload-result", mount_result_to_string(m->reload_result));
1176 if (m->control_pid > 0)
1177 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) m->control_pid);
1179 if (m->control_command_id >= 0)
1180 unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id));
1182 exec_context_serialize(&m->exec_context, UNIT(m), f);
1187 static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1188 Mount *m = MOUNT(u);
1195 if (streq(key, "state")) {
1198 if ((state = mount_state_from_string(value)) < 0)
1199 log_debug_unit(u->id, "Failed to parse state value %s", value);
1201 m->deserialized_state = state;
1202 } else if (streq(key, "result")) {
1205 f = mount_result_from_string(value);
1207 log_debug_unit(UNIT(m)->id,
1208 "Failed to parse result value %s", value);
1209 else if (f != MOUNT_SUCCESS)
1212 } else if (streq(key, "reload-result")) {
1215 f = mount_result_from_string(value);
1217 log_debug_unit(UNIT(m)->id,
1218 "Failed to parse reload result value %s", value);
1219 else if (f != MOUNT_SUCCESS)
1220 m->reload_result = f;
1222 } else if (streq(key, "control-pid")) {
1225 if (parse_pid(value, &pid) < 0)
1226 log_debug_unit(UNIT(m)->id,
1227 "Failed to parse control-pid value %s", value);
1229 m->control_pid = pid;
1230 } else if (streq(key, "control-command")) {
1231 MountExecCommand id;
1233 if ((id = mount_exec_command_from_string(value)) < 0)
1234 log_debug_unit(UNIT(m)->id,
1235 "Failed to parse exec-command value %s", value);
1237 m->control_command_id = id;
1238 m->control_command = m->exec_command + id;
1240 } else if (streq(key, "tmp-dir")) {
1247 m->exec_context.tmp_dir = t;
1248 } else if (streq(key, "var-tmp-dir")) {
1255 m->exec_context.var_tmp_dir = t;
1257 log_debug_unit(UNIT(m)->id,
1258 "Unknown serialization key '%s'", key);
1263 static UnitActiveState mount_active_state(Unit *u) {
1266 return state_translation_table[MOUNT(u)->state];
1269 static const char *mount_sub_state_to_string(Unit *u) {
1272 return mount_state_to_string(MOUNT(u)->state);
1275 static bool mount_check_gc(Unit *u) {
1276 Mount *m = MOUNT(u);
1280 return m->from_proc_self_mountinfo;
1283 static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1284 Mount *m = MOUNT(u);
1290 if (pid != m->control_pid)
1295 if (is_clean_exit(code, status, NULL))
1297 else if (code == CLD_EXITED)
1298 f = MOUNT_FAILURE_EXIT_CODE;
1299 else if (code == CLD_KILLED)
1300 f = MOUNT_FAILURE_SIGNAL;
1301 else if (code == CLD_DUMPED)
1302 f = MOUNT_FAILURE_CORE_DUMP;
1304 assert_not_reached("Unknown code");
1306 if (f != MOUNT_SUCCESS)
1309 if (m->control_command) {
1310 exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
1312 m->control_command = NULL;
1313 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
1316 log_full_unit(f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE, u->id,
1317 "%s mount process exited, code=%s status=%i",
1318 u->id, sigchld_code_to_string(code), status);
1320 /* Note that mount(8) returning and the kernel sending us a
1321 * mount table change event might happen out-of-order. If an
1322 * operation succeed we assume the kernel will follow soon too
1323 * and already change into the resulting state. If it fails
1324 * we check if the kernel still knows about the mount. and
1325 * change state accordingly. */
1329 case MOUNT_MOUNTING:
1330 case MOUNT_MOUNTING_DONE:
1331 case MOUNT_MOUNTING_SIGKILL:
1332 case MOUNT_MOUNTING_SIGTERM:
1334 if (f == MOUNT_SUCCESS)
1335 mount_enter_mounted(m, f);
1336 else if (m->from_proc_self_mountinfo)
1337 mount_enter_mounted(m, f);
1339 mount_enter_dead(m, f);
1342 case MOUNT_REMOUNTING:
1343 case MOUNT_REMOUNTING_SIGKILL:
1344 case MOUNT_REMOUNTING_SIGTERM:
1346 m->reload_result = f;
1347 if (m->from_proc_self_mountinfo)
1348 mount_enter_mounted(m, MOUNT_SUCCESS);
1350 mount_enter_dead(m, MOUNT_SUCCESS);
1354 case MOUNT_UNMOUNTING:
1355 case MOUNT_UNMOUNTING_SIGKILL:
1356 case MOUNT_UNMOUNTING_SIGTERM:
1358 if (f == MOUNT_SUCCESS)
1359 mount_enter_dead(m, f);
1360 else if (m->from_proc_self_mountinfo)
1361 mount_enter_mounted(m, f);
1363 mount_enter_dead(m, f);
1367 assert_not_reached("Uh, control process died at wrong time.");
1370 /* Notify clients about changed exit status */
1371 unit_add_to_dbus_queue(u);
1374 static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
1375 Mount *m = MOUNT(u);
1378 assert(elapsed == 1);
1379 assert(w == &m->timer_watch);
1383 case MOUNT_MOUNTING:
1384 case MOUNT_MOUNTING_DONE:
1385 log_warning_unit(u->id,
1386 "%s mounting timed out. Stopping.", u->id);
1387 mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1390 case MOUNT_REMOUNTING:
1391 log_warning_unit(u->id,
1392 "%s remounting timed out. Stopping.", u->id);
1393 m->reload_result = MOUNT_FAILURE_TIMEOUT;
1394 mount_enter_mounted(m, MOUNT_SUCCESS);
1397 case MOUNT_UNMOUNTING:
1398 log_warning_unit(u->id,
1399 "%s unmounting timed out. Stopping.", u->id);
1400 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1403 case MOUNT_MOUNTING_SIGTERM:
1404 if (m->kill_context.send_sigkill) {
1405 log_warning_unit(u->id,
1406 "%s mounting timed out. Killing.", u->id);
1407 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1409 log_warning_unit(u->id,
1410 "%s mounting timed out. Skipping SIGKILL. Ignoring.",
1413 if (m->from_proc_self_mountinfo)
1414 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1416 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1420 case MOUNT_REMOUNTING_SIGTERM:
1421 if (m->kill_context.send_sigkill) {
1422 log_warning_unit(u->id,
1423 "%s remounting timed out. Killing.", u->id);
1424 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1426 log_warning_unit(u->id,
1427 "%s remounting timed out. Skipping SIGKILL. Ignoring.",
1430 if (m->from_proc_self_mountinfo)
1431 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1433 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1437 case MOUNT_UNMOUNTING_SIGTERM:
1438 if (m->kill_context.send_sigkill) {
1439 log_warning_unit(u->id,
1440 "%s unmounting timed out. Killing.", u->id);
1441 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1443 log_warning_unit(u->id,
1444 "%s unmounting timed out. Skipping SIGKILL. Ignoring.",
1447 if (m->from_proc_self_mountinfo)
1448 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1450 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1454 case MOUNT_MOUNTING_SIGKILL:
1455 case MOUNT_REMOUNTING_SIGKILL:
1456 case MOUNT_UNMOUNTING_SIGKILL:
1457 log_warning_unit(u->id,
1458 "%s mount process still around after SIGKILL. Ignoring.",
1461 if (m->from_proc_self_mountinfo)
1462 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1464 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1468 assert_not_reached("Timeout at wrong time.");
1472 static int mount_add_one(
1476 const char *options,
1483 char *e, *w = NULL, *o = NULL, *f = NULL;
1485 bool load_extras = false;
1493 /* Ignore API mount points. They should never be referenced in
1494 * dependencies ever. */
1495 if (mount_point_is_api(where) || mount_point_ignore(where))
1498 if (streq(fstype, "autofs"))
1501 /* probably some kind of swap, ignore */
1502 if (!is_path(where))
1505 e = unit_name_from_path(where, ".mount");
1509 u = manager_get_unit(m, e);
1513 u = unit_new(m, sizeof(Mount));
1519 r = unit_add_name(u, e);
1525 MOUNT(u)->where = strdup(where);
1526 if (!MOUNT(u)->where) {
1531 u->source_path = strdup("/proc/self/mountinfo");
1532 if (!u->source_path) {
1537 r = unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_LOCAL_FS_TARGET, NULL, true);
1541 r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
1545 unit_add_to_load_queue(u);
1550 if (!MOUNT(u)->where) {
1551 MOUNT(u)->where = strdup(where);
1552 if (!MOUNT(u)->where) {
1558 if (u->load_state == UNIT_ERROR) {
1559 u->load_state = UNIT_LOADED;
1562 /* Load in the extras later on, after we
1563 * finished initialization of the unit */
1568 if (!(w = strdup(what)) ||
1569 !(o = strdup(options)) ||
1570 !(f = strdup(fstype))) {
1575 p = &MOUNT(u)->parameters_proc_self_mountinfo;
1577 MOUNT(u)->is_mounted = true;
1578 MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
1579 MOUNT(u)->just_changed = !streq_ptr(p->options, o);
1582 MOUNT(u)->from_proc_self_mountinfo = true;
1596 r = mount_add_extras(MOUNT(u));
1601 unit_add_to_dbus_queue(u);
1616 static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
1619 char *device, *path, *options, *options2, *fstype, *d, *p, *o;
1623 rewind(m->proc_self_mountinfo);
1628 device = path = options = options2 = fstype = d = p = o = NULL;
1630 if ((k = fscanf(m->proc_self_mountinfo,
1631 "%*s " /* (1) mount id */
1632 "%*s " /* (2) parent id */
1633 "%*s " /* (3) major:minor */
1634 "%*s " /* (4) root */
1635 "%ms " /* (5) mount point */
1636 "%ms" /* (6) mount options */
1637 "%*[^-]" /* (7) optional fields */
1638 "- " /* (8) separator */
1639 "%ms " /* (9) file system type */
1640 "%ms" /* (10) mount source */
1641 "%ms" /* (11) mount options 2 */
1642 "%*[^\n]", /* some rubbish at the end */
1652 log_warning("Failed to parse /proc/self/mountinfo:%u.", i);
1656 o = strjoin(options, ",", options2, NULL);
1662 if (!(d = cunescape(device)) ||
1663 !(p = cunescape(path))) {
1668 if ((k = mount_add_one(m, d, p, o, fstype, 0, set_flags)) < 0)
1695 static void mount_shutdown(Manager *m) {
1698 if (m->proc_self_mountinfo) {
1699 fclose(m->proc_self_mountinfo);
1700 m->proc_self_mountinfo = NULL;
1704 static int mount_enumerate(Manager *m) {
1708 if (!m->proc_self_mountinfo) {
1709 struct epoll_event ev = {
1711 .data.ptr = &m->mount_watch,
1714 m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
1715 if (!m->proc_self_mountinfo)
1718 m->mount_watch.type = WATCH_MOUNT;
1719 m->mount_watch.fd = fileno(m->proc_self_mountinfo);
1721 if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->mount_watch.fd, &ev) < 0)
1725 r = mount_load_proc_self_mountinfo(m, false);
1736 void mount_fd_event(Manager *m, int events) {
1741 assert(events & EPOLLPRI);
1743 /* The manager calls this for every fd event happening on the
1744 * /proc/self/mountinfo file, which informs us about mounting
1747 r = mount_load_proc_self_mountinfo(m, true);
1749 log_error("Failed to reread /proc/self/mountinfo: %s", strerror(-r));
1751 /* Reset flags, just in case, for later calls */
1752 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1753 Mount *mount = MOUNT(u);
1755 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1761 manager_dispatch_load_queue(m);
1763 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1764 Mount *mount = MOUNT(u);
1766 if (!mount->is_mounted) {
1767 /* This has just been unmounted. */
1769 mount->from_proc_self_mountinfo = false;
1771 switch (mount->state) {
1774 mount_enter_dead(mount, MOUNT_SUCCESS);
1778 mount_set_state(mount, mount->state);
1783 } else if (mount->just_mounted || mount->just_changed) {
1785 /* New or changed mount entry */
1787 switch (mount->state) {
1791 mount_enter_mounted(mount, MOUNT_SUCCESS);
1794 case MOUNT_MOUNTING:
1795 mount_enter_mounting_done(mount);
1799 /* Nothing really changed, but let's
1800 * issue an notification call
1801 * nonetheless, in case somebody is
1802 * waiting for this. (e.g. file system
1803 * ro/rw remounts.) */
1804 mount_set_state(mount, mount->state);
1809 /* Reset the flags for later calls */
1810 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1814 static void mount_reset_failed(Unit *u) {
1815 Mount *m = MOUNT(u);
1819 if (m->state == MOUNT_FAILED)
1820 mount_set_state(m, MOUNT_DEAD);
1822 m->result = MOUNT_SUCCESS;
1823 m->reload_result = MOUNT_SUCCESS;
1826 static int mount_kill(Unit *u, KillWho who, int signo, DBusError *error) {
1827 return unit_kill_common(u, who, signo, -1, MOUNT(u)->control_pid, error);
1830 static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
1831 [MOUNT_DEAD] = "dead",
1832 [MOUNT_MOUNTING] = "mounting",
1833 [MOUNT_MOUNTING_DONE] = "mounting-done",
1834 [MOUNT_MOUNTED] = "mounted",
1835 [MOUNT_REMOUNTING] = "remounting",
1836 [MOUNT_UNMOUNTING] = "unmounting",
1837 [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm",
1838 [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill",
1839 [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
1840 [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
1841 [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
1842 [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
1843 [MOUNT_FAILED] = "failed"
1846 DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
1848 static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
1849 [MOUNT_EXEC_MOUNT] = "ExecMount",
1850 [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
1851 [MOUNT_EXEC_REMOUNT] = "ExecRemount",
1854 DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
1856 static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
1857 [MOUNT_SUCCESS] = "success",
1858 [MOUNT_FAILURE_RESOURCES] = "resources",
1859 [MOUNT_FAILURE_TIMEOUT] = "timeout",
1860 [MOUNT_FAILURE_EXIT_CODE] = "exit-code",
1861 [MOUNT_FAILURE_SIGNAL] = "signal",
1862 [MOUNT_FAILURE_CORE_DUMP] = "core-dump"
1865 DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
1867 const UnitVTable mount_vtable = {
1868 .object_size = sizeof(Mount),
1875 .exec_context_offset = offsetof(Mount, exec_context),
1876 .exec_section = "Mount",
1879 .no_instances = true,
1885 .coldplug = mount_coldplug,
1889 .start = mount_start,
1891 .reload = mount_reload,
1895 .serialize = mount_serialize,
1896 .deserialize_item = mount_deserialize_item,
1898 .active_state = mount_active_state,
1899 .sub_state_to_string = mount_sub_state_to_string,
1901 .check_gc = mount_check_gc,
1903 .sigchld_event = mount_sigchld_event,
1904 .timer_event = mount_timer_event,
1906 .reset_failed = mount_reset_failed,
1908 .bus_interface = "org.freedesktop.systemd1.Mount",
1909 .bus_message_handler = bus_mount_message_handler,
1910 .bus_invalidating_properties = bus_mount_invalidating_properties,
1912 .enumerate = mount_enumerate,
1913 .shutdown = mount_shutdown,
1915 .status_message_formats = {
1916 .starting_stopping = {
1917 [0] = "Mounting %s...",
1918 [1] = "Unmounting %s...",
1920 .finished_start_job = {
1921 [JOB_DONE] = "Mounted %s.",
1922 [JOB_FAILED] = "Failed to mount %s.",
1923 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1924 [JOB_TIMEOUT] = "Timed out mounting %s.",
1926 .finished_stop_job = {
1927 [JOB_DONE] = "Unmounted %s.",
1928 [JOB_FAILED] = "Failed unmounting %s.",
1929 [JOB_TIMEOUT] = "Timed out unmounting %s.",