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/>.
24 #include <sys/epoll.h>
27 #include <sys/inotify.h>
33 #include "sd-messages.h"
36 #include "path-util.h"
37 #include "mount-setup.h"
38 #include "unit-name.h"
39 #include "dbus-mount.h"
41 #include "exit-status.h"
42 #include "fstab-util.h"
44 #define RETRY_UMOUNT_MAX 32
46 DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_table*, mnt_free_table);
47 DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_iter*, mnt_free_iter);
49 static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
50 [MOUNT_DEAD] = UNIT_INACTIVE,
51 [MOUNT_MOUNTING] = UNIT_ACTIVATING,
52 [MOUNT_MOUNTING_DONE] = UNIT_ACTIVE,
53 [MOUNT_MOUNTED] = UNIT_ACTIVE,
54 [MOUNT_REMOUNTING] = UNIT_RELOADING,
55 [MOUNT_UNMOUNTING] = UNIT_DEACTIVATING,
56 [MOUNT_MOUNTING_SIGTERM] = UNIT_DEACTIVATING,
57 [MOUNT_MOUNTING_SIGKILL] = UNIT_DEACTIVATING,
58 [MOUNT_REMOUNTING_SIGTERM] = UNIT_RELOADING,
59 [MOUNT_REMOUNTING_SIGKILL] = UNIT_RELOADING,
60 [MOUNT_UNMOUNTING_SIGTERM] = UNIT_DEACTIVATING,
61 [MOUNT_UNMOUNTING_SIGKILL] = UNIT_DEACTIVATING,
62 [MOUNT_FAILED] = UNIT_FAILED
65 static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
66 static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
68 static bool mount_needs_network(const char *options, const char *fstype) {
69 if (fstab_test_option(options, "_netdev\0"))
72 if (fstype && fstype_is_network(fstype))
78 static bool mount_is_network(const MountParameters *p) {
81 return mount_needs_network(p->options, p->fstype);
84 static bool mount_is_bind(const MountParameters *p) {
87 if (fstab_test_option(p->options, "bind\0" "rbind\0"))
90 if (p->fstype && STR_IN_SET(p->fstype, "bind", "rbind"))
96 static bool mount_is_auto(const MountParameters *p) {
99 return !fstab_test_option(p->options, "noauto\0");
102 static bool needs_quota(const MountParameters *p) {
105 if (mount_is_network(p))
108 if (mount_is_bind(p))
111 return fstab_test_option(p->options,
112 "usrquota\0" "grpquota\0" "quota\0" "usrjquota\0" "grpjquota\0");
115 static void mount_init(Unit *u) {
119 assert(u->load_state == UNIT_STUB);
121 m->timeout_usec = u->manager->default_timeout_start_usec;
122 m->directory_mode = 0755;
124 if (unit_has_name(u, "-.mount")) {
125 /* Don't allow start/stop for root directory */
126 u->refuse_manual_start = true;
127 u->refuse_manual_stop = true;
129 /* The stdio/kmsg bridge socket is on /, in order to avoid a
130 * dep loop, don't use kmsg logging for -.mount */
131 m->exec_context.std_output = u->manager->default_std_output;
132 m->exec_context.std_error = u->manager->default_std_error;
135 /* We need to make sure that /bin/mount is always called in
136 * the same process group as us, so that the autofs kernel
137 * side doesn't send us another mount request while we are
138 * already trying to comply its last one. */
139 m->exec_context.same_pgrp = true;
141 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
143 u->ignore_on_isolate = true;
146 static int mount_arm_timer(Mount *m) {
151 if (m->timeout_usec <= 0) {
152 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
156 if (m->timer_event_source) {
157 r = sd_event_source_set_time(m->timer_event_source, now(CLOCK_MONOTONIC) + m->timeout_usec);
161 return sd_event_source_set_enabled(m->timer_event_source, SD_EVENT_ONESHOT);
164 return sd_event_add_time(
165 UNIT(m)->manager->event,
166 &m->timer_event_source,
168 now(CLOCK_MONOTONIC) + m->timeout_usec, 0,
169 mount_dispatch_timer, m);
172 static void mount_unwatch_control_pid(Mount *m) {
175 if (m->control_pid <= 0)
178 unit_unwatch_pid(UNIT(m), m->control_pid);
182 static void mount_parameters_done(MountParameters *p) {
189 p->what = p->options = p->fstype = NULL;
192 static void mount_done(Unit *u) {
200 mount_parameters_done(&m->parameters_proc_self_mountinfo);
201 mount_parameters_done(&m->parameters_fragment);
203 m->exec_runtime = exec_runtime_unref(m->exec_runtime);
204 exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
205 m->control_command = NULL;
207 mount_unwatch_control_pid(m);
209 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
212 _pure_ static MountParameters* get_mount_parameters_fragment(Mount *m) {
215 if (m->from_fragment)
216 return &m->parameters_fragment;
221 _pure_ static MountParameters* get_mount_parameters(Mount *m) {
224 if (m->from_proc_self_mountinfo)
225 return &m->parameters_proc_self_mountinfo;
227 return get_mount_parameters_fragment(m);
230 static int mount_add_mount_links(Mount *m) {
231 _cleanup_free_ char *parent = NULL;
240 if (!path_equal(m->where, "/")) {
241 /* Adds in links to other mount points that might lie further
242 * up in the hierarchy */
243 r = path_get_parent(m->where, &parent);
247 r = unit_require_mounts_for(UNIT(m), parent);
252 /* Adds in links to other mount points that might be needed
253 * for the source path (if this is a bind mount) to be
255 pm = get_mount_parameters_fragment(m);
256 if (pm && pm->what &&
257 path_is_absolute(pm->what) &&
258 !mount_is_network(pm)) {
260 r = unit_require_mounts_for(UNIT(m), pm->what);
265 /* Adds in links to other units that use this path or paths
266 * further down in the hierarchy */
267 s = manager_get_units_requiring_mounts_for(UNIT(m)->manager, m->where);
268 SET_FOREACH(other, s, i) {
270 if (other->load_state != UNIT_LOADED)
273 if (other == UNIT(m))
276 r = unit_add_dependency(other, UNIT_AFTER, UNIT(m), true);
280 if (UNIT(m)->fragment_path) {
281 /* If we have fragment configuration, then make this dependency required */
282 r = unit_add_dependency(other, UNIT_REQUIRES, UNIT(m), true);
291 static int mount_add_device_links(Mount *m) {
293 bool device_wants_mount = false;
298 p = get_mount_parameters(m);
305 if (mount_is_bind(p))
308 if (!is_device_path(p->what))
311 if (path_equal(m->where, "/"))
314 if (mount_is_auto(p) && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
315 device_wants_mount = true;
317 r = unit_add_node_link(UNIT(m), p->what, device_wants_mount);
324 static int mount_add_quota_links(Mount *m) {
330 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
333 p = get_mount_parameters_fragment(m);
340 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true);
344 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true);
351 static bool should_umount(Mount *m) {
354 if (path_equal(m->where, "/") ||
355 path_equal(m->where, "/usr"))
358 p = get_mount_parameters(m);
359 if (p && fstab_test_option(p->options, "x-initrd.mount\0") &&
366 static int mount_add_default_dependencies(Mount *m) {
367 const char *after, *after2, *online;
373 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
376 /* We do not add any default dependencies to / and /usr, since
377 * they are guaranteed to stay mounted the whole time, since
378 * our system is on it. Also, don't bother with anything
379 * mounted below virtual file systems, it's also going to be
380 * virtual, and hence not worth the effort. */
381 if (path_equal(m->where, "/") ||
382 path_equal(m->where, "/usr") ||
383 path_startswith(m->where, "/proc") ||
384 path_startswith(m->where, "/sys") ||
385 path_startswith(m->where, "/dev"))
388 p = get_mount_parameters(m);
392 if (mount_is_network(p)) {
393 after = SPECIAL_REMOTE_FS_PRE_TARGET;
394 after2 = SPECIAL_NETWORK_TARGET;
395 online = SPECIAL_NETWORK_ONLINE_TARGET;
397 after = SPECIAL_LOCAL_FS_PRE_TARGET;
402 r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true);
407 r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after2, NULL, true);
413 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, online, NULL, true);
418 if (should_umount(m)) {
419 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
427 static int mount_verify(Mount *m) {
428 _cleanup_free_ char *e = NULL;
433 if (UNIT(m)->load_state != UNIT_LOADED)
436 if (!m->from_fragment && !m->from_proc_self_mountinfo)
439 e = unit_name_from_path(m->where, ".mount");
443 b = unit_has_name(UNIT(m), e);
445 log_unit_error(UNIT(m)->id, "%s's Where= setting doesn't match unit name. Refusing.", UNIT(m)->id);
449 if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) {
450 log_unit_error(UNIT(m)->id, "Cannot create mount unit for API file system %s. Refusing.", m->where);
454 if (UNIT(m)->fragment_path && !m->parameters_fragment.what) {
455 log_unit_error(UNIT(m)->id, "%s's What setting is missing. Refusing.", UNIT(m)->id);
459 if (m->exec_context.pam_name && m->kill_context.kill_mode != KILL_CONTROL_GROUP) {
460 log_unit_error(UNIT(m)->id, "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.",UNIT(m)->id);
467 static int mount_add_extras(Mount *m) {
473 if (u->fragment_path)
474 m->from_fragment = true;
477 m->where = unit_name_to_path(u->id);
482 path_kill_slashes(m->where);
484 if (!u->description) {
485 r = unit_set_description(u, m->where);
490 r = mount_add_device_links(m);
494 r = mount_add_mount_links(m);
498 r = mount_add_quota_links(m);
502 r = unit_patch_contexts(u);
506 r = unit_add_exec_dependencies(u, &m->exec_context);
510 r = unit_add_default_slice(u, &m->cgroup_context);
514 if (u->default_dependencies) {
515 r = mount_add_default_dependencies(m);
523 static int mount_load(Unit *u) {
528 assert(u->load_state == UNIT_STUB);
530 if (m->from_proc_self_mountinfo)
531 r = unit_load_fragment_and_dropin_optional(u);
533 r = unit_load_fragment_and_dropin(u);
538 /* This is a new unit? Then let's add in some extras */
539 if (u->load_state == UNIT_LOADED) {
540 r = mount_add_extras(m);
545 return mount_verify(m);
548 static int mount_notify_automount(Mount *m, int status) {
555 SET_FOREACH(p, UNIT(m)->dependencies[UNIT_TRIGGERED_BY], i)
556 if (p->type == UNIT_AUTOMOUNT) {
557 r = automount_send_ready(AUTOMOUNT(p), status);
565 static void mount_set_state(Mount *m, MountState state) {
566 MountState old_state;
569 old_state = m->state;
572 if (state != MOUNT_MOUNTING &&
573 state != MOUNT_MOUNTING_DONE &&
574 state != MOUNT_REMOUNTING &&
575 state != MOUNT_UNMOUNTING &&
576 state != MOUNT_MOUNTING_SIGTERM &&
577 state != MOUNT_MOUNTING_SIGKILL &&
578 state != MOUNT_UNMOUNTING_SIGTERM &&
579 state != MOUNT_UNMOUNTING_SIGKILL &&
580 state != MOUNT_REMOUNTING_SIGTERM &&
581 state != MOUNT_REMOUNTING_SIGKILL) {
582 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
583 mount_unwatch_control_pid(m);
584 m->control_command = NULL;
585 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
588 if (state == MOUNT_MOUNTED ||
589 state == MOUNT_REMOUNTING)
590 mount_notify_automount(m, 0);
591 else if (state == MOUNT_DEAD ||
592 state == MOUNT_UNMOUNTING ||
593 state == MOUNT_MOUNTING_SIGTERM ||
594 state == MOUNT_MOUNTING_SIGKILL ||
595 state == MOUNT_REMOUNTING_SIGTERM ||
596 state == MOUNT_REMOUNTING_SIGKILL ||
597 state == MOUNT_UNMOUNTING_SIGTERM ||
598 state == MOUNT_UNMOUNTING_SIGKILL ||
599 state == MOUNT_FAILED) {
600 if (state != old_state)
601 mount_notify_automount(m, -ENODEV);
604 if (state != old_state)
605 log_unit_debug(UNIT(m)->id,
606 "%s changed %s -> %s",
608 mount_state_to_string(old_state),
609 mount_state_to_string(state));
611 unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
612 m->reload_result = MOUNT_SUCCESS;
615 static int mount_coldplug(Unit *u, Hashmap *deferred_work) {
617 MountState new_state = MOUNT_DEAD;
621 assert(m->state == MOUNT_DEAD);
623 if (m->deserialized_state != m->state)
624 new_state = m->deserialized_state;
625 else if (m->from_proc_self_mountinfo)
626 new_state = MOUNT_MOUNTED;
628 if (new_state == m->state)
631 if (new_state == MOUNT_MOUNTING ||
632 new_state == MOUNT_MOUNTING_DONE ||
633 new_state == MOUNT_REMOUNTING ||
634 new_state == MOUNT_UNMOUNTING ||
635 new_state == MOUNT_MOUNTING_SIGTERM ||
636 new_state == MOUNT_MOUNTING_SIGKILL ||
637 new_state == MOUNT_UNMOUNTING_SIGTERM ||
638 new_state == MOUNT_UNMOUNTING_SIGKILL ||
639 new_state == MOUNT_REMOUNTING_SIGTERM ||
640 new_state == MOUNT_REMOUNTING_SIGKILL) {
642 if (m->control_pid <= 0)
645 r = unit_watch_pid(UNIT(m), m->control_pid);
649 r = mount_arm_timer(m);
654 mount_set_state(m, new_state);
658 static void mount_dump(Unit *u, FILE *f, const char *prefix) {
665 p = get_mount_parameters(m);
668 "%sMount State: %s\n"
672 "%sFile System Type: %s\n"
674 "%sFrom /proc/self/mountinfo: %s\n"
675 "%sFrom fragment: %s\n"
676 "%sDirectoryMode: %04o\n",
677 prefix, mount_state_to_string(m->state),
678 prefix, mount_result_to_string(m->result),
680 prefix, p ? strna(p->what) : "n/a",
681 prefix, p ? strna(p->fstype) : "n/a",
682 prefix, p ? strna(p->options) : "n/a",
683 prefix, yes_no(m->from_proc_self_mountinfo),
684 prefix, yes_no(m->from_fragment),
685 prefix, m->directory_mode);
687 if (m->control_pid > 0)
689 "%sControl PID: "PID_FMT"\n",
690 prefix, m->control_pid);
692 exec_context_dump(&m->exec_context, f, prefix);
693 kill_context_dump(&m->kill_context, f, prefix);
696 static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
699 ExecParameters exec_params = {
700 .apply_permissions = true,
701 .apply_chroot = true,
702 .apply_tty_stdin = true,
709 (void) unit_realize_cgroup(UNIT(m));
710 if (m->reset_cpu_usage) {
711 (void) unit_reset_cpu_usage(UNIT(m));
712 m->reset_cpu_usage = false;
715 r = unit_setup_exec_runtime(UNIT(m));
719 r = mount_arm_timer(m);
723 exec_params.environment = UNIT(m)->manager->environment;
724 exec_params.confirm_spawn = UNIT(m)->manager->confirm_spawn;
725 exec_params.cgroup_supported = UNIT(m)->manager->cgroup_supported;
726 exec_params.cgroup_path = UNIT(m)->cgroup_path;
727 exec_params.cgroup_delegate = m->cgroup_context.delegate;
728 exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(m)->manager);
729 exec_params.unit_id = UNIT(m)->id;
739 r = unit_watch_pid(UNIT(m), pid);
741 /* FIXME: we need to do something here */
749 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
754 static void mount_enter_dead(Mount *m, MountResult f) {
757 if (f != MOUNT_SUCCESS)
760 exec_runtime_destroy(m->exec_runtime);
761 m->exec_runtime = exec_runtime_unref(m->exec_runtime);
763 exec_context_destroy_runtime_directory(&m->exec_context, manager_get_runtime_prefix(UNIT(m)->manager));
765 mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
768 static void mount_enter_mounted(Mount *m, MountResult f) {
771 if (f != MOUNT_SUCCESS)
774 mount_set_state(m, MOUNT_MOUNTED);
777 static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
782 if (f != MOUNT_SUCCESS)
785 r = unit_kill_context(
788 (state != MOUNT_MOUNTING_SIGTERM && state != MOUNT_UNMOUNTING_SIGTERM && state != MOUNT_REMOUNTING_SIGTERM) ?
789 KILL_KILL : KILL_TERMINATE,
797 r = mount_arm_timer(m);
801 mount_set_state(m, state);
802 } else if (state == MOUNT_REMOUNTING_SIGTERM)
803 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_SUCCESS);
804 else if (state == MOUNT_REMOUNTING_SIGKILL)
805 mount_enter_mounted(m, MOUNT_SUCCESS);
806 else if (state == MOUNT_MOUNTING_SIGTERM)
807 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_SUCCESS);
808 else if (state == MOUNT_UNMOUNTING_SIGTERM)
809 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_SUCCESS);
811 mount_enter_dead(m, MOUNT_SUCCESS);
816 log_unit_warning(UNIT(m)->id,
817 "%s failed to kill processes: %s", UNIT(m)->id, strerror(-r));
819 if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
820 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
822 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
825 void warn_if_dir_nonempty(const char *unit, const char* where) {
831 r = dir_is_empty(where);
835 log_unit_struct(unit,
837 LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
838 LOG_MESSAGE("%s: Directory %s to mount over is not empty, mounting anyway.",
843 log_unit_warning(unit,
844 "MESSAGE=Failed to check directory %s: %s",
845 where, strerror(-r));
848 static int fail_if_symlink(const char *unit, const char* where) {
851 if (is_symlink(where) > 0) {
852 log_unit_struct(unit,
854 LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
855 LOG_MESSAGE("%s: Mount on symlink %s not allowed.",
865 static void mount_enter_unmounting(Mount *m) {
870 /* Start counting our attempts */
871 if (!IN_SET(m->state,
873 MOUNT_UNMOUNTING_SIGTERM,
874 MOUNT_UNMOUNTING_SIGKILL))
875 m->n_retry_umount = 0;
877 m->control_command_id = MOUNT_EXEC_UNMOUNT;
878 m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
880 r = exec_command_set(m->control_command, "/bin/umount", m->where, NULL);
881 if (r >= 0 && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
882 r = exec_command_append(m->control_command, "-n", NULL);
886 mount_unwatch_control_pid(m);
888 r = mount_spawn(m, m->control_command, &m->control_pid);
892 mount_set_state(m, MOUNT_UNMOUNTING);
897 log_unit_warning(UNIT(m)->id,
898 "%s failed to run 'umount' task: %s",
899 UNIT(m)->id, strerror(-r));
900 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
903 static void mount_enter_mounting(Mount *m) {
909 m->control_command_id = MOUNT_EXEC_MOUNT;
910 m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
912 mkdir_p_label(m->where, m->directory_mode);
914 warn_if_dir_nonempty(m->meta.id, m->where);
916 /* Create the source directory for bind-mounts if needed */
917 p = get_mount_parameters_fragment(m);
918 if (p && mount_is_bind(p))
919 mkdir_p_label(p->what, m->directory_mode);
921 r = fail_if_symlink(m->meta.id, m->where);
925 if (m->from_fragment) {
926 _cleanup_free_ char *opts = NULL;
928 r = fstab_filter_options(m->parameters_fragment.options,
929 "nofail\0" "noauto\0" "auto\0", NULL, NULL, &opts);
933 r = exec_command_set(m->control_command, "/bin/mount",
934 m->parameters_fragment.what, m->where, NULL);
935 if (r >= 0 && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
936 r = exec_command_append(m->control_command, "-n", NULL);
937 if (r >= 0 && m->sloppy_options)
938 r = exec_command_append(m->control_command, "-s", NULL);
939 if (r >= 0 && m->parameters_fragment.fstype)
940 r = exec_command_append(m->control_command, "-t", m->parameters_fragment.fstype, NULL);
941 if (r >= 0 && !isempty(opts))
942 r = exec_command_append(m->control_command, "-o", opts, NULL);
949 mount_unwatch_control_pid(m);
951 r = mount_spawn(m, m->control_command, &m->control_pid);
955 mount_set_state(m, MOUNT_MOUNTING);
960 log_unit_warning(UNIT(m)->id,
961 "%s failed to run 'mount' task: %s",
962 UNIT(m)->id, strerror(-r));
963 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
966 static void mount_enter_remounting(Mount *m) {
971 m->control_command_id = MOUNT_EXEC_REMOUNT;
972 m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
974 if (m->from_fragment) {
977 if (m->parameters_fragment.options)
978 o = strjoina("remount,", m->parameters_fragment.options);
982 r = exec_command_set(m->control_command, "/bin/mount",
983 m->parameters_fragment.what, m->where,
985 if (r >= 0 && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
986 r = exec_command_append(m->control_command, "-n", NULL);
987 if (r >= 0 && m->sloppy_options)
988 r = exec_command_append(m->control_command, "-s", NULL);
989 if (r >= 0 && m->parameters_fragment.fstype)
990 r = exec_command_append(m->control_command, "-t", m->parameters_fragment.fstype, NULL);
997 mount_unwatch_control_pid(m);
999 r = mount_spawn(m, m->control_command, &m->control_pid);
1003 mount_set_state(m, MOUNT_REMOUNTING);
1008 log_unit_warning(UNIT(m)->id,
1009 "%s failed to run 'remount' task: %s",
1010 UNIT(m)->id, strerror(-r));
1011 m->reload_result = MOUNT_FAILURE_RESOURCES;
1012 mount_enter_mounted(m, MOUNT_SUCCESS);
1015 static int mount_start(Unit *u) {
1016 Mount *m = MOUNT(u);
1020 /* We cannot fulfill this request right now, try again later
1022 if (m->state == MOUNT_UNMOUNTING ||
1023 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1024 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1025 m->state == MOUNT_MOUNTING_SIGTERM ||
1026 m->state == MOUNT_MOUNTING_SIGKILL)
1029 /* Already on it! */
1030 if (m->state == MOUNT_MOUNTING)
1033 assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED);
1035 m->result = MOUNT_SUCCESS;
1036 m->reload_result = MOUNT_SUCCESS;
1037 m->reset_cpu_usage = true;
1039 mount_enter_mounting(m);
1043 static int mount_stop(Unit *u) {
1044 Mount *m = MOUNT(u);
1049 if (m->state == MOUNT_UNMOUNTING ||
1050 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1051 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1052 m->state == MOUNT_MOUNTING_SIGTERM ||
1053 m->state == MOUNT_MOUNTING_SIGKILL)
1056 assert(m->state == MOUNT_MOUNTING ||
1057 m->state == MOUNT_MOUNTING_DONE ||
1058 m->state == MOUNT_MOUNTED ||
1059 m->state == MOUNT_REMOUNTING ||
1060 m->state == MOUNT_REMOUNTING_SIGTERM ||
1061 m->state == MOUNT_REMOUNTING_SIGKILL);
1063 mount_enter_unmounting(m);
1067 static int mount_reload(Unit *u) {
1068 Mount *m = MOUNT(u);
1072 if (m->state == MOUNT_MOUNTING_DONE)
1075 assert(m->state == MOUNT_MOUNTED);
1077 mount_enter_remounting(m);
1081 static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
1082 Mount *m = MOUNT(u);
1088 unit_serialize_item(u, f, "state", mount_state_to_string(m->state));
1089 unit_serialize_item(u, f, "result", mount_result_to_string(m->result));
1090 unit_serialize_item(u, f, "reload-result", mount_result_to_string(m->reload_result));
1092 if (m->control_pid > 0)
1093 unit_serialize_item_format(u, f, "control-pid", PID_FMT, m->control_pid);
1095 if (m->control_command_id >= 0)
1096 unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id));
1101 static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1102 Mount *m = MOUNT(u);
1109 if (streq(key, "state")) {
1112 if ((state = mount_state_from_string(value)) < 0)
1113 log_unit_debug(u->id, "Failed to parse state value %s", value);
1115 m->deserialized_state = state;
1116 } else if (streq(key, "result")) {
1119 f = mount_result_from_string(value);
1121 log_unit_debug(UNIT(m)->id,
1122 "Failed to parse result value %s", value);
1123 else if (f != MOUNT_SUCCESS)
1126 } else if (streq(key, "reload-result")) {
1129 f = mount_result_from_string(value);
1131 log_unit_debug(UNIT(m)->id,
1132 "Failed to parse reload result value %s", value);
1133 else if (f != MOUNT_SUCCESS)
1134 m->reload_result = f;
1136 } else if (streq(key, "control-pid")) {
1139 if (parse_pid(value, &pid) < 0)
1140 log_unit_debug(UNIT(m)->id,
1141 "Failed to parse control-pid value %s", value);
1143 m->control_pid = pid;
1144 } else if (streq(key, "control-command")) {
1145 MountExecCommand id;
1147 if ((id = mount_exec_command_from_string(value)) < 0)
1148 log_unit_debug(UNIT(m)->id,
1149 "Failed to parse exec-command value %s", value);
1151 m->control_command_id = id;
1152 m->control_command = m->exec_command + id;
1155 log_unit_debug(UNIT(m)->id,
1156 "Unknown serialization key '%s'", key);
1161 _pure_ static UnitActiveState mount_active_state(Unit *u) {
1164 return state_translation_table[MOUNT(u)->state];
1167 _pure_ static const char *mount_sub_state_to_string(Unit *u) {
1170 return mount_state_to_string(MOUNT(u)->state);
1173 _pure_ static bool mount_check_gc(Unit *u) {
1174 Mount *m = MOUNT(u);
1178 return m->from_proc_self_mountinfo;
1181 static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1182 Mount *m = MOUNT(u);
1188 if (pid != m->control_pid)
1193 if (is_clean_exit(code, status, NULL))
1195 else if (code == CLD_EXITED)
1196 f = MOUNT_FAILURE_EXIT_CODE;
1197 else if (code == CLD_KILLED)
1198 f = MOUNT_FAILURE_SIGNAL;
1199 else if (code == CLD_DUMPED)
1200 f = MOUNT_FAILURE_CORE_DUMP;
1202 assert_not_reached("Unknown code");
1204 if (f != MOUNT_SUCCESS)
1207 if (m->control_command) {
1208 exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
1210 m->control_command = NULL;
1211 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
1214 log_unit_full(u->id,
1215 f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
1216 "%s mount process exited, code=%s status=%i",
1217 u->id, sigchld_code_to_string(code), status);
1219 /* Note that mount(8) returning and the kernel sending us a
1220 * mount table change event might happen out-of-order. If an
1221 * operation succeed we assume the kernel will follow soon too
1222 * and already change into the resulting state. If it fails
1223 * we check if the kernel still knows about the mount. and
1224 * change state accordingly. */
1228 case MOUNT_MOUNTING:
1229 case MOUNT_MOUNTING_DONE:
1230 case MOUNT_MOUNTING_SIGKILL:
1231 case MOUNT_MOUNTING_SIGTERM:
1233 if (f == MOUNT_SUCCESS)
1234 mount_enter_mounted(m, f);
1235 else if (m->from_proc_self_mountinfo)
1236 mount_enter_mounted(m, f);
1238 mount_enter_dead(m, f);
1241 case MOUNT_REMOUNTING:
1242 case MOUNT_REMOUNTING_SIGKILL:
1243 case MOUNT_REMOUNTING_SIGTERM:
1245 m->reload_result = f;
1246 if (m->from_proc_self_mountinfo)
1247 mount_enter_mounted(m, MOUNT_SUCCESS);
1249 mount_enter_dead(m, MOUNT_SUCCESS);
1253 case MOUNT_UNMOUNTING:
1254 case MOUNT_UNMOUNTING_SIGKILL:
1255 case MOUNT_UNMOUNTING_SIGTERM:
1257 if (f == MOUNT_SUCCESS) {
1259 if (m->from_proc_self_mountinfo) {
1261 /* Still a mount point? If so, let's
1262 * try again. Most likely there were
1263 * multiple mount points stacked on
1264 * top of each other. Note that due to
1265 * the io event priority logic we can
1266 * be sure the new mountinfo is loaded
1267 * before we process the SIGCHLD for
1268 * the mount command. */
1270 if (m->n_retry_umount < RETRY_UMOUNT_MAX) {
1271 log_unit_debug(u->id, "%s: mount still present, trying again.", u->id);
1272 m->n_retry_umount++;
1273 mount_enter_unmounting(m);
1275 log_unit_debug(u->id, "%s: mount still present after %u attempts to unmount, giving up.", u->id, m->n_retry_umount);
1276 mount_enter_mounted(m, f);
1279 mount_enter_dead(m, f);
1281 } else if (m->from_proc_self_mountinfo)
1282 mount_enter_mounted(m, f);
1284 mount_enter_dead(m, f);
1288 assert_not_reached("Uh, control process died at wrong time.");
1291 /* Notify clients about changed exit status */
1292 unit_add_to_dbus_queue(u);
1295 static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1296 Mount *m = MOUNT(userdata);
1299 assert(m->timer_event_source == source);
1303 case MOUNT_MOUNTING:
1304 case MOUNT_MOUNTING_DONE:
1305 log_unit_warning(UNIT(m)->id,
1306 "%s mounting timed out. Stopping.", UNIT(m)->id);
1307 mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1310 case MOUNT_REMOUNTING:
1311 log_unit_warning(UNIT(m)->id,
1312 "%s remounting timed out. Stopping.", UNIT(m)->id);
1313 m->reload_result = MOUNT_FAILURE_TIMEOUT;
1314 mount_enter_mounted(m, MOUNT_SUCCESS);
1317 case MOUNT_UNMOUNTING:
1318 log_unit_warning(UNIT(m)->id,
1319 "%s unmounting timed out. Stopping.", UNIT(m)->id);
1320 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1323 case MOUNT_MOUNTING_SIGTERM:
1324 if (m->kill_context.send_sigkill) {
1325 log_unit_warning(UNIT(m)->id,
1326 "%s mounting timed out. Killing.", UNIT(m)->id);
1327 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1329 log_unit_warning(UNIT(m)->id,
1330 "%s mounting timed out. Skipping SIGKILL. Ignoring.",
1333 if (m->from_proc_self_mountinfo)
1334 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1336 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1340 case MOUNT_REMOUNTING_SIGTERM:
1341 if (m->kill_context.send_sigkill) {
1342 log_unit_warning(UNIT(m)->id,
1343 "%s remounting timed out. Killing.", UNIT(m)->id);
1344 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1346 log_unit_warning(UNIT(m)->id,
1347 "%s remounting timed out. Skipping SIGKILL. Ignoring.",
1350 if (m->from_proc_self_mountinfo)
1351 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1353 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1357 case MOUNT_UNMOUNTING_SIGTERM:
1358 if (m->kill_context.send_sigkill) {
1359 log_unit_warning(UNIT(m)->id,
1360 "%s unmounting timed out. Killing.", UNIT(m)->id);
1361 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1363 log_unit_warning(UNIT(m)->id,
1364 "%s unmounting timed out. Skipping SIGKILL. Ignoring.",
1367 if (m->from_proc_self_mountinfo)
1368 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1370 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1374 case MOUNT_MOUNTING_SIGKILL:
1375 case MOUNT_REMOUNTING_SIGKILL:
1376 case MOUNT_UNMOUNTING_SIGKILL:
1377 log_unit_warning(UNIT(m)->id,
1378 "%s mount process still around after SIGKILL. Ignoring.",
1381 if (m->from_proc_self_mountinfo)
1382 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1384 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1388 assert_not_reached("Timeout at wrong time.");
1394 static int mount_setup_unit(
1398 const char *options,
1402 _cleanup_free_ char *e = NULL, *w = NULL, *o = NULL, *f = NULL;
1403 bool load_extras = false;
1405 bool delete, changed = false;
1415 /* Ignore API mount points. They should never be referenced in
1416 * dependencies ever. */
1417 if (mount_point_is_api(where) || mount_point_ignore(where))
1420 if (streq(fstype, "autofs"))
1423 /* probably some kind of swap, ignore */
1424 if (!is_path(where))
1427 e = unit_name_from_path(where, ".mount");
1431 u = manager_get_unit(m, e);
1435 u = unit_new(m, sizeof(Mount));
1439 r = unit_add_name(u, e);
1443 MOUNT(u)->where = strdup(where);
1444 if (!MOUNT(u)->where) {
1449 u->source_path = strdup("/proc/self/mountinfo");
1450 if (!u->source_path) {
1455 if (m->running_as == SYSTEMD_SYSTEM) {
1458 target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET;
1459 r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true);
1463 if (should_umount(MOUNT(u))) {
1464 r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
1470 unit_add_to_load_queue(u);
1475 if (!MOUNT(u)->where) {
1476 MOUNT(u)->where = strdup(where);
1477 if (!MOUNT(u)->where) {
1483 if (m->running_as == SYSTEMD_SYSTEM &&
1484 mount_needs_network(options, fstype)) {
1485 /* _netdev option may have shown up late, or on a
1486 * remount. Add remote-fs dependencies, even though
1487 * local-fs ones may already be there. */
1488 unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET, NULL, true);
1492 if (u->load_state == UNIT_NOT_FOUND) {
1493 u->load_state = UNIT_LOADED;
1496 /* Load in the extras later on, after we
1497 * finished initialization of the unit */
1504 o = strdup(options);
1506 if (!w || !o || !f) {
1511 p = &MOUNT(u)->parameters_proc_self_mountinfo;
1513 changed = changed ||
1514 !streq_ptr(p->options, options) ||
1515 !streq_ptr(p->what, what) ||
1516 !streq_ptr(p->fstype, fstype);
1519 MOUNT(u)->is_mounted = true;
1520 MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
1521 MOUNT(u)->just_changed = changed;
1524 MOUNT(u)->from_proc_self_mountinfo = true;
1539 r = mount_add_extras(MOUNT(u));
1545 unit_add_to_dbus_queue(u);
1550 log_warning_errno(r, "Failed to set up mount unit: %m");
1558 static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
1559 _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
1560 _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
1565 t = mnt_new_table();
1569 i = mnt_new_iter(MNT_ITER_FORWARD);
1573 r = mnt_table_parse_mtab(t, NULL);
1575 return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
1579 const char *device, *path, *options, *fstype;
1580 _cleanup_free_ const char *d = NULL, *p = NULL;
1581 struct libmnt_fs *fs;
1584 k = mnt_table_next_fs(t, i, &fs);
1588 return log_error_errno(k, "Failed to get next entry from /proc/self/mountinfo: %m");
1590 device = mnt_fs_get_source(fs);
1591 path = mnt_fs_get_target(fs);
1592 options = mnt_fs_get_options(fs);
1593 fstype = mnt_fs_get_fstype(fs);
1595 d = cunescape(device);
1599 p = cunescape(path);
1603 (void) device_found_node(m, d, true, DEVICE_FOUND_MOUNT, set_flags);
1605 k = mount_setup_unit(m, d, p, options, fstype, set_flags);
1606 if (r == 0 && k < 0)
1613 static void mount_shutdown(Manager *m) {
1616 m->mount_event_source = sd_event_source_unref(m->mount_event_source);
1617 m->mount_utab_event_source = sd_event_source_unref(m->mount_utab_event_source);
1619 if (m->proc_self_mountinfo) {
1620 fclose(m->proc_self_mountinfo);
1621 m->proc_self_mountinfo = NULL;
1623 m->utab_inotify_fd = safe_close(m->utab_inotify_fd);
1626 static int mount_get_timeout(Unit *u, uint64_t *timeout) {
1627 Mount *m = MOUNT(u);
1630 if (!m->timer_event_source)
1633 r = sd_event_source_get_time(m->timer_event_source, timeout);
1640 static int mount_enumerate(Manager *m) {
1646 if (!m->proc_self_mountinfo) {
1647 m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
1648 if (!m->proc_self_mountinfo)
1651 r = sd_event_add_io(m->event, &m->mount_event_source, fileno(m->proc_self_mountinfo), EPOLLPRI, mount_dispatch_io, m);
1655 /* Dispatch this before we dispatch SIGCHLD, so that
1656 * we always get the events from /proc/self/mountinfo
1657 * before the SIGCHLD of /bin/mount. */
1658 r = sd_event_source_set_priority(m->mount_event_source, -10);
1663 if (m->utab_inotify_fd < 0) {
1664 m->utab_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
1665 if (m->utab_inotify_fd < 0) {
1670 (void) mkdir_p_label("/run/mount", 0755);
1672 r = inotify_add_watch(m->utab_inotify_fd, "/run/mount", IN_MOVED_TO);
1678 r = sd_event_add_io(m->event, &m->mount_utab_event_source, m->utab_inotify_fd, EPOLLIN, mount_dispatch_io, m);
1682 r = sd_event_source_set_priority(m->mount_utab_event_source, -10);
1687 r = mount_load_proc_self_mountinfo(m, false);
1698 static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1699 Manager *m = userdata;
1704 assert(revents & (EPOLLPRI | EPOLLIN));
1706 /* The manager calls this for every fd event happening on the
1707 * /proc/self/mountinfo file, which informs us about mounting
1708 * table changes, and for /run/mount events which we watch
1709 * for mount options. */
1711 if (fd == m->utab_inotify_fd) {
1712 bool rescan = false;
1714 /* FIXME: We *really* need to replace this with
1715 * libmount's own API for this, we should not hardcode
1716 * internal behaviour of libmount here. */
1719 union inotify_event_buffer buffer;
1720 struct inotify_event *e;
1723 l = read(fd, &buffer, sizeof(buffer));
1725 if (errno == EAGAIN || errno == EINTR)
1728 log_error_errno(errno, "Failed to read utab inotify: %m");
1732 FOREACH_INOTIFY_EVENT(e, buffer, l) {
1733 /* Only care about changes to utab,
1734 * but we have to monitor the
1735 * directory to reliably get
1736 * notifications about when utab is
1737 * replaced using rename(2) */
1738 if ((e->mask & IN_Q_OVERFLOW) || streq(e->name, "utab"))
1747 r = mount_load_proc_self_mountinfo(m, true);
1749 /* Reset flags, just in case, for later calls */
1750 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1751 Mount *mount = MOUNT(u);
1753 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1759 manager_dispatch_load_queue(m);
1761 LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
1762 Mount *mount = MOUNT(u);
1764 if (!mount->is_mounted) {
1766 mount->from_proc_self_mountinfo = false;
1768 switch (mount->state) {
1771 /* This has just been unmounted by
1772 * somebody else, follow the state
1774 mount_enter_dead(mount, MOUNT_SUCCESS);
1781 if (mount->parameters_proc_self_mountinfo.what)
1782 (void) device_found_node(m, mount->parameters_proc_self_mountinfo.what, false, DEVICE_FOUND_MOUNT, true);
1785 } else if (mount->just_mounted || mount->just_changed) {
1787 /* New or changed mount entry */
1789 switch (mount->state) {
1793 /* This has just been mounted by
1794 * somebody else, follow the state
1796 mount_enter_mounted(mount, MOUNT_SUCCESS);
1799 case MOUNT_MOUNTING:
1800 mount_set_state(mount, MOUNT_MOUNTING_DONE);
1804 /* Nothing really changed, but let's
1805 * issue an notification call
1806 * nonetheless, in case somebody is
1807 * waiting for this. (e.g. file system
1808 * ro/rw remounts.) */
1809 mount_set_state(mount, mount->state);
1814 /* Reset the flags for later calls */
1815 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1821 static void mount_reset_failed(Unit *u) {
1822 Mount *m = MOUNT(u);
1826 if (m->state == MOUNT_FAILED)
1827 mount_set_state(m, MOUNT_DEAD);
1829 m->result = MOUNT_SUCCESS;
1830 m->reload_result = MOUNT_SUCCESS;
1833 static int mount_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1834 return unit_kill_common(u, who, signo, -1, MOUNT(u)->control_pid, error);
1837 static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
1838 [MOUNT_DEAD] = "dead",
1839 [MOUNT_MOUNTING] = "mounting",
1840 [MOUNT_MOUNTING_DONE] = "mounting-done",
1841 [MOUNT_MOUNTED] = "mounted",
1842 [MOUNT_REMOUNTING] = "remounting",
1843 [MOUNT_UNMOUNTING] = "unmounting",
1844 [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm",
1845 [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill",
1846 [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
1847 [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
1848 [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
1849 [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
1850 [MOUNT_FAILED] = "failed"
1853 DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
1855 static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
1856 [MOUNT_EXEC_MOUNT] = "ExecMount",
1857 [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
1858 [MOUNT_EXEC_REMOUNT] = "ExecRemount",
1861 DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
1863 static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
1864 [MOUNT_SUCCESS] = "success",
1865 [MOUNT_FAILURE_RESOURCES] = "resources",
1866 [MOUNT_FAILURE_TIMEOUT] = "timeout",
1867 [MOUNT_FAILURE_EXIT_CODE] = "exit-code",
1868 [MOUNT_FAILURE_SIGNAL] = "signal",
1869 [MOUNT_FAILURE_CORE_DUMP] = "core-dump"
1872 DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
1874 const UnitVTable mount_vtable = {
1875 .object_size = sizeof(Mount),
1876 .exec_context_offset = offsetof(Mount, exec_context),
1877 .cgroup_context_offset = offsetof(Mount, cgroup_context),
1878 .kill_context_offset = offsetof(Mount, kill_context),
1879 .exec_runtime_offset = offsetof(Mount, exec_runtime),
1885 .private_section = "Mount",
1888 .no_instances = true,
1894 .coldplug = mount_coldplug,
1898 .start = mount_start,
1900 .reload = mount_reload,
1904 .serialize = mount_serialize,
1905 .deserialize_item = mount_deserialize_item,
1907 .active_state = mount_active_state,
1908 .sub_state_to_string = mount_sub_state_to_string,
1910 .check_gc = mount_check_gc,
1912 .sigchld_event = mount_sigchld_event,
1914 .reset_failed = mount_reset_failed,
1916 .bus_interface = "org.freedesktop.systemd1.Mount",
1917 .bus_vtable = bus_mount_vtable,
1918 .bus_set_property = bus_mount_set_property,
1919 .bus_commit_properties = bus_mount_commit_properties,
1921 .get_timeout = mount_get_timeout,
1923 .can_transient = true,
1925 .enumerate = mount_enumerate,
1926 .shutdown = mount_shutdown,
1928 .status_message_formats = {
1929 .starting_stopping = {
1930 [0] = "Mounting %s...",
1931 [1] = "Unmounting %s...",
1933 .finished_start_job = {
1934 [JOB_DONE] = "Mounted %s.",
1935 [JOB_FAILED] = "Failed to mount %s.",
1936 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1937 [JOB_TIMEOUT] = "Timed out mounting %s.",
1939 .finished_stop_job = {
1940 [JOB_DONE] = "Unmounted %s.",
1941 [JOB_FAILED] = "Failed unmounting %s.",
1942 [JOB_TIMEOUT] = "Timed out unmounting %s.",