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 /* Quotas are not enabled on network filesystems,
106 * but we want them, for example, on storage connected via iscsi */
107 if (p->fstype && fstype_is_network(p->fstype))
110 if (mount_is_bind(p))
113 return fstab_test_option(p->options,
114 "usrquota\0" "grpquota\0" "quota\0" "usrjquota\0" "grpjquota\0");
117 static void mount_init(Unit *u) {
121 assert(u->load_state == UNIT_STUB);
123 m->timeout_usec = u->manager->default_timeout_start_usec;
124 m->directory_mode = 0755;
126 if (unit_has_name(u, "-.mount")) {
127 /* Don't allow start/stop for root directory */
128 u->refuse_manual_start = true;
129 u->refuse_manual_stop = true;
131 /* The stdio/kmsg bridge socket is on /, in order to avoid a
132 * dep loop, don't use kmsg logging for -.mount */
133 m->exec_context.std_output = u->manager->default_std_output;
134 m->exec_context.std_error = u->manager->default_std_error;
137 /* We need to make sure that /bin/mount is always called in
138 * the same process group as us, so that the autofs kernel
139 * side doesn't send us another mount request while we are
140 * already trying to comply its last one. */
141 m->exec_context.same_pgrp = true;
143 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
145 u->ignore_on_isolate = true;
148 static int mount_arm_timer(Mount *m) {
153 if (m->timeout_usec <= 0) {
154 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
158 if (m->timer_event_source) {
159 r = sd_event_source_set_time(m->timer_event_source, now(CLOCK_MONOTONIC) + m->timeout_usec);
163 return sd_event_source_set_enabled(m->timer_event_source, SD_EVENT_ONESHOT);
166 return sd_event_add_time(
167 UNIT(m)->manager->event,
168 &m->timer_event_source,
170 now(CLOCK_MONOTONIC) + m->timeout_usec, 0,
171 mount_dispatch_timer, m);
174 static void mount_unwatch_control_pid(Mount *m) {
177 if (m->control_pid <= 0)
180 unit_unwatch_pid(UNIT(m), m->control_pid);
184 static void mount_parameters_done(MountParameters *p) {
191 p->what = p->options = p->fstype = NULL;
194 static void mount_done(Unit *u) {
202 mount_parameters_done(&m->parameters_proc_self_mountinfo);
203 mount_parameters_done(&m->parameters_fragment);
205 m->exec_runtime = exec_runtime_unref(m->exec_runtime);
206 exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
207 m->control_command = NULL;
209 mount_unwatch_control_pid(m);
211 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
214 _pure_ static MountParameters* get_mount_parameters_fragment(Mount *m) {
217 if (m->from_fragment)
218 return &m->parameters_fragment;
223 _pure_ static MountParameters* get_mount_parameters(Mount *m) {
226 if (m->from_proc_self_mountinfo)
227 return &m->parameters_proc_self_mountinfo;
229 return get_mount_parameters_fragment(m);
232 static int mount_add_mount_links(Mount *m) {
233 _cleanup_free_ char *parent = NULL;
242 if (!path_equal(m->where, "/")) {
243 /* Adds in links to other mount points that might lie further
244 * up in the hierarchy */
245 r = path_get_parent(m->where, &parent);
249 r = unit_require_mounts_for(UNIT(m), parent);
254 /* Adds in links to other mount points that might be needed
255 * for the source path (if this is a bind mount) to be
257 pm = get_mount_parameters_fragment(m);
258 if (pm && pm->what &&
259 path_is_absolute(pm->what) &&
260 !mount_is_network(pm)) {
262 r = unit_require_mounts_for(UNIT(m), pm->what);
267 /* Adds in links to other units that use this path or paths
268 * further down in the hierarchy */
269 s = manager_get_units_requiring_mounts_for(UNIT(m)->manager, m->where);
270 SET_FOREACH(other, s, i) {
272 if (other->load_state != UNIT_LOADED)
275 if (other == UNIT(m))
278 r = unit_add_dependency(other, UNIT_AFTER, UNIT(m), true);
282 if (UNIT(m)->fragment_path) {
283 /* If we have fragment configuration, then make this dependency required */
284 r = unit_add_dependency(other, UNIT_REQUIRES, UNIT(m), true);
293 static int mount_add_device_links(Mount *m) {
295 bool device_wants_mount = false;
300 p = get_mount_parameters(m);
307 if (mount_is_bind(p))
310 if (!is_device_path(p->what))
313 if (path_equal(m->where, "/"))
316 if (mount_is_auto(p) && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
317 device_wants_mount = true;
319 r = unit_add_node_link(UNIT(m), p->what, device_wants_mount);
326 static int mount_add_quota_links(Mount *m) {
332 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
335 p = get_mount_parameters_fragment(m);
342 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTACHECK_SERVICE, NULL, true);
346 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_WANTS, SPECIAL_QUOTAON_SERVICE, NULL, true);
353 static bool should_umount(Mount *m) {
356 if (path_equal(m->where, "/") ||
357 path_equal(m->where, "/usr"))
360 p = get_mount_parameters(m);
361 if (p && fstab_test_option(p->options, "x-initrd.mount\0") &&
368 static int mount_add_default_dependencies(Mount *m) {
369 const char *after, *after2, *online;
375 if (UNIT(m)->manager->running_as != SYSTEMD_SYSTEM)
378 /* We do not add any default dependencies to / and /usr, since
379 * they are guaranteed to stay mounted the whole time, since
380 * our system is on it. Also, don't bother with anything
381 * mounted below virtual file systems, it's also going to be
382 * virtual, and hence not worth the effort. */
383 if (path_equal(m->where, "/") ||
384 path_equal(m->where, "/usr") ||
385 path_startswith(m->where, "/proc") ||
386 path_startswith(m->where, "/sys") ||
387 path_startswith(m->where, "/dev"))
390 p = get_mount_parameters(m);
394 if (mount_is_network(p)) {
395 after = SPECIAL_REMOTE_FS_PRE_TARGET;
396 after2 = SPECIAL_NETWORK_TARGET;
397 online = SPECIAL_NETWORK_ONLINE_TARGET;
399 after = SPECIAL_LOCAL_FS_PRE_TARGET;
404 r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after, NULL, true);
409 r = unit_add_dependency_by_name(UNIT(m), UNIT_AFTER, after2, NULL, true);
415 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_WANTS, UNIT_AFTER, online, NULL, true);
420 if (should_umount(m)) {
421 r = unit_add_two_dependencies_by_name(UNIT(m), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
429 static int mount_verify(Mount *m) {
430 _cleanup_free_ char *e = NULL;
435 if (UNIT(m)->load_state != UNIT_LOADED)
438 if (!m->from_fragment && !m->from_proc_self_mountinfo)
441 e = unit_name_from_path(m->where, ".mount");
445 b = unit_has_name(UNIT(m), e);
447 log_unit_error(UNIT(m)->id, "%s's Where= setting doesn't match unit name. Refusing.", UNIT(m)->id);
451 if (mount_point_is_api(m->where) || mount_point_ignore(m->where)) {
452 log_unit_error(UNIT(m)->id, "Cannot create mount unit for API file system %s. Refusing.", m->where);
456 if (UNIT(m)->fragment_path && !m->parameters_fragment.what) {
457 log_unit_error(UNIT(m)->id, "%s's What setting is missing. Refusing.", UNIT(m)->id);
461 if (m->exec_context.pam_name && m->kill_context.kill_mode != KILL_CONTROL_GROUP) {
462 log_unit_error(UNIT(m)->id, "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.",UNIT(m)->id);
469 static int mount_add_extras(Mount *m) {
475 if (u->fragment_path)
476 m->from_fragment = true;
479 m->where = unit_name_to_path(u->id);
484 path_kill_slashes(m->where);
486 if (!u->description) {
487 r = unit_set_description(u, m->where);
492 r = mount_add_device_links(m);
496 r = mount_add_mount_links(m);
500 r = mount_add_quota_links(m);
504 r = unit_patch_contexts(u);
508 r = unit_add_exec_dependencies(u, &m->exec_context);
512 r = unit_add_default_slice(u, &m->cgroup_context);
516 if (u->default_dependencies) {
517 r = mount_add_default_dependencies(m);
525 static int mount_load(Unit *u) {
530 assert(u->load_state == UNIT_STUB);
532 if (m->from_proc_self_mountinfo)
533 r = unit_load_fragment_and_dropin_optional(u);
535 r = unit_load_fragment_and_dropin(u);
540 /* This is a new unit? Then let's add in some extras */
541 if (u->load_state == UNIT_LOADED) {
542 r = mount_add_extras(m);
547 return mount_verify(m);
550 static int mount_notify_automount(Mount *m, int status) {
557 SET_FOREACH(p, UNIT(m)->dependencies[UNIT_TRIGGERED_BY], i)
558 if (p->type == UNIT_AUTOMOUNT) {
559 r = automount_send_ready(AUTOMOUNT(p), status);
567 static void mount_set_state(Mount *m, MountState state) {
568 MountState old_state;
571 old_state = m->state;
574 if (state != MOUNT_MOUNTING &&
575 state != MOUNT_MOUNTING_DONE &&
576 state != MOUNT_REMOUNTING &&
577 state != MOUNT_UNMOUNTING &&
578 state != MOUNT_MOUNTING_SIGTERM &&
579 state != MOUNT_MOUNTING_SIGKILL &&
580 state != MOUNT_UNMOUNTING_SIGTERM &&
581 state != MOUNT_UNMOUNTING_SIGKILL &&
582 state != MOUNT_REMOUNTING_SIGTERM &&
583 state != MOUNT_REMOUNTING_SIGKILL) {
584 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
585 mount_unwatch_control_pid(m);
586 m->control_command = NULL;
587 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
590 if (state == MOUNT_MOUNTED ||
591 state == MOUNT_REMOUNTING)
592 mount_notify_automount(m, 0);
593 else if (state == MOUNT_DEAD ||
594 state == MOUNT_UNMOUNTING ||
595 state == MOUNT_MOUNTING_SIGTERM ||
596 state == MOUNT_MOUNTING_SIGKILL ||
597 state == MOUNT_REMOUNTING_SIGTERM ||
598 state == MOUNT_REMOUNTING_SIGKILL ||
599 state == MOUNT_UNMOUNTING_SIGTERM ||
600 state == MOUNT_UNMOUNTING_SIGKILL ||
601 state == MOUNT_FAILED) {
602 if (state != old_state)
603 mount_notify_automount(m, -ENODEV);
606 if (state != old_state)
607 log_unit_debug(UNIT(m)->id,
608 "%s changed %s -> %s",
610 mount_state_to_string(old_state),
611 mount_state_to_string(state));
613 unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state], m->reload_result == MOUNT_SUCCESS);
614 m->reload_result = MOUNT_SUCCESS;
617 static int mount_coldplug(Unit *u, Hashmap *deferred_work) {
619 MountState new_state = MOUNT_DEAD;
623 assert(m->state == MOUNT_DEAD);
625 if (m->deserialized_state != m->state)
626 new_state = m->deserialized_state;
627 else if (m->from_proc_self_mountinfo)
628 new_state = MOUNT_MOUNTED;
630 if (new_state == m->state)
633 if (new_state == MOUNT_MOUNTING ||
634 new_state == MOUNT_MOUNTING_DONE ||
635 new_state == MOUNT_REMOUNTING ||
636 new_state == MOUNT_UNMOUNTING ||
637 new_state == MOUNT_MOUNTING_SIGTERM ||
638 new_state == MOUNT_MOUNTING_SIGKILL ||
639 new_state == MOUNT_UNMOUNTING_SIGTERM ||
640 new_state == MOUNT_UNMOUNTING_SIGKILL ||
641 new_state == MOUNT_REMOUNTING_SIGTERM ||
642 new_state == MOUNT_REMOUNTING_SIGKILL) {
644 if (m->control_pid <= 0)
647 r = unit_watch_pid(UNIT(m), m->control_pid);
651 r = mount_arm_timer(m);
656 mount_set_state(m, new_state);
660 static void mount_dump(Unit *u, FILE *f, const char *prefix) {
667 p = get_mount_parameters(m);
670 "%sMount State: %s\n"
674 "%sFile System Type: %s\n"
676 "%sFrom /proc/self/mountinfo: %s\n"
677 "%sFrom fragment: %s\n"
678 "%sDirectoryMode: %04o\n",
679 prefix, mount_state_to_string(m->state),
680 prefix, mount_result_to_string(m->result),
682 prefix, p ? strna(p->what) : "n/a",
683 prefix, p ? strna(p->fstype) : "n/a",
684 prefix, p ? strna(p->options) : "n/a",
685 prefix, yes_no(m->from_proc_self_mountinfo),
686 prefix, yes_no(m->from_fragment),
687 prefix, m->directory_mode);
689 if (m->control_pid > 0)
691 "%sControl PID: "PID_FMT"\n",
692 prefix, m->control_pid);
694 exec_context_dump(&m->exec_context, f, prefix);
695 kill_context_dump(&m->kill_context, f, prefix);
698 static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
701 ExecParameters exec_params = {
702 .apply_permissions = true,
703 .apply_chroot = true,
704 .apply_tty_stdin = true,
711 (void) unit_realize_cgroup(UNIT(m));
712 if (m->reset_cpu_usage) {
713 (void) unit_reset_cpu_usage(UNIT(m));
714 m->reset_cpu_usage = false;
717 r = unit_setup_exec_runtime(UNIT(m));
721 r = mount_arm_timer(m);
725 exec_params.environment = UNIT(m)->manager->environment;
726 exec_params.confirm_spawn = UNIT(m)->manager->confirm_spawn;
727 exec_params.cgroup_supported = UNIT(m)->manager->cgroup_supported;
728 exec_params.cgroup_path = UNIT(m)->cgroup_path;
729 exec_params.cgroup_delegate = m->cgroup_context.delegate;
730 exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(m)->manager);
731 exec_params.unit_id = UNIT(m)->id;
741 r = unit_watch_pid(UNIT(m), pid);
743 /* FIXME: we need to do something here */
751 m->timer_event_source = sd_event_source_unref(m->timer_event_source);
756 static void mount_enter_dead(Mount *m, MountResult f) {
759 if (f != MOUNT_SUCCESS)
762 exec_runtime_destroy(m->exec_runtime);
763 m->exec_runtime = exec_runtime_unref(m->exec_runtime);
765 exec_context_destroy_runtime_directory(&m->exec_context, manager_get_runtime_prefix(UNIT(m)->manager));
767 mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
770 static void mount_enter_mounted(Mount *m, MountResult f) {
773 if (f != MOUNT_SUCCESS)
776 mount_set_state(m, MOUNT_MOUNTED);
779 static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
784 if (f != MOUNT_SUCCESS)
787 r = unit_kill_context(
790 (state != MOUNT_MOUNTING_SIGTERM && state != MOUNT_UNMOUNTING_SIGTERM && state != MOUNT_REMOUNTING_SIGTERM) ?
791 KILL_KILL : KILL_TERMINATE,
799 r = mount_arm_timer(m);
803 mount_set_state(m, state);
804 } else if (state == MOUNT_REMOUNTING_SIGTERM)
805 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_SUCCESS);
806 else if (state == MOUNT_REMOUNTING_SIGKILL)
807 mount_enter_mounted(m, MOUNT_SUCCESS);
808 else if (state == MOUNT_MOUNTING_SIGTERM)
809 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_SUCCESS);
810 else if (state == MOUNT_UNMOUNTING_SIGTERM)
811 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_SUCCESS);
813 mount_enter_dead(m, MOUNT_SUCCESS);
818 log_unit_warning(UNIT(m)->id,
819 "%s failed to kill processes: %s", UNIT(m)->id, strerror(-r));
821 if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
822 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
824 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
827 void warn_if_dir_nonempty(const char *unit, const char* where) {
833 r = dir_is_empty(where);
837 log_unit_struct(unit,
839 LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
840 LOG_MESSAGE("%s: Directory %s to mount over is not empty, mounting anyway.",
845 log_unit_warning(unit,
846 "MESSAGE=Failed to check directory %s: %s",
847 where, strerror(-r));
850 static int fail_if_symlink(const char *unit, const char* where) {
853 if (is_symlink(where) > 0) {
854 log_unit_struct(unit,
856 LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING),
857 LOG_MESSAGE("%s: Mount on symlink %s not allowed.",
867 static void mount_enter_unmounting(Mount *m) {
872 /* Start counting our attempts */
873 if (!IN_SET(m->state,
875 MOUNT_UNMOUNTING_SIGTERM,
876 MOUNT_UNMOUNTING_SIGKILL))
877 m->n_retry_umount = 0;
879 m->control_command_id = MOUNT_EXEC_UNMOUNT;
880 m->control_command = m->exec_command + MOUNT_EXEC_UNMOUNT;
882 r = exec_command_set(m->control_command, "/bin/umount", m->where, NULL);
883 if (r >= 0 && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
884 r = exec_command_append(m->control_command, "-n", NULL);
888 mount_unwatch_control_pid(m);
890 r = mount_spawn(m, m->control_command, &m->control_pid);
894 mount_set_state(m, MOUNT_UNMOUNTING);
899 log_unit_warning(UNIT(m)->id,
900 "%s failed to run 'umount' task: %s",
901 UNIT(m)->id, strerror(-r));
902 mount_enter_mounted(m, MOUNT_FAILURE_RESOURCES);
905 static void mount_enter_mounting(Mount *m) {
911 m->control_command_id = MOUNT_EXEC_MOUNT;
912 m->control_command = m->exec_command + MOUNT_EXEC_MOUNT;
914 mkdir_p_label(m->where, m->directory_mode);
916 warn_if_dir_nonempty(m->meta.id, m->where);
918 /* Create the source directory for bind-mounts if needed */
919 p = get_mount_parameters_fragment(m);
920 if (p && mount_is_bind(p))
921 mkdir_p_label(p->what, m->directory_mode);
923 r = fail_if_symlink(m->meta.id, m->where);
927 if (m->from_fragment) {
928 _cleanup_free_ char *opts = NULL;
930 r = fstab_filter_options(m->parameters_fragment.options,
931 "nofail\0" "noauto\0" "auto\0", NULL, NULL, &opts);
935 r = exec_command_set(m->control_command, "/bin/mount",
936 m->parameters_fragment.what, m->where, NULL);
937 if (r >= 0 && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
938 r = exec_command_append(m->control_command, "-n", NULL);
939 if (r >= 0 && m->sloppy_options)
940 r = exec_command_append(m->control_command, "-s", NULL);
941 if (r >= 0 && m->parameters_fragment.fstype)
942 r = exec_command_append(m->control_command, "-t", m->parameters_fragment.fstype, NULL);
943 if (r >= 0 && !isempty(opts))
944 r = exec_command_append(m->control_command, "-o", opts, NULL);
951 mount_unwatch_control_pid(m);
953 r = mount_spawn(m, m->control_command, &m->control_pid);
957 mount_set_state(m, MOUNT_MOUNTING);
962 log_unit_warning(UNIT(m)->id,
963 "%s failed to run 'mount' task: %s",
964 UNIT(m)->id, strerror(-r));
965 mount_enter_dead(m, MOUNT_FAILURE_RESOURCES);
968 static void mount_enter_remounting(Mount *m) {
973 m->control_command_id = MOUNT_EXEC_REMOUNT;
974 m->control_command = m->exec_command + MOUNT_EXEC_REMOUNT;
976 if (m->from_fragment) {
979 if (m->parameters_fragment.options)
980 o = strjoina("remount,", m->parameters_fragment.options);
984 r = exec_command_set(m->control_command, "/bin/mount",
985 m->parameters_fragment.what, m->where,
987 if (r >= 0 && UNIT(m)->manager->running_as == SYSTEMD_SYSTEM)
988 r = exec_command_append(m->control_command, "-n", NULL);
989 if (r >= 0 && m->sloppy_options)
990 r = exec_command_append(m->control_command, "-s", NULL);
991 if (r >= 0 && m->parameters_fragment.fstype)
992 r = exec_command_append(m->control_command, "-t", m->parameters_fragment.fstype, NULL);
999 mount_unwatch_control_pid(m);
1001 r = mount_spawn(m, m->control_command, &m->control_pid);
1005 mount_set_state(m, MOUNT_REMOUNTING);
1010 log_unit_warning(UNIT(m)->id,
1011 "%s failed to run 'remount' task: %s",
1012 UNIT(m)->id, strerror(-r));
1013 m->reload_result = MOUNT_FAILURE_RESOURCES;
1014 mount_enter_mounted(m, MOUNT_SUCCESS);
1017 static int mount_start(Unit *u) {
1018 Mount *m = MOUNT(u);
1022 /* We cannot fulfill this request right now, try again later
1024 if (m->state == MOUNT_UNMOUNTING ||
1025 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1026 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1027 m->state == MOUNT_MOUNTING_SIGTERM ||
1028 m->state == MOUNT_MOUNTING_SIGKILL)
1031 /* Already on it! */
1032 if (m->state == MOUNT_MOUNTING)
1035 assert(m->state == MOUNT_DEAD || m->state == MOUNT_FAILED);
1037 m->result = MOUNT_SUCCESS;
1038 m->reload_result = MOUNT_SUCCESS;
1039 m->reset_cpu_usage = true;
1041 mount_enter_mounting(m);
1045 static int mount_stop(Unit *u) {
1046 Mount *m = MOUNT(u);
1051 if (m->state == MOUNT_UNMOUNTING ||
1052 m->state == MOUNT_UNMOUNTING_SIGKILL ||
1053 m->state == MOUNT_UNMOUNTING_SIGTERM ||
1054 m->state == MOUNT_MOUNTING_SIGTERM ||
1055 m->state == MOUNT_MOUNTING_SIGKILL)
1058 assert(m->state == MOUNT_MOUNTING ||
1059 m->state == MOUNT_MOUNTING_DONE ||
1060 m->state == MOUNT_MOUNTED ||
1061 m->state == MOUNT_REMOUNTING ||
1062 m->state == MOUNT_REMOUNTING_SIGTERM ||
1063 m->state == MOUNT_REMOUNTING_SIGKILL);
1065 mount_enter_unmounting(m);
1069 static int mount_reload(Unit *u) {
1070 Mount *m = MOUNT(u);
1074 if (m->state == MOUNT_MOUNTING_DONE)
1077 assert(m->state == MOUNT_MOUNTED);
1079 mount_enter_remounting(m);
1083 static int mount_serialize(Unit *u, FILE *f, FDSet *fds) {
1084 Mount *m = MOUNT(u);
1090 unit_serialize_item(u, f, "state", mount_state_to_string(m->state));
1091 unit_serialize_item(u, f, "result", mount_result_to_string(m->result));
1092 unit_serialize_item(u, f, "reload-result", mount_result_to_string(m->reload_result));
1094 if (m->control_pid > 0)
1095 unit_serialize_item_format(u, f, "control-pid", PID_FMT, m->control_pid);
1097 if (m->control_command_id >= 0)
1098 unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(m->control_command_id));
1103 static int mount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1104 Mount *m = MOUNT(u);
1111 if (streq(key, "state")) {
1114 if ((state = mount_state_from_string(value)) < 0)
1115 log_unit_debug(u->id, "Failed to parse state value %s", value);
1117 m->deserialized_state = state;
1118 } else if (streq(key, "result")) {
1121 f = mount_result_from_string(value);
1123 log_unit_debug(UNIT(m)->id,
1124 "Failed to parse result value %s", value);
1125 else if (f != MOUNT_SUCCESS)
1128 } else if (streq(key, "reload-result")) {
1131 f = mount_result_from_string(value);
1133 log_unit_debug(UNIT(m)->id,
1134 "Failed to parse reload result value %s", value);
1135 else if (f != MOUNT_SUCCESS)
1136 m->reload_result = f;
1138 } else if (streq(key, "control-pid")) {
1141 if (parse_pid(value, &pid) < 0)
1142 log_unit_debug(UNIT(m)->id,
1143 "Failed to parse control-pid value %s", value);
1145 m->control_pid = pid;
1146 } else if (streq(key, "control-command")) {
1147 MountExecCommand id;
1149 if ((id = mount_exec_command_from_string(value)) < 0)
1150 log_unit_debug(UNIT(m)->id,
1151 "Failed to parse exec-command value %s", value);
1153 m->control_command_id = id;
1154 m->control_command = m->exec_command + id;
1157 log_unit_debug(UNIT(m)->id,
1158 "Unknown serialization key '%s'", key);
1163 _pure_ static UnitActiveState mount_active_state(Unit *u) {
1166 return state_translation_table[MOUNT(u)->state];
1169 _pure_ static const char *mount_sub_state_to_string(Unit *u) {
1172 return mount_state_to_string(MOUNT(u)->state);
1175 _pure_ static bool mount_check_gc(Unit *u) {
1176 Mount *m = MOUNT(u);
1180 return m->from_proc_self_mountinfo;
1183 static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
1184 Mount *m = MOUNT(u);
1190 if (pid != m->control_pid)
1195 if (is_clean_exit(code, status, NULL))
1197 else if (code == CLD_EXITED)
1198 f = MOUNT_FAILURE_EXIT_CODE;
1199 else if (code == CLD_KILLED)
1200 f = MOUNT_FAILURE_SIGNAL;
1201 else if (code == CLD_DUMPED)
1202 f = MOUNT_FAILURE_CORE_DUMP;
1204 assert_not_reached("Unknown code");
1206 if (f != MOUNT_SUCCESS)
1209 if (m->control_command) {
1210 exec_status_exit(&m->control_command->exec_status, &m->exec_context, pid, code, status);
1212 m->control_command = NULL;
1213 m->control_command_id = _MOUNT_EXEC_COMMAND_INVALID;
1216 log_unit_full(u->id,
1217 f == MOUNT_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
1218 "%s mount process exited, code=%s status=%i",
1219 u->id, sigchld_code_to_string(code), status);
1221 /* Note that mount(8) returning and the kernel sending us a
1222 * mount table change event might happen out-of-order. If an
1223 * operation succeed we assume the kernel will follow soon too
1224 * and already change into the resulting state. If it fails
1225 * we check if the kernel still knows about the mount. and
1226 * change state accordingly. */
1230 case MOUNT_MOUNTING:
1231 case MOUNT_MOUNTING_DONE:
1232 case MOUNT_MOUNTING_SIGKILL:
1233 case MOUNT_MOUNTING_SIGTERM:
1235 if (f == MOUNT_SUCCESS)
1236 mount_enter_mounted(m, f);
1237 else if (m->from_proc_self_mountinfo)
1238 mount_enter_mounted(m, f);
1240 mount_enter_dead(m, f);
1243 case MOUNT_REMOUNTING:
1244 case MOUNT_REMOUNTING_SIGKILL:
1245 case MOUNT_REMOUNTING_SIGTERM:
1247 m->reload_result = f;
1248 if (m->from_proc_self_mountinfo)
1249 mount_enter_mounted(m, MOUNT_SUCCESS);
1251 mount_enter_dead(m, MOUNT_SUCCESS);
1255 case MOUNT_UNMOUNTING:
1256 case MOUNT_UNMOUNTING_SIGKILL:
1257 case MOUNT_UNMOUNTING_SIGTERM:
1259 if (f == MOUNT_SUCCESS) {
1261 if (m->from_proc_self_mountinfo) {
1263 /* Still a mount point? If so, let's
1264 * try again. Most likely there were
1265 * multiple mount points stacked on
1266 * top of each other. Note that due to
1267 * the io event priority logic we can
1268 * be sure the new mountinfo is loaded
1269 * before we process the SIGCHLD for
1270 * the mount command. */
1272 if (m->n_retry_umount < RETRY_UMOUNT_MAX) {
1273 log_unit_debug(u->id, "%s: mount still present, trying again.", u->id);
1274 m->n_retry_umount++;
1275 mount_enter_unmounting(m);
1277 log_unit_debug(u->id, "%s: mount still present after %u attempts to unmount, giving up.", u->id, m->n_retry_umount);
1278 mount_enter_mounted(m, f);
1281 mount_enter_dead(m, f);
1283 } else if (m->from_proc_self_mountinfo)
1284 mount_enter_mounted(m, f);
1286 mount_enter_dead(m, f);
1290 assert_not_reached("Uh, control process died at wrong time.");
1293 /* Notify clients about changed exit status */
1294 unit_add_to_dbus_queue(u);
1297 static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
1298 Mount *m = MOUNT(userdata);
1301 assert(m->timer_event_source == source);
1305 case MOUNT_MOUNTING:
1306 case MOUNT_MOUNTING_DONE:
1307 log_unit_warning(UNIT(m)->id,
1308 "%s mounting timed out. Stopping.", UNIT(m)->id);
1309 mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1312 case MOUNT_REMOUNTING:
1313 log_unit_warning(UNIT(m)->id,
1314 "%s remounting timed out. Stopping.", UNIT(m)->id);
1315 m->reload_result = MOUNT_FAILURE_TIMEOUT;
1316 mount_enter_mounted(m, MOUNT_SUCCESS);
1319 case MOUNT_UNMOUNTING:
1320 log_unit_warning(UNIT(m)->id,
1321 "%s unmounting timed out. Stopping.", UNIT(m)->id);
1322 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, MOUNT_FAILURE_TIMEOUT);
1325 case MOUNT_MOUNTING_SIGTERM:
1326 if (m->kill_context.send_sigkill) {
1327 log_unit_warning(UNIT(m)->id,
1328 "%s mounting timed out. Killing.", UNIT(m)->id);
1329 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1331 log_unit_warning(UNIT(m)->id,
1332 "%s mounting timed out. Skipping SIGKILL. Ignoring.",
1335 if (m->from_proc_self_mountinfo)
1336 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1338 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1342 case MOUNT_REMOUNTING_SIGTERM:
1343 if (m->kill_context.send_sigkill) {
1344 log_unit_warning(UNIT(m)->id,
1345 "%s remounting timed out. Killing.", UNIT(m)->id);
1346 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1348 log_unit_warning(UNIT(m)->id,
1349 "%s remounting timed out. Skipping SIGKILL. Ignoring.",
1352 if (m->from_proc_self_mountinfo)
1353 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1355 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1359 case MOUNT_UNMOUNTING_SIGTERM:
1360 if (m->kill_context.send_sigkill) {
1361 log_unit_warning(UNIT(m)->id,
1362 "%s unmounting timed out. Killing.", UNIT(m)->id);
1363 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_FAILURE_TIMEOUT);
1365 log_unit_warning(UNIT(m)->id,
1366 "%s unmounting timed out. Skipping SIGKILL. Ignoring.",
1369 if (m->from_proc_self_mountinfo)
1370 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1372 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1376 case MOUNT_MOUNTING_SIGKILL:
1377 case MOUNT_REMOUNTING_SIGKILL:
1378 case MOUNT_UNMOUNTING_SIGKILL:
1379 log_unit_warning(UNIT(m)->id,
1380 "%s mount process still around after SIGKILL. Ignoring.",
1383 if (m->from_proc_self_mountinfo)
1384 mount_enter_mounted(m, MOUNT_FAILURE_TIMEOUT);
1386 mount_enter_dead(m, MOUNT_FAILURE_TIMEOUT);
1390 assert_not_reached("Timeout at wrong time.");
1396 static int mount_setup_unit(
1400 const char *options,
1404 _cleanup_free_ char *e = NULL, *w = NULL, *o = NULL, *f = NULL;
1405 bool load_extras = false;
1407 bool delete, changed = false;
1417 /* Ignore API mount points. They should never be referenced in
1418 * dependencies ever. */
1419 if (mount_point_is_api(where) || mount_point_ignore(where))
1422 if (streq(fstype, "autofs"))
1425 /* probably some kind of swap, ignore */
1426 if (!is_path(where))
1429 e = unit_name_from_path(where, ".mount");
1433 u = manager_get_unit(m, e);
1437 u = unit_new(m, sizeof(Mount));
1441 r = unit_add_name(u, e);
1445 MOUNT(u)->where = strdup(where);
1446 if (!MOUNT(u)->where) {
1451 u->source_path = strdup("/proc/self/mountinfo");
1452 if (!u->source_path) {
1457 if (m->running_as == SYSTEMD_SYSTEM) {
1460 target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET;
1461 r = unit_add_dependency_by_name(u, UNIT_BEFORE, target, NULL, true);
1465 if (should_umount(MOUNT(u))) {
1466 r = unit_add_dependency_by_name(u, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
1472 unit_add_to_load_queue(u);
1477 if (!MOUNT(u)->where) {
1478 MOUNT(u)->where = strdup(where);
1479 if (!MOUNT(u)->where) {
1485 if (m->running_as == SYSTEMD_SYSTEM &&
1486 mount_needs_network(options, fstype)) {
1487 /* _netdev option may have shown up late, or on a
1488 * remount. Add remote-fs dependencies, even though
1489 * local-fs ones may already be there. */
1490 unit_add_dependency_by_name(u, UNIT_BEFORE, SPECIAL_REMOTE_FS_TARGET, NULL, true);
1494 if (u->load_state == UNIT_NOT_FOUND) {
1495 u->load_state = UNIT_LOADED;
1498 /* Load in the extras later on, after we
1499 * finished initialization of the unit */
1506 o = strdup(options);
1508 if (!w || !o || !f) {
1513 p = &MOUNT(u)->parameters_proc_self_mountinfo;
1515 changed = changed ||
1516 !streq_ptr(p->options, options) ||
1517 !streq_ptr(p->what, what) ||
1518 !streq_ptr(p->fstype, fstype);
1521 MOUNT(u)->is_mounted = true;
1522 MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
1523 MOUNT(u)->just_changed = changed;
1526 MOUNT(u)->from_proc_self_mountinfo = true;
1541 r = mount_add_extras(MOUNT(u));
1547 unit_add_to_dbus_queue(u);
1552 log_warning_errno(r, "Failed to set up mount unit: %m");
1560 static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
1561 _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
1562 _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
1567 t = mnt_new_table();
1571 i = mnt_new_iter(MNT_ITER_FORWARD);
1575 r = mnt_table_parse_mtab(t, NULL);
1577 return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
1581 const char *device, *path, *options, *fstype;
1582 _cleanup_free_ const char *d = NULL, *p = NULL;
1583 struct libmnt_fs *fs;
1586 k = mnt_table_next_fs(t, i, &fs);
1590 return log_error_errno(k, "Failed to get next entry from /proc/self/mountinfo: %m");
1592 device = mnt_fs_get_source(fs);
1593 path = mnt_fs_get_target(fs);
1594 options = mnt_fs_get_options(fs);
1595 fstype = mnt_fs_get_fstype(fs);
1597 d = cunescape(device);
1601 p = cunescape(path);
1605 (void) device_found_node(m, d, true, DEVICE_FOUND_MOUNT, set_flags);
1607 k = mount_setup_unit(m, d, p, options, fstype, set_flags);
1608 if (r == 0 && k < 0)
1615 static void mount_shutdown(Manager *m) {
1618 m->mount_event_source = sd_event_source_unref(m->mount_event_source);
1619 m->mount_utab_event_source = sd_event_source_unref(m->mount_utab_event_source);
1621 if (m->proc_self_mountinfo) {
1622 fclose(m->proc_self_mountinfo);
1623 m->proc_self_mountinfo = NULL;
1625 m->utab_inotify_fd = safe_close(m->utab_inotify_fd);
1628 static int mount_get_timeout(Unit *u, uint64_t *timeout) {
1629 Mount *m = MOUNT(u);
1632 if (!m->timer_event_source)
1635 r = sd_event_source_get_time(m->timer_event_source, timeout);
1642 static int mount_enumerate(Manager *m) {
1648 if (!m->proc_self_mountinfo) {
1649 m->proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
1650 if (!m->proc_self_mountinfo)
1653 r = sd_event_add_io(m->event, &m->mount_event_source, fileno(m->proc_self_mountinfo), EPOLLPRI, mount_dispatch_io, m);
1657 /* Dispatch this before we dispatch SIGCHLD, so that
1658 * we always get the events from /proc/self/mountinfo
1659 * before the SIGCHLD of /bin/mount. */
1660 r = sd_event_source_set_priority(m->mount_event_source, -10);
1665 if (m->utab_inotify_fd < 0) {
1666 m->utab_inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC);
1667 if (m->utab_inotify_fd < 0) {
1672 (void) mkdir_p_label("/run/mount", 0755);
1674 r = inotify_add_watch(m->utab_inotify_fd, "/run/mount", IN_MOVED_TO);
1680 r = sd_event_add_io(m->event, &m->mount_utab_event_source, m->utab_inotify_fd, EPOLLIN, mount_dispatch_io, m);
1684 r = sd_event_source_set_priority(m->mount_utab_event_source, -10);
1689 r = mount_load_proc_self_mountinfo(m, false);
1700 static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
1701 Manager *m = userdata;
1706 assert(revents & (EPOLLPRI | EPOLLIN));
1708 /* The manager calls this for every fd event happening on the
1709 * /proc/self/mountinfo file, which informs us about mounting
1710 * table changes, and for /run/mount events which we watch
1711 * for mount options. */
1713 if (fd == m->utab_inotify_fd) {
1714 bool rescan = false;
1716 /* FIXME: We *really* need to replace this with
1717 * libmount's own API for this, we should not hardcode
1718 * internal behaviour of libmount here. */
1721 union inotify_event_buffer buffer;
1722 struct inotify_event *e;
1725 l = read(fd, &buffer, sizeof(buffer));
1727 if (errno == EAGAIN || errno == EINTR)
1730 log_error_errno(errno, "Failed to read utab inotify: %m");
1734 FOREACH_INOTIFY_EVENT(e, buffer, l) {
1735 /* Only care about changes to utab,
1736 * but we have to monitor the
1737 * directory to reliably get
1738 * notifications about when utab is
1739 * replaced using rename(2) */
1740 if ((e->mask & IN_Q_OVERFLOW) || streq(e->name, "utab"))
1749 r = mount_load_proc_self_mountinfo(m, true);
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) {
1768 mount->from_proc_self_mountinfo = false;
1770 switch (mount->state) {
1773 /* This has just been unmounted by
1774 * somebody else, follow the state
1776 mount_enter_dead(mount, MOUNT_SUCCESS);
1783 if (mount->parameters_proc_self_mountinfo.what)
1784 (void) device_found_node(m, mount->parameters_proc_self_mountinfo.what, false, DEVICE_FOUND_MOUNT, true);
1787 } else if (mount->just_mounted || mount->just_changed) {
1789 /* New or changed mount entry */
1791 switch (mount->state) {
1795 /* This has just been mounted by
1796 * somebody else, follow the state
1798 mount_enter_mounted(mount, MOUNT_SUCCESS);
1801 case MOUNT_MOUNTING:
1802 mount_set_state(mount, MOUNT_MOUNTING_DONE);
1806 /* Nothing really changed, but let's
1807 * issue an notification call
1808 * nonetheless, in case somebody is
1809 * waiting for this. (e.g. file system
1810 * ro/rw remounts.) */
1811 mount_set_state(mount, mount->state);
1816 /* Reset the flags for later calls */
1817 mount->is_mounted = mount->just_mounted = mount->just_changed = false;
1823 static void mount_reset_failed(Unit *u) {
1824 Mount *m = MOUNT(u);
1828 if (m->state == MOUNT_FAILED)
1829 mount_set_state(m, MOUNT_DEAD);
1831 m->result = MOUNT_SUCCESS;
1832 m->reload_result = MOUNT_SUCCESS;
1835 static int mount_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
1836 return unit_kill_common(u, who, signo, -1, MOUNT(u)->control_pid, error);
1839 static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
1840 [MOUNT_DEAD] = "dead",
1841 [MOUNT_MOUNTING] = "mounting",
1842 [MOUNT_MOUNTING_DONE] = "mounting-done",
1843 [MOUNT_MOUNTED] = "mounted",
1844 [MOUNT_REMOUNTING] = "remounting",
1845 [MOUNT_UNMOUNTING] = "unmounting",
1846 [MOUNT_MOUNTING_SIGTERM] = "mounting-sigterm",
1847 [MOUNT_MOUNTING_SIGKILL] = "mounting-sigkill",
1848 [MOUNT_REMOUNTING_SIGTERM] = "remounting-sigterm",
1849 [MOUNT_REMOUNTING_SIGKILL] = "remounting-sigkill",
1850 [MOUNT_UNMOUNTING_SIGTERM] = "unmounting-sigterm",
1851 [MOUNT_UNMOUNTING_SIGKILL] = "unmounting-sigkill",
1852 [MOUNT_FAILED] = "failed"
1855 DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
1857 static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
1858 [MOUNT_EXEC_MOUNT] = "ExecMount",
1859 [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
1860 [MOUNT_EXEC_REMOUNT] = "ExecRemount",
1863 DEFINE_STRING_TABLE_LOOKUP(mount_exec_command, MountExecCommand);
1865 static const char* const mount_result_table[_MOUNT_RESULT_MAX] = {
1866 [MOUNT_SUCCESS] = "success",
1867 [MOUNT_FAILURE_RESOURCES] = "resources",
1868 [MOUNT_FAILURE_TIMEOUT] = "timeout",
1869 [MOUNT_FAILURE_EXIT_CODE] = "exit-code",
1870 [MOUNT_FAILURE_SIGNAL] = "signal",
1871 [MOUNT_FAILURE_CORE_DUMP] = "core-dump"
1874 DEFINE_STRING_TABLE_LOOKUP(mount_result, MountResult);
1876 const UnitVTable mount_vtable = {
1877 .object_size = sizeof(Mount),
1878 .exec_context_offset = offsetof(Mount, exec_context),
1879 .cgroup_context_offset = offsetof(Mount, cgroup_context),
1880 .kill_context_offset = offsetof(Mount, kill_context),
1881 .exec_runtime_offset = offsetof(Mount, exec_runtime),
1887 .private_section = "Mount",
1890 .no_instances = true,
1896 .coldplug = mount_coldplug,
1900 .start = mount_start,
1902 .reload = mount_reload,
1906 .serialize = mount_serialize,
1907 .deserialize_item = mount_deserialize_item,
1909 .active_state = mount_active_state,
1910 .sub_state_to_string = mount_sub_state_to_string,
1912 .check_gc = mount_check_gc,
1914 .sigchld_event = mount_sigchld_event,
1916 .reset_failed = mount_reset_failed,
1918 .bus_interface = "org.freedesktop.systemd1.Mount",
1919 .bus_vtable = bus_mount_vtable,
1920 .bus_set_property = bus_mount_set_property,
1921 .bus_commit_properties = bus_mount_commit_properties,
1923 .get_timeout = mount_get_timeout,
1925 .can_transient = true,
1927 .enumerate = mount_enumerate,
1928 .shutdown = mount_shutdown,
1930 .status_message_formats = {
1931 .starting_stopping = {
1932 [0] = "Mounting %s...",
1933 [1] = "Unmounting %s...",
1935 .finished_start_job = {
1936 [JOB_DONE] = "Mounted %s.",
1937 [JOB_FAILED] = "Failed to mount %s.",
1938 [JOB_DEPENDENCY] = "Dependency failed for %s.",
1939 [JOB_TIMEOUT] = "Timed out mounting %s.",
1941 .finished_stop_job = {
1942 [JOB_DONE] = "Unmounted %s.",
1943 [JOB_FAILED] = "Failed unmounting %s.",
1944 [JOB_TIMEOUT] = "Timed out unmounting %s.",