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>
32 #include "load-fragment.h"
33 #include "load-dropin.h"
35 #include "sd-messages.h"
38 #include "path-util.h"
39 #include "mount-setup.h"
40 #include "unit-name.h"
41 #include "dbus-mount.h"
43 #include "bus-errors.h"
44 #include "exit-status.h"
47 static const UnitActiveState state_translation_table
[_MOUNT_STATE_MAX
] = {
48 [MOUNT_DEAD
] = UNIT_INACTIVE
,
49 [MOUNT_MOUNTING
] = UNIT_ACTIVATING
,
50 [MOUNT_MOUNTING_DONE
] = UNIT_ACTIVE
,
51 [MOUNT_MOUNTED
] = UNIT_ACTIVE
,
52 [MOUNT_REMOUNTING
] = UNIT_RELOADING
,
53 [MOUNT_UNMOUNTING
] = UNIT_DEACTIVATING
,
54 [MOUNT_MOUNTING_SIGTERM
] = UNIT_DEACTIVATING
,
55 [MOUNT_MOUNTING_SIGKILL
] = UNIT_DEACTIVATING
,
56 [MOUNT_REMOUNTING_SIGTERM
] = UNIT_RELOADING
,
57 [MOUNT_REMOUNTING_SIGKILL
] = UNIT_RELOADING
,
58 [MOUNT_UNMOUNTING_SIGTERM
] = UNIT_DEACTIVATING
,
59 [MOUNT_UNMOUNTING_SIGKILL
] = UNIT_DEACTIVATING
,
60 [MOUNT_FAILED
] = UNIT_FAILED
63 static int mount_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
64 static int mount_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
);
66 static bool mount_is_network(MountParameters
*p
) {
69 if (mount_test_option(p
->options
, "_netdev"))
72 if (p
->fstype
&& fstype_is_network(p
->fstype
))
78 static bool mount_is_bind(MountParameters
*p
) {
81 if (mount_test_option(p
->options
, "bind"))
84 if (p
->fstype
&& streq(p
->fstype
, "bind"))
87 if (mount_test_option(p
->options
, "rbind"))
90 if (p
->fstype
&& streq(p
->fstype
, "rbind"))
96 static bool mount_is_auto(MountParameters
*p
) {
99 return !mount_test_option(p
->options
, "noauto");
102 static bool needs_quota(MountParameters
*p
) {
105 if (mount_is_network(p
))
108 if (mount_is_bind(p
))
111 return mount_test_option(p
->options
, "usrquota") ||
112 mount_test_option(p
->options
, "grpquota") ||
113 mount_test_option(p
->options
, "quota") ||
114 mount_test_option(p
->options
, "usrjquota") ||
115 mount_test_option(p
->options
, "grpjquota");
118 static void mount_init(Unit
*u
) {
122 assert(u
->load_state
== UNIT_STUB
);
124 m
->timeout_usec
= u
->manager
->default_timeout_start_usec
;
125 m
->directory_mode
= 0755;
127 if (unit_has_name(u
, "-.mount")) {
128 /* Don't allow start/stop for root directory */
129 u
->refuse_manual_start
= true;
130 u
->refuse_manual_stop
= true;
132 /* The stdio/kmsg bridge socket is on /, in order to avoid a
133 * dep loop, don't use kmsg logging for -.mount */
134 m
->exec_context
.std_output
= u
->manager
->default_std_output
;
135 m
->exec_context
.std_error
= u
->manager
->default_std_error
;
138 /* We need to make sure that /bin/mount is always called in
139 * the same process group as us, so that the autofs kernel
140 * side doesn't send us another mount request while we are
141 * already trying to comply its last one. */
142 m
->exec_context
.same_pgrp
= true;
144 m
->control_command_id
= _MOUNT_EXEC_COMMAND_INVALID
;
146 u
->ignore_on_isolate
= true;
149 static int mount_arm_timer(Mount
*m
) {
154 if (m
->timeout_usec
<= 0) {
155 m
->timer_event_source
= sd_event_source_unref(m
->timer_event_source
);
159 if (m
->timer_event_source
) {
160 r
= sd_event_source_set_time(m
->timer_event_source
, now(CLOCK_MONOTONIC
) + m
->timeout_usec
);
164 return sd_event_source_set_enabled(m
->timer_event_source
, SD_EVENT_ONESHOT
);
167 return sd_event_add_time(
168 UNIT(m
)->manager
->event
,
169 &m
->timer_event_source
,
171 now(CLOCK_MONOTONIC
) + m
->timeout_usec
, 0,
172 mount_dispatch_timer
, m
);
175 static void mount_unwatch_control_pid(Mount
*m
) {
178 if (m
->control_pid
<= 0)
181 unit_unwatch_pid(UNIT(m
), m
->control_pid
);
185 static void mount_parameters_done(MountParameters
*p
) {
192 p
->what
= p
->options
= p
->fstype
= NULL
;
195 static void mount_done(Unit
*u
) {
203 mount_parameters_done(&m
->parameters_proc_self_mountinfo
);
204 mount_parameters_done(&m
->parameters_fragment
);
206 m
->exec_runtime
= exec_runtime_unref(m
->exec_runtime
);
207 exec_command_done_array(m
->exec_command
, _MOUNT_EXEC_COMMAND_MAX
);
208 m
->control_command
= NULL
;
210 mount_unwatch_control_pid(m
);
212 m
->timer_event_source
= sd_event_source_unref(m
->timer_event_source
);
215 _pure_
static MountParameters
* get_mount_parameters_fragment(Mount
*m
) {
218 if (m
->from_fragment
)
219 return &m
->parameters_fragment
;
224 _pure_
static MountParameters
* get_mount_parameters(Mount
*m
) {
227 if (m
->from_proc_self_mountinfo
)
228 return &m
->parameters_proc_self_mountinfo
;
230 return get_mount_parameters_fragment(m
);
233 static int mount_add_mount_links(Mount
*m
) {
234 _cleanup_free_
char *parent
= NULL
;
243 if (!path_equal(m
->where
, "/")) {
244 /* Adds in links to other mount points that might lie further
245 * up in the hierarchy */
246 r
= path_get_parent(m
->where
, &parent
);
250 r
= unit_require_mounts_for(UNIT(m
), parent
);
255 /* Adds in links to other mount points that might be needed
256 * for the source path (if this is a bind mount) to be
258 pm
= get_mount_parameters_fragment(m
);
259 if (pm
&& pm
->what
&&
260 path_is_absolute(pm
->what
) &&
261 !mount_is_network(pm
)) {
263 r
= unit_require_mounts_for(UNIT(m
), pm
->what
);
268 /* Adds in links to other units that use this path or paths
269 * further down in the hierarchy */
270 s
= manager_get_units_requiring_mounts_for(UNIT(m
)->manager
, m
->where
);
271 SET_FOREACH(other
, s
, i
) {
273 if (other
->load_state
!= UNIT_LOADED
)
276 if (other
== UNIT(m
))
279 r
= unit_add_dependency(other
, UNIT_AFTER
, UNIT(m
), true);
283 if (UNIT(m
)->fragment_path
) {
284 /* If we have fragment configuration, then make this dependency required */
285 r
= unit_add_dependency(other
, UNIT_REQUIRES
, UNIT(m
), true);
294 static int mount_add_device_links(Mount
*m
) {
296 bool device_wants_mount
= false;
301 p
= get_mount_parameters_fragment(m
);
308 if (mount_is_bind(p
))
311 if (!is_device_path(p
->what
))
314 if (path_equal(m
->where
, "/"))
317 if (mount_is_auto(p
) && UNIT(m
)->manager
->running_as
== SYSTEMD_SYSTEM
)
318 device_wants_mount
= true;
320 r
= unit_add_node_link(UNIT(m
), p
->what
, device_wants_mount
);
327 static int mount_add_quota_links(Mount
*m
) {
333 if (UNIT(m
)->manager
->running_as
!= SYSTEMD_SYSTEM
)
336 p
= get_mount_parameters_fragment(m
);
343 r
= unit_add_two_dependencies_by_name(UNIT(m
), UNIT_BEFORE
, UNIT_WANTS
, SPECIAL_QUOTACHECK_SERVICE
, NULL
, true);
347 r
= unit_add_two_dependencies_by_name(UNIT(m
), UNIT_BEFORE
, UNIT_WANTS
, SPECIAL_QUOTAON_SERVICE
, NULL
, true);
354 static bool should_umount(Mount
*m
) {
357 if (path_equal(m
->where
, "/") ||
358 path_equal(m
->where
, "/usr"))
361 p
= get_mount_parameters(m
);
362 if (p
&& mount_test_option(p
->options
, "x-initrd.mount") &&
369 static int mount_add_default_dependencies(Mount
*m
) {
370 const char *after
, *after2
, *online
;
376 if (UNIT(m
)->manager
->running_as
!= SYSTEMD_SYSTEM
)
379 p
= get_mount_parameters(m
);
384 if (path_equal(m
->where
, "/") ||
385 path_equal(m
->where
, "/usr"))
388 if (mount_is_network(p
)) {
389 after
= SPECIAL_REMOTE_FS_PRE_TARGET
;
390 after2
= SPECIAL_NETWORK_TARGET
;
391 online
= SPECIAL_NETWORK_ONLINE_TARGET
;
393 after
= SPECIAL_LOCAL_FS_PRE_TARGET
;
398 r
= unit_add_dependency_by_name(UNIT(m
), UNIT_AFTER
, after
, NULL
, true);
403 r
= unit_add_dependency_by_name(UNIT(m
), UNIT_AFTER
, after2
, NULL
, true);
409 r
= unit_add_two_dependencies_by_name(UNIT(m
), UNIT_WANTS
, UNIT_AFTER
, online
, NULL
, true);
414 if (should_umount(m
)) {
415 r
= unit_add_two_dependencies_by_name(UNIT(m
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
423 static int mount_verify(Mount
*m
) {
424 _cleanup_free_
char *e
= NULL
;
429 if (UNIT(m
)->load_state
!= UNIT_LOADED
)
432 if (!m
->from_fragment
&& !m
->from_proc_self_mountinfo
)
435 e
= unit_name_from_path(m
->where
, ".mount");
439 b
= unit_has_name(UNIT(m
), e
);
441 log_unit_error(UNIT(m
)->id
, "%s's Where= setting doesn't match unit name. Refusing.", UNIT(m
)->id
);
445 if (mount_point_is_api(m
->where
) || mount_point_ignore(m
->where
)) {
446 log_unit_error(UNIT(m
)->id
, "Cannot create mount unit for API file system %s. Refusing.", m
->where
);
450 if (UNIT(m
)->fragment_path
&& !m
->parameters_fragment
.what
) {
451 log_unit_error(UNIT(m
)->id
, "%s's What setting is missing. Refusing.", UNIT(m
)->id
);
455 if (m
->exec_context
.pam_name
&& m
->kill_context
.kill_mode
!= KILL_CONTROL_GROUP
) {
456 log_unit_error(UNIT(m
)->id
, "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.",UNIT(m
)->id
);
463 static int mount_add_extras(Mount
*m
) {
469 if (u
->fragment_path
)
470 m
->from_fragment
= true;
473 m
->where
= unit_name_to_path(u
->id
);
478 path_kill_slashes(m
->where
);
480 if (!u
->description
) {
481 r
= unit_set_description(u
, m
->where
);
486 r
= mount_add_device_links(m
);
490 r
= mount_add_mount_links(m
);
494 r
= mount_add_quota_links(m
);
498 r
= unit_patch_contexts(u
);
502 r
= unit_add_exec_dependencies(u
, &m
->exec_context
);
506 r
= unit_add_default_slice(u
, &m
->cgroup_context
);
510 if (u
->default_dependencies
) {
511 r
= mount_add_default_dependencies(m
);
519 static int mount_load(Unit
*u
) {
524 assert(u
->load_state
== UNIT_STUB
);
526 if (m
->from_proc_self_mountinfo
)
527 r
= unit_load_fragment_and_dropin_optional(u
);
529 r
= unit_load_fragment_and_dropin(u
);
534 /* This is a new unit? Then let's add in some extras */
535 if (u
->load_state
== UNIT_LOADED
) {
536 r
= mount_add_extras(m
);
541 return mount_verify(m
);
544 static int mount_notify_automount(Mount
*m
, int status
) {
551 SET_FOREACH(p
, UNIT(m
)->dependencies
[UNIT_TRIGGERED_BY
], i
)
552 if (p
->type
== UNIT_AUTOMOUNT
) {
553 r
= automount_send_ready(AUTOMOUNT(p
), status
);
561 static void mount_set_state(Mount
*m
, MountState state
) {
562 MountState old_state
;
565 old_state
= m
->state
;
568 if (state
!= MOUNT_MOUNTING
&&
569 state
!= MOUNT_MOUNTING_DONE
&&
570 state
!= MOUNT_REMOUNTING
&&
571 state
!= MOUNT_UNMOUNTING
&&
572 state
!= MOUNT_MOUNTING_SIGTERM
&&
573 state
!= MOUNT_MOUNTING_SIGKILL
&&
574 state
!= MOUNT_UNMOUNTING_SIGTERM
&&
575 state
!= MOUNT_UNMOUNTING_SIGKILL
&&
576 state
!= MOUNT_REMOUNTING_SIGTERM
&&
577 state
!= MOUNT_REMOUNTING_SIGKILL
) {
578 m
->timer_event_source
= sd_event_source_unref(m
->timer_event_source
);
579 mount_unwatch_control_pid(m
);
580 m
->control_command
= NULL
;
581 m
->control_command_id
= _MOUNT_EXEC_COMMAND_INVALID
;
584 if (state
== MOUNT_MOUNTED
||
585 state
== MOUNT_REMOUNTING
)
586 mount_notify_automount(m
, 0);
587 else if (state
== MOUNT_DEAD
||
588 state
== MOUNT_UNMOUNTING
||
589 state
== MOUNT_MOUNTING_SIGTERM
||
590 state
== MOUNT_MOUNTING_SIGKILL
||
591 state
== MOUNT_REMOUNTING_SIGTERM
||
592 state
== MOUNT_REMOUNTING_SIGKILL
||
593 state
== MOUNT_UNMOUNTING_SIGTERM
||
594 state
== MOUNT_UNMOUNTING_SIGKILL
||
595 state
== MOUNT_FAILED
) {
596 if (state
!= old_state
)
597 mount_notify_automount(m
, -ENODEV
);
600 if (state
!= old_state
)
601 log_unit_debug(UNIT(m
)->id
,
602 "%s changed %s -> %s",
604 mount_state_to_string(old_state
),
605 mount_state_to_string(state
));
607 unit_notify(UNIT(m
), state_translation_table
[old_state
], state_translation_table
[state
], m
->reload_result
== MOUNT_SUCCESS
);
608 m
->reload_result
= MOUNT_SUCCESS
;
611 static int mount_coldplug(Unit
*u
) {
613 MountState new_state
= MOUNT_DEAD
;
617 assert(m
->state
== MOUNT_DEAD
);
619 if (m
->deserialized_state
!= m
->state
)
620 new_state
= m
->deserialized_state
;
621 else if (m
->from_proc_self_mountinfo
)
622 new_state
= MOUNT_MOUNTED
;
624 if (new_state
== m
->state
)
627 if (new_state
== MOUNT_MOUNTING
||
628 new_state
== MOUNT_MOUNTING_DONE
||
629 new_state
== MOUNT_REMOUNTING
||
630 new_state
== MOUNT_UNMOUNTING
||
631 new_state
== MOUNT_MOUNTING_SIGTERM
||
632 new_state
== MOUNT_MOUNTING_SIGKILL
||
633 new_state
== MOUNT_UNMOUNTING_SIGTERM
||
634 new_state
== MOUNT_UNMOUNTING_SIGKILL
||
635 new_state
== MOUNT_REMOUNTING_SIGTERM
||
636 new_state
== MOUNT_REMOUNTING_SIGKILL
) {
638 if (m
->control_pid
<= 0)
641 r
= unit_watch_pid(UNIT(m
), m
->control_pid
);
645 r
= mount_arm_timer(m
);
650 mount_set_state(m
, new_state
);
654 static void mount_dump(Unit
*u
, FILE *f
, const char *prefix
) {
661 p
= get_mount_parameters(m
);
664 "%sMount State: %s\n"
668 "%sFile System Type: %s\n"
670 "%sFrom /proc/self/mountinfo: %s\n"
671 "%sFrom fragment: %s\n"
672 "%sDirectoryMode: %04o\n",
673 prefix
, mount_state_to_string(m
->state
),
674 prefix
, mount_result_to_string(m
->result
),
676 prefix
, p
? strna(p
->what
) : "n/a",
677 prefix
, p
? strna(p
->fstype
) : "n/a",
678 prefix
, p
? strna(p
->options
) : "n/a",
679 prefix
, yes_no(m
->from_proc_self_mountinfo
),
680 prefix
, yes_no(m
->from_fragment
),
681 prefix
, m
->directory_mode
);
683 if (m
->control_pid
> 0)
685 "%sControl PID: "PID_FMT
"\n",
686 prefix
, m
->control_pid
);
688 exec_context_dump(&m
->exec_context
, f
, prefix
);
689 kill_context_dump(&m
->kill_context
, f
, prefix
);
692 static int mount_spawn(Mount
*m
, ExecCommand
*c
, pid_t
*_pid
) {
695 ExecParameters exec_params
= {
696 .apply_permissions
= true,
697 .apply_chroot
= true,
698 .apply_tty_stdin
= true,
705 unit_realize_cgroup(UNIT(m
));
707 r
= unit_setup_exec_runtime(UNIT(m
));
711 r
= mount_arm_timer(m
);
715 exec_params
.environment
= UNIT(m
)->manager
->environment
;
716 exec_params
.confirm_spawn
= UNIT(m
)->manager
->confirm_spawn
;
717 exec_params
.cgroup_supported
= UNIT(m
)->manager
->cgroup_supported
;
718 exec_params
.cgroup_path
= UNIT(m
)->cgroup_path
;
719 exec_params
.cgroup_delegate
= m
->cgroup_context
.delegate
;
720 exec_params
.runtime_prefix
= manager_get_runtime_prefix(UNIT(m
)->manager
);
721 exec_params
.unit_id
= UNIT(m
)->id
;
731 r
= unit_watch_pid(UNIT(m
), pid
);
733 /* FIXME: we need to do something here */
741 m
->timer_event_source
= sd_event_source_unref(m
->timer_event_source
);
746 static void mount_enter_dead(Mount
*m
, MountResult f
) {
749 if (f
!= MOUNT_SUCCESS
)
752 exec_runtime_destroy(m
->exec_runtime
);
753 m
->exec_runtime
= exec_runtime_unref(m
->exec_runtime
);
755 exec_context_destroy_runtime_directory(&m
->exec_context
, manager_get_runtime_prefix(UNIT(m
)->manager
));
757 mount_set_state(m
, m
->result
!= MOUNT_SUCCESS
? MOUNT_FAILED
: MOUNT_DEAD
);
760 static void mount_enter_mounted(Mount
*m
, MountResult f
) {
763 if (f
!= MOUNT_SUCCESS
)
766 mount_set_state(m
, MOUNT_MOUNTED
);
769 static void mount_enter_signal(Mount
*m
, MountState state
, MountResult f
) {
774 if (f
!= MOUNT_SUCCESS
)
777 r
= unit_kill_context(
780 (state
!= MOUNT_MOUNTING_SIGTERM
&& state
!= MOUNT_UNMOUNTING_SIGTERM
&& state
!= MOUNT_REMOUNTING_SIGTERM
) ?
781 KILL_KILL
: KILL_TERMINATE
,
789 r
= mount_arm_timer(m
);
793 mount_set_state(m
, state
);
794 } else if (state
== MOUNT_REMOUNTING_SIGTERM
)
795 mount_enter_signal(m
, MOUNT_REMOUNTING_SIGKILL
, MOUNT_SUCCESS
);
796 else if (state
== MOUNT_REMOUNTING_SIGKILL
)
797 mount_enter_mounted(m
, MOUNT_SUCCESS
);
798 else if (state
== MOUNT_MOUNTING_SIGTERM
)
799 mount_enter_signal(m
, MOUNT_MOUNTING_SIGKILL
, MOUNT_SUCCESS
);
800 else if (state
== MOUNT_UNMOUNTING_SIGTERM
)
801 mount_enter_signal(m
, MOUNT_UNMOUNTING_SIGKILL
, MOUNT_SUCCESS
);
803 mount_enter_dead(m
, MOUNT_SUCCESS
);
808 log_unit_warning(UNIT(m
)->id
,
809 "%s failed to kill processes: %s", UNIT(m
)->id
, strerror(-r
));
811 if (state
== MOUNT_REMOUNTING_SIGTERM
|| state
== MOUNT_REMOUNTING_SIGKILL
)
812 mount_enter_mounted(m
, MOUNT_FAILURE_RESOURCES
);
814 mount_enter_dead(m
, MOUNT_FAILURE_RESOURCES
);
817 void warn_if_dir_nonempty(const char *unit
, const char* where
) {
823 r
= dir_is_empty(where
);
827 log_unit_struct(unit
,
829 LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING
),
830 LOG_MESSAGE("%s: Directory %s to mount over is not empty, mounting anyway.",
835 log_unit_warning(unit
,
836 "MESSAGE=Failed to check directory %s: %s",
837 where
, strerror(-r
));
840 static int fail_if_symlink(const char *unit
, const char* where
) {
843 if (is_symlink(where
) > 0) {
844 log_unit_struct(unit
,
846 LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING
),
847 LOG_MESSAGE("%s: Mount on symlink %s not allowed.",
857 static void mount_enter_unmounting(Mount
*m
) {
862 m
->control_command_id
= MOUNT_EXEC_UNMOUNT
;
863 m
->control_command
= m
->exec_command
+ MOUNT_EXEC_UNMOUNT
;
865 if ((r
= exec_command_set(
873 mount_unwatch_control_pid(m
);
875 if ((r
= mount_spawn(m
, m
->control_command
, &m
->control_pid
)) < 0)
878 mount_set_state(m
, MOUNT_UNMOUNTING
);
883 log_unit_warning(UNIT(m
)->id
,
884 "%s failed to run 'umount' task: %s",
885 UNIT(m
)->id
, strerror(-r
));
886 mount_enter_mounted(m
, MOUNT_FAILURE_RESOURCES
);
889 static void mount_enter_mounting(Mount
*m
) {
895 m
->control_command_id
= MOUNT_EXEC_MOUNT
;
896 m
->control_command
= m
->exec_command
+ MOUNT_EXEC_MOUNT
;
898 mkdir_p_label(m
->where
, m
->directory_mode
);
900 warn_if_dir_nonempty(m
->meta
.id
, m
->where
);
902 /* Create the source directory for bind-mounts if needed */
903 p
= get_mount_parameters_fragment(m
);
904 if (p
&& mount_is_bind(p
))
905 mkdir_p_label(p
->what
, m
->directory_mode
);
907 r
= fail_if_symlink(m
->meta
.id
, m
->where
);
911 if (m
->from_fragment
)
912 r
= exec_command_set(
915 m
->sloppy_options
? "-ns" : "-n",
916 m
->parameters_fragment
.what
,
918 "-t", m
->parameters_fragment
.fstype
? m
->parameters_fragment
.fstype
: "auto",
919 m
->parameters_fragment
.options
? "-o" : NULL
, m
->parameters_fragment
.options
,
927 mount_unwatch_control_pid(m
);
929 r
= mount_spawn(m
, m
->control_command
, &m
->control_pid
);
933 mount_set_state(m
, MOUNT_MOUNTING
);
938 log_unit_warning(UNIT(m
)->id
,
939 "%s failed to run 'mount' task: %s",
940 UNIT(m
)->id
, strerror(-r
));
941 mount_enter_dead(m
, MOUNT_FAILURE_RESOURCES
);
944 static void mount_enter_remounting(Mount
*m
) {
949 m
->control_command_id
= MOUNT_EXEC_REMOUNT
;
950 m
->control_command
= m
->exec_command
+ MOUNT_EXEC_REMOUNT
;
952 if (m
->from_fragment
) {
955 if (m
->parameters_fragment
.options
)
956 o
= strappenda("remount,", m
->parameters_fragment
.options
);
960 r
= exec_command_set(
963 m
->sloppy_options
? "-ns" : "-n",
964 m
->parameters_fragment
.what
,
966 "-t", m
->parameters_fragment
.fstype
? m
->parameters_fragment
.fstype
: "auto",
975 mount_unwatch_control_pid(m
);
977 r
= mount_spawn(m
, m
->control_command
, &m
->control_pid
);
981 mount_set_state(m
, MOUNT_REMOUNTING
);
986 log_unit_warning(UNIT(m
)->id
,
987 "%s failed to run 'remount' task: %s",
988 UNIT(m
)->id
, strerror(-r
));
989 m
->reload_result
= MOUNT_FAILURE_RESOURCES
;
990 mount_enter_mounted(m
, MOUNT_SUCCESS
);
993 static int mount_start(Unit
*u
) {
998 /* We cannot fulfill this request right now, try again later
1000 if (m
->state
== MOUNT_UNMOUNTING
||
1001 m
->state
== MOUNT_UNMOUNTING_SIGTERM
||
1002 m
->state
== MOUNT_UNMOUNTING_SIGKILL
||
1003 m
->state
== MOUNT_MOUNTING_SIGTERM
||
1004 m
->state
== MOUNT_MOUNTING_SIGKILL
)
1007 /* Already on it! */
1008 if (m
->state
== MOUNT_MOUNTING
)
1011 assert(m
->state
== MOUNT_DEAD
|| m
->state
== MOUNT_FAILED
);
1013 m
->result
= MOUNT_SUCCESS
;
1014 m
->reload_result
= MOUNT_SUCCESS
;
1016 mount_enter_mounting(m
);
1020 static int mount_stop(Unit
*u
) {
1021 Mount
*m
= MOUNT(u
);
1026 if (m
->state
== MOUNT_UNMOUNTING
||
1027 m
->state
== MOUNT_UNMOUNTING_SIGKILL
||
1028 m
->state
== MOUNT_UNMOUNTING_SIGTERM
||
1029 m
->state
== MOUNT_MOUNTING_SIGTERM
||
1030 m
->state
== MOUNT_MOUNTING_SIGKILL
)
1033 assert(m
->state
== MOUNT_MOUNTING
||
1034 m
->state
== MOUNT_MOUNTING_DONE
||
1035 m
->state
== MOUNT_MOUNTED
||
1036 m
->state
== MOUNT_REMOUNTING
||
1037 m
->state
== MOUNT_REMOUNTING_SIGTERM
||
1038 m
->state
== MOUNT_REMOUNTING_SIGKILL
);
1040 mount_enter_unmounting(m
);
1044 static int mount_reload(Unit
*u
) {
1045 Mount
*m
= MOUNT(u
);
1049 if (m
->state
== MOUNT_MOUNTING_DONE
)
1052 assert(m
->state
== MOUNT_MOUNTED
);
1054 mount_enter_remounting(m
);
1058 static int mount_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
1059 Mount
*m
= MOUNT(u
);
1065 unit_serialize_item(u
, f
, "state", mount_state_to_string(m
->state
));
1066 unit_serialize_item(u
, f
, "result", mount_result_to_string(m
->result
));
1067 unit_serialize_item(u
, f
, "reload-result", mount_result_to_string(m
->reload_result
));
1069 if (m
->control_pid
> 0)
1070 unit_serialize_item_format(u
, f
, "control-pid", PID_FMT
, m
->control_pid
);
1072 if (m
->control_command_id
>= 0)
1073 unit_serialize_item(u
, f
, "control-command", mount_exec_command_to_string(m
->control_command_id
));
1078 static int mount_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
1079 Mount
*m
= MOUNT(u
);
1086 if (streq(key
, "state")) {
1089 if ((state
= mount_state_from_string(value
)) < 0)
1090 log_unit_debug(u
->id
, "Failed to parse state value %s", value
);
1092 m
->deserialized_state
= state
;
1093 } else if (streq(key
, "result")) {
1096 f
= mount_result_from_string(value
);
1098 log_unit_debug(UNIT(m
)->id
,
1099 "Failed to parse result value %s", value
);
1100 else if (f
!= MOUNT_SUCCESS
)
1103 } else if (streq(key
, "reload-result")) {
1106 f
= mount_result_from_string(value
);
1108 log_unit_debug(UNIT(m
)->id
,
1109 "Failed to parse reload result value %s", value
);
1110 else if (f
!= MOUNT_SUCCESS
)
1111 m
->reload_result
= f
;
1113 } else if (streq(key
, "control-pid")) {
1116 if (parse_pid(value
, &pid
) < 0)
1117 log_unit_debug(UNIT(m
)->id
,
1118 "Failed to parse control-pid value %s", value
);
1120 m
->control_pid
= pid
;
1121 } else if (streq(key
, "control-command")) {
1122 MountExecCommand id
;
1124 if ((id
= mount_exec_command_from_string(value
)) < 0)
1125 log_unit_debug(UNIT(m
)->id
,
1126 "Failed to parse exec-command value %s", value
);
1128 m
->control_command_id
= id
;
1129 m
->control_command
= m
->exec_command
+ id
;
1132 log_unit_debug(UNIT(m
)->id
,
1133 "Unknown serialization key '%s'", key
);
1138 _pure_
static UnitActiveState
mount_active_state(Unit
*u
) {
1141 return state_translation_table
[MOUNT(u
)->state
];
1144 _pure_
static const char *mount_sub_state_to_string(Unit
*u
) {
1147 return mount_state_to_string(MOUNT(u
)->state
);
1150 _pure_
static bool mount_check_gc(Unit
*u
) {
1151 Mount
*m
= MOUNT(u
);
1155 return m
->from_proc_self_mountinfo
;
1158 static void mount_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
1159 Mount
*m
= MOUNT(u
);
1165 if (pid
!= m
->control_pid
)
1170 if (is_clean_exit(code
, status
, NULL
))
1172 else if (code
== CLD_EXITED
)
1173 f
= MOUNT_FAILURE_EXIT_CODE
;
1174 else if (code
== CLD_KILLED
)
1175 f
= MOUNT_FAILURE_SIGNAL
;
1176 else if (code
== CLD_DUMPED
)
1177 f
= MOUNT_FAILURE_CORE_DUMP
;
1179 assert_not_reached("Unknown code");
1181 if (f
!= MOUNT_SUCCESS
)
1184 if (m
->control_command
) {
1185 exec_status_exit(&m
->control_command
->exec_status
, &m
->exec_context
, pid
, code
, status
);
1187 m
->control_command
= NULL
;
1188 m
->control_command_id
= _MOUNT_EXEC_COMMAND_INVALID
;
1191 log_unit_full(u
->id
,
1192 f
== MOUNT_SUCCESS
? LOG_DEBUG
: LOG_NOTICE
,
1193 "%s mount process exited, code=%s status=%i",
1194 u
->id
, sigchld_code_to_string(code
), status
);
1196 /* Note that mount(8) returning and the kernel sending us a
1197 * mount table change event might happen out-of-order. If an
1198 * operation succeed we assume the kernel will follow soon too
1199 * and already change into the resulting state. If it fails
1200 * we check if the kernel still knows about the mount. and
1201 * change state accordingly. */
1205 case MOUNT_MOUNTING
:
1206 case MOUNT_MOUNTING_DONE
:
1207 case MOUNT_MOUNTING_SIGKILL
:
1208 case MOUNT_MOUNTING_SIGTERM
:
1210 if (f
== MOUNT_SUCCESS
)
1211 mount_enter_mounted(m
, f
);
1212 else if (m
->from_proc_self_mountinfo
)
1213 mount_enter_mounted(m
, f
);
1215 mount_enter_dead(m
, f
);
1218 case MOUNT_REMOUNTING
:
1219 case MOUNT_REMOUNTING_SIGKILL
:
1220 case MOUNT_REMOUNTING_SIGTERM
:
1222 m
->reload_result
= f
;
1223 if (m
->from_proc_self_mountinfo
)
1224 mount_enter_mounted(m
, MOUNT_SUCCESS
);
1226 mount_enter_dead(m
, MOUNT_SUCCESS
);
1230 case MOUNT_UNMOUNTING
:
1231 case MOUNT_UNMOUNTING_SIGKILL
:
1232 case MOUNT_UNMOUNTING_SIGTERM
:
1234 if (f
== MOUNT_SUCCESS
)
1235 mount_enter_dead(m
, f
);
1236 else if (m
->from_proc_self_mountinfo
)
1237 mount_enter_mounted(m
, f
);
1239 mount_enter_dead(m
, f
);
1243 assert_not_reached("Uh, control process died at wrong time.");
1246 /* Notify clients about changed exit status */
1247 unit_add_to_dbus_queue(u
);
1250 static int mount_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
1251 Mount
*m
= MOUNT(userdata
);
1254 assert(m
->timer_event_source
== source
);
1258 case MOUNT_MOUNTING
:
1259 case MOUNT_MOUNTING_DONE
:
1260 log_unit_warning(UNIT(m
)->id
,
1261 "%s mounting timed out. Stopping.", UNIT(m
)->id
);
1262 mount_enter_signal(m
, MOUNT_MOUNTING_SIGTERM
, MOUNT_FAILURE_TIMEOUT
);
1265 case MOUNT_REMOUNTING
:
1266 log_unit_warning(UNIT(m
)->id
,
1267 "%s remounting timed out. Stopping.", UNIT(m
)->id
);
1268 m
->reload_result
= MOUNT_FAILURE_TIMEOUT
;
1269 mount_enter_mounted(m
, MOUNT_SUCCESS
);
1272 case MOUNT_UNMOUNTING
:
1273 log_unit_warning(UNIT(m
)->id
,
1274 "%s unmounting timed out. Stopping.", UNIT(m
)->id
);
1275 mount_enter_signal(m
, MOUNT_UNMOUNTING_SIGTERM
, MOUNT_FAILURE_TIMEOUT
);
1278 case MOUNT_MOUNTING_SIGTERM
:
1279 if (m
->kill_context
.send_sigkill
) {
1280 log_unit_warning(UNIT(m
)->id
,
1281 "%s mounting timed out. Killing.", UNIT(m
)->id
);
1282 mount_enter_signal(m
, MOUNT_MOUNTING_SIGKILL
, MOUNT_FAILURE_TIMEOUT
);
1284 log_unit_warning(UNIT(m
)->id
,
1285 "%s mounting timed out. Skipping SIGKILL. Ignoring.",
1288 if (m
->from_proc_self_mountinfo
)
1289 mount_enter_mounted(m
, MOUNT_FAILURE_TIMEOUT
);
1291 mount_enter_dead(m
, MOUNT_FAILURE_TIMEOUT
);
1295 case MOUNT_REMOUNTING_SIGTERM
:
1296 if (m
->kill_context
.send_sigkill
) {
1297 log_unit_warning(UNIT(m
)->id
,
1298 "%s remounting timed out. Killing.", UNIT(m
)->id
);
1299 mount_enter_signal(m
, MOUNT_REMOUNTING_SIGKILL
, MOUNT_FAILURE_TIMEOUT
);
1301 log_unit_warning(UNIT(m
)->id
,
1302 "%s remounting timed out. Skipping SIGKILL. Ignoring.",
1305 if (m
->from_proc_self_mountinfo
)
1306 mount_enter_mounted(m
, MOUNT_FAILURE_TIMEOUT
);
1308 mount_enter_dead(m
, MOUNT_FAILURE_TIMEOUT
);
1312 case MOUNT_UNMOUNTING_SIGTERM
:
1313 if (m
->kill_context
.send_sigkill
) {
1314 log_unit_warning(UNIT(m
)->id
,
1315 "%s unmounting timed out. Killing.", UNIT(m
)->id
);
1316 mount_enter_signal(m
, MOUNT_UNMOUNTING_SIGKILL
, MOUNT_FAILURE_TIMEOUT
);
1318 log_unit_warning(UNIT(m
)->id
,
1319 "%s unmounting timed out. Skipping SIGKILL. Ignoring.",
1322 if (m
->from_proc_self_mountinfo
)
1323 mount_enter_mounted(m
, MOUNT_FAILURE_TIMEOUT
);
1325 mount_enter_dead(m
, MOUNT_FAILURE_TIMEOUT
);
1329 case MOUNT_MOUNTING_SIGKILL
:
1330 case MOUNT_REMOUNTING_SIGKILL
:
1331 case MOUNT_UNMOUNTING_SIGKILL
:
1332 log_unit_warning(UNIT(m
)->id
,
1333 "%s mount process still around after SIGKILL. Ignoring.",
1336 if (m
->from_proc_self_mountinfo
)
1337 mount_enter_mounted(m
, MOUNT_FAILURE_TIMEOUT
);
1339 mount_enter_dead(m
, MOUNT_FAILURE_TIMEOUT
);
1343 assert_not_reached("Timeout at wrong time.");
1349 static int mount_add_one(
1353 const char *options
,
1357 _cleanup_free_
char *e
= NULL
, *w
= NULL
, *o
= NULL
, *f
= NULL
;
1358 bool load_extras
= false;
1360 bool delete, changed
= false;
1370 /* Ignore API mount points. They should never be referenced in
1371 * dependencies ever. */
1372 if (mount_point_is_api(where
) || mount_point_ignore(where
))
1375 if (streq(fstype
, "autofs"))
1378 /* probably some kind of swap, ignore */
1379 if (!is_path(where
))
1382 e
= unit_name_from_path(where
, ".mount");
1386 u
= manager_get_unit(m
, e
);
1390 u
= unit_new(m
, sizeof(Mount
));
1394 r
= unit_add_name(u
, e
);
1398 MOUNT(u
)->where
= strdup(where
);
1399 if (!MOUNT(u
)->where
) {
1404 u
->source_path
= strdup("/proc/self/mountinfo");
1405 if (!u
->source_path
) {
1411 if (m
->running_as
== SYSTEMD_SYSTEM
) {
1414 target
= fstype_is_network(fstype
) ? SPECIAL_REMOTE_FS_TARGET
: SPECIAL_LOCAL_FS_TARGET
;
1416 r
= unit_add_dependency_by_name(u
, UNIT_BEFORE
, target
, NULL
, true);
1420 if (should_umount(MOUNT(u
))) {
1421 r
= unit_add_dependency_by_name(u
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
1427 unit_add_to_load_queue(u
);
1432 if (!MOUNT(u
)->where
) {
1433 MOUNT(u
)->where
= strdup(where
);
1434 if (!MOUNT(u
)->where
) {
1440 if (u
->load_state
== UNIT_NOT_FOUND
) {
1441 u
->load_state
= UNIT_LOADED
;
1444 /* Load in the extras later on, after we
1445 * finished initialization of the unit */
1452 o
= strdup(options
);
1454 if (!w
|| !o
|| !f
) {
1459 p
= &MOUNT(u
)->parameters_proc_self_mountinfo
;
1461 changed
= changed
||
1462 !streq_ptr(p
->options
, options
) ||
1463 !streq_ptr(p
->what
, what
) ||
1464 !streq_ptr(p
->fstype
, fstype
);
1467 MOUNT(u
)->is_mounted
= true;
1468 MOUNT(u
)->just_mounted
= !MOUNT(u
)->from_proc_self_mountinfo
;
1469 MOUNT(u
)->just_changed
= changed
;
1472 MOUNT(u
)->from_proc_self_mountinfo
= true;
1487 r
= mount_add_extras(MOUNT(u
));
1493 unit_add_to_dbus_queue(u
);
1504 static inline void mnt_free_table_p(struct libmnt_table
**tb
) {
1505 mnt_free_table(*tb
);
1508 static inline void mnt_free_iter_p(struct libmnt_iter
**itr
) {
1509 mnt_free_iter(*itr
);
1512 static int mount_load_proc_self_mountinfo(Manager
*m
, bool set_flags
) {
1513 _cleanup_(mnt_free_table_p
) struct libmnt_table
*tb
= NULL
;
1514 _cleanup_(mnt_free_iter_p
) struct libmnt_iter
*itr
= NULL
;
1515 struct libmnt_fs
*fs
;
1520 tb
= mnt_new_table();
1521 itr
= mnt_new_iter(MNT_ITER_FORWARD
);
1525 mnt_table_parse_mtab(tb
, NULL
);
1529 while (mnt_table_next_fs(tb
, itr
, &fs
) == 0) {
1530 const char *device
, *path
, *options
, *fstype
;
1531 _cleanup_free_
const char *d
= NULL
, *p
= NULL
;
1534 device
= mnt_fs_get_source(fs
);
1535 path
= mnt_fs_get_target(fs
);
1536 options
= mnt_fs_get_options(fs
);
1537 fstype
= mnt_fs_get_fstype(fs
);
1539 d
= cunescape(device
);
1540 p
= cunescape(path
);
1544 k
= mount_add_one(m
, d
, p
, options
, fstype
, set_flags
);
1552 static void mount_shutdown(Manager
*m
) {
1555 m
->mount_event_source
= sd_event_source_unref(m
->mount_event_source
);
1557 if (m
->proc_self_mountinfo
) {
1558 fclose(m
->proc_self_mountinfo
);
1559 m
->proc_self_mountinfo
= NULL
;
1563 static int mount_get_timeout(Unit
*u
, uint64_t *timeout
) {
1564 Mount
*m
= MOUNT(u
);
1567 if (!m
->timer_event_source
)
1570 r
= sd_event_source_get_time(m
->timer_event_source
, timeout
);
1577 static int mount_enumerate(Manager
*m
) {
1583 if (!m
->proc_self_mountinfo
) {
1584 m
->proc_self_mountinfo
= fopen("/proc/self/mountinfo", "re");
1585 if (!m
->proc_self_mountinfo
)
1588 r
= sd_event_add_io(m
->event
, &m
->mount_event_source
, fileno(m
->proc_self_mountinfo
), EPOLLPRI
, mount_dispatch_io
, m
);
1592 /* Dispatch this before we dispatch SIGCHLD, so that
1593 * we always get the events from /proc/self/mountinfo
1594 * before the SIGCHLD of /bin/mount. */
1595 r
= sd_event_source_set_priority(m
->mount_event_source
, -10);
1600 r
= mount_load_proc_self_mountinfo(m
, false);
1611 static int mount_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
) {
1612 Manager
*m
= userdata
;
1617 assert(revents
& EPOLLPRI
);
1619 /* The manager calls this for every fd event happening on the
1620 * /proc/self/mountinfo file, which informs us about mounting
1623 r
= mount_load_proc_self_mountinfo(m
, true);
1625 log_error_errno(r
, "Failed to reread /proc/self/mountinfo: %m");
1627 /* Reset flags, just in case, for later calls */
1628 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_MOUNT
]) {
1629 Mount
*mount
= MOUNT(u
);
1631 mount
->is_mounted
= mount
->just_mounted
= mount
->just_changed
= false;
1637 manager_dispatch_load_queue(m
);
1639 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_MOUNT
]) {
1640 Mount
*mount
= MOUNT(u
);
1642 if (!mount
->is_mounted
) {
1644 mount
->from_proc_self_mountinfo
= false;
1646 switch (mount
->state
) {
1649 /* This has just been unmounted by
1650 * somebody else, follow the state
1652 mount_enter_dead(mount
, MOUNT_SUCCESS
);
1659 } else if (mount
->just_mounted
|| mount
->just_changed
) {
1661 /* New or changed mount entry */
1663 switch (mount
->state
) {
1667 /* This has just been mounted by
1668 * somebody else, follow the state
1670 mount_enter_mounted(mount
, MOUNT_SUCCESS
);
1673 case MOUNT_MOUNTING
:
1674 mount_set_state(mount
, MOUNT_MOUNTING_DONE
);
1678 /* Nothing really changed, but let's
1679 * issue an notification call
1680 * nonetheless, in case somebody is
1681 * waiting for this. (e.g. file system
1682 * ro/rw remounts.) */
1683 mount_set_state(mount
, mount
->state
);
1688 /* Reset the flags for later calls */
1689 mount
->is_mounted
= mount
->just_mounted
= mount
->just_changed
= false;
1695 static void mount_reset_failed(Unit
*u
) {
1696 Mount
*m
= MOUNT(u
);
1700 if (m
->state
== MOUNT_FAILED
)
1701 mount_set_state(m
, MOUNT_DEAD
);
1703 m
->result
= MOUNT_SUCCESS
;
1704 m
->reload_result
= MOUNT_SUCCESS
;
1707 static int mount_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
1708 return unit_kill_common(u
, who
, signo
, -1, MOUNT(u
)->control_pid
, error
);
1711 static const char* const mount_state_table
[_MOUNT_STATE_MAX
] = {
1712 [MOUNT_DEAD
] = "dead",
1713 [MOUNT_MOUNTING
] = "mounting",
1714 [MOUNT_MOUNTING_DONE
] = "mounting-done",
1715 [MOUNT_MOUNTED
] = "mounted",
1716 [MOUNT_REMOUNTING
] = "remounting",
1717 [MOUNT_UNMOUNTING
] = "unmounting",
1718 [MOUNT_MOUNTING_SIGTERM
] = "mounting-sigterm",
1719 [MOUNT_MOUNTING_SIGKILL
] = "mounting-sigkill",
1720 [MOUNT_REMOUNTING_SIGTERM
] = "remounting-sigterm",
1721 [MOUNT_REMOUNTING_SIGKILL
] = "remounting-sigkill",
1722 [MOUNT_UNMOUNTING_SIGTERM
] = "unmounting-sigterm",
1723 [MOUNT_UNMOUNTING_SIGKILL
] = "unmounting-sigkill",
1724 [MOUNT_FAILED
] = "failed"
1727 DEFINE_STRING_TABLE_LOOKUP(mount_state
, MountState
);
1729 static const char* const mount_exec_command_table
[_MOUNT_EXEC_COMMAND_MAX
] = {
1730 [MOUNT_EXEC_MOUNT
] = "ExecMount",
1731 [MOUNT_EXEC_UNMOUNT
] = "ExecUnmount",
1732 [MOUNT_EXEC_REMOUNT
] = "ExecRemount",
1735 DEFINE_STRING_TABLE_LOOKUP(mount_exec_command
, MountExecCommand
);
1737 static const char* const mount_result_table
[_MOUNT_RESULT_MAX
] = {
1738 [MOUNT_SUCCESS
] = "success",
1739 [MOUNT_FAILURE_RESOURCES
] = "resources",
1740 [MOUNT_FAILURE_TIMEOUT
] = "timeout",
1741 [MOUNT_FAILURE_EXIT_CODE
] = "exit-code",
1742 [MOUNT_FAILURE_SIGNAL
] = "signal",
1743 [MOUNT_FAILURE_CORE_DUMP
] = "core-dump"
1746 DEFINE_STRING_TABLE_LOOKUP(mount_result
, MountResult
);
1748 const UnitVTable mount_vtable
= {
1749 .object_size
= sizeof(Mount
),
1750 .exec_context_offset
= offsetof(Mount
, exec_context
),
1751 .cgroup_context_offset
= offsetof(Mount
, cgroup_context
),
1752 .kill_context_offset
= offsetof(Mount
, kill_context
),
1753 .exec_runtime_offset
= offsetof(Mount
, exec_runtime
),
1759 .private_section
= "Mount",
1762 .no_instances
= true,
1768 .coldplug
= mount_coldplug
,
1772 .start
= mount_start
,
1774 .reload
= mount_reload
,
1778 .serialize
= mount_serialize
,
1779 .deserialize_item
= mount_deserialize_item
,
1781 .active_state
= mount_active_state
,
1782 .sub_state_to_string
= mount_sub_state_to_string
,
1784 .check_gc
= mount_check_gc
,
1786 .sigchld_event
= mount_sigchld_event
,
1788 .reset_failed
= mount_reset_failed
,
1790 .bus_interface
= "org.freedesktop.systemd1.Mount",
1791 .bus_vtable
= bus_mount_vtable
,
1792 .bus_set_property
= bus_mount_set_property
,
1793 .bus_commit_properties
= bus_mount_commit_properties
,
1795 .get_timeout
= mount_get_timeout
,
1797 .can_transient
= true,
1799 .enumerate
= mount_enumerate
,
1800 .shutdown
= mount_shutdown
,
1802 .status_message_formats
= {
1803 .starting_stopping
= {
1804 [0] = "Mounting %s...",
1805 [1] = "Unmounting %s...",
1807 .finished_start_job
= {
1808 [JOB_DONE
] = "Mounted %s.",
1809 [JOB_FAILED
] = "Failed to mount %s.",
1810 [JOB_DEPENDENCY
] = "Dependency failed for %s.",
1811 [JOB_TIMEOUT
] = "Timed out mounting %s.",
1813 .finished_stop_job
= {
1814 [JOB_DONE
] = "Unmounted %s.",
1815 [JOB_FAILED
] = "Failed unmounting %s.",
1816 [JOB_TIMEOUT
] = "Timed out unmounting %s.",