1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include <sys/epoll.h>
31 #include "load-fragment.h"
32 #include "load-dropin.h"
34 #include "sd-messages.h"
37 #include "path-util.h"
38 #include "mount-setup.h"
39 #include "unit-name.h"
40 #include "dbus-mount.h"
42 #include "bus-errors.h"
43 #include "exit-status.h"
46 static const UnitActiveState state_translation_table
[_MOUNT_STATE_MAX
] = {
47 [MOUNT_DEAD
] = UNIT_INACTIVE
,
48 [MOUNT_MOUNTING
] = UNIT_ACTIVATING
,
49 [MOUNT_MOUNTING_DONE
] = UNIT_ACTIVE
,
50 [MOUNT_MOUNTED
] = UNIT_ACTIVE
,
51 [MOUNT_REMOUNTING
] = UNIT_RELOADING
,
52 [MOUNT_UNMOUNTING
] = UNIT_DEACTIVATING
,
53 [MOUNT_MOUNTING_SIGTERM
] = UNIT_DEACTIVATING
,
54 [MOUNT_MOUNTING_SIGKILL
] = UNIT_DEACTIVATING
,
55 [MOUNT_REMOUNTING_SIGTERM
] = UNIT_RELOADING
,
56 [MOUNT_REMOUNTING_SIGKILL
] = UNIT_RELOADING
,
57 [MOUNT_UNMOUNTING_SIGTERM
] = UNIT_DEACTIVATING
,
58 [MOUNT_UNMOUNTING_SIGKILL
] = UNIT_DEACTIVATING
,
59 [MOUNT_FAILED
] = UNIT_FAILED
62 static int mount_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
);
63 static int mount_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
);
65 static bool mount_is_network(MountParameters
*p
) {
68 if (mount_test_option(p
->options
, "_netdev"))
71 if (p
->fstype
&& fstype_is_network(p
->fstype
))
77 static bool mount_is_bind(MountParameters
*p
) {
80 if (mount_test_option(p
->options
, "bind"))
83 if (p
->fstype
&& streq(p
->fstype
, "bind"))
86 if (mount_test_option(p
->options
, "rbind"))
89 if (p
->fstype
&& streq(p
->fstype
, "rbind"))
95 static bool mount_is_auto(MountParameters
*p
) {
98 return !mount_test_option(p
->options
, "noauto");
101 static bool needs_quota(MountParameters
*p
) {
104 if (mount_is_network(p
))
107 if (mount_is_bind(p
))
110 return mount_test_option(p
->options
, "usrquota") ||
111 mount_test_option(p
->options
, "grpquota") ||
112 mount_test_option(p
->options
, "quota") ||
113 mount_test_option(p
->options
, "usrjquota") ||
114 mount_test_option(p
->options
, "grpjquota");
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_fragment(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
&& mount_test_option(p
->options
, "x-initrd.mount") &&
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 p
= get_mount_parameters(m
);
383 if (path_equal(m
->where
, "/") ||
384 path_equal(m
->where
, "/usr"))
387 if (mount_is_network(p
)) {
388 after
= SPECIAL_REMOTE_FS_PRE_TARGET
;
389 after2
= SPECIAL_NETWORK_TARGET
;
390 online
= SPECIAL_NETWORK_ONLINE_TARGET
;
392 after
= SPECIAL_LOCAL_FS_PRE_TARGET
;
397 r
= unit_add_dependency_by_name(UNIT(m
), UNIT_AFTER
, after
, NULL
, true);
402 r
= unit_add_dependency_by_name(UNIT(m
), UNIT_AFTER
, after2
, NULL
, true);
408 r
= unit_add_two_dependencies_by_name(UNIT(m
), UNIT_WANTS
, UNIT_AFTER
, online
, NULL
, true);
413 if (should_umount(m
)) {
414 r
= unit_add_two_dependencies_by_name(UNIT(m
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
422 static int mount_verify(Mount
*m
) {
423 _cleanup_free_
char *e
= NULL
;
428 if (UNIT(m
)->load_state
!= UNIT_LOADED
)
431 if (!m
->from_fragment
&& !m
->from_proc_self_mountinfo
)
434 e
= unit_name_from_path(m
->where
, ".mount");
438 b
= unit_has_name(UNIT(m
), e
);
440 log_unit_error(UNIT(m
)->id
, "%s's Where= setting doesn't match unit name. Refusing.", UNIT(m
)->id
);
444 if (mount_point_is_api(m
->where
) || mount_point_ignore(m
->where
)) {
445 log_unit_error(UNIT(m
)->id
, "Cannot create mount unit for API file system %s. Refusing.", m
->where
);
449 if (UNIT(m
)->fragment_path
&& !m
->parameters_fragment
.what
) {
450 log_unit_error(UNIT(m
)->id
, "%s's What setting is missing. Refusing.", UNIT(m
)->id
);
454 if (m
->exec_context
.pam_name
&& m
->kill_context
.kill_mode
!= KILL_CONTROL_GROUP
) {
455 log_unit_error(UNIT(m
)->id
, "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.",UNIT(m
)->id
);
462 static int mount_add_extras(Mount
*m
) {
468 if (u
->fragment_path
)
469 m
->from_fragment
= true;
472 m
->where
= unit_name_to_path(u
->id
);
477 path_kill_slashes(m
->where
);
479 if (!u
->description
) {
480 r
= unit_set_description(u
, m
->where
);
485 r
= mount_add_device_links(m
);
489 r
= mount_add_mount_links(m
);
493 r
= mount_add_quota_links(m
);
497 r
= unit_patch_contexts(u
);
501 r
= unit_add_exec_dependencies(u
, &m
->exec_context
);
505 r
= unit_add_default_slice(u
, &m
->cgroup_context
);
509 if (u
->default_dependencies
) {
510 r
= mount_add_default_dependencies(m
);
518 static int mount_load(Unit
*u
) {
523 assert(u
->load_state
== UNIT_STUB
);
525 if (m
->from_proc_self_mountinfo
)
526 r
= unit_load_fragment_and_dropin_optional(u
);
528 r
= unit_load_fragment_and_dropin(u
);
533 /* This is a new unit? Then let's add in some extras */
534 if (u
->load_state
== UNIT_LOADED
) {
535 r
= mount_add_extras(m
);
540 return mount_verify(m
);
543 static int mount_notify_automount(Mount
*m
, int status
) {
550 SET_FOREACH(p
, UNIT(m
)->dependencies
[UNIT_TRIGGERED_BY
], i
)
551 if (p
->type
== UNIT_AUTOMOUNT
) {
552 r
= automount_send_ready(AUTOMOUNT(p
), status
);
560 static void mount_set_state(Mount
*m
, MountState state
) {
561 MountState old_state
;
564 old_state
= m
->state
;
567 if (state
!= MOUNT_MOUNTING
&&
568 state
!= MOUNT_MOUNTING_DONE
&&
569 state
!= MOUNT_REMOUNTING
&&
570 state
!= MOUNT_UNMOUNTING
&&
571 state
!= MOUNT_MOUNTING_SIGTERM
&&
572 state
!= MOUNT_MOUNTING_SIGKILL
&&
573 state
!= MOUNT_UNMOUNTING_SIGTERM
&&
574 state
!= MOUNT_UNMOUNTING_SIGKILL
&&
575 state
!= MOUNT_REMOUNTING_SIGTERM
&&
576 state
!= MOUNT_REMOUNTING_SIGKILL
) {
577 m
->timer_event_source
= sd_event_source_unref(m
->timer_event_source
);
578 mount_unwatch_control_pid(m
);
579 m
->control_command
= NULL
;
580 m
->control_command_id
= _MOUNT_EXEC_COMMAND_INVALID
;
583 if (state
== MOUNT_MOUNTED
||
584 state
== MOUNT_REMOUNTING
)
585 mount_notify_automount(m
, 0);
586 else if (state
== MOUNT_DEAD
||
587 state
== MOUNT_UNMOUNTING
||
588 state
== MOUNT_MOUNTING_SIGTERM
||
589 state
== MOUNT_MOUNTING_SIGKILL
||
590 state
== MOUNT_REMOUNTING_SIGTERM
||
591 state
== MOUNT_REMOUNTING_SIGKILL
||
592 state
== MOUNT_UNMOUNTING_SIGTERM
||
593 state
== MOUNT_UNMOUNTING_SIGKILL
||
594 state
== MOUNT_FAILED
) {
595 if (state
!= old_state
)
596 mount_notify_automount(m
, -ENODEV
);
599 if (state
!= old_state
)
600 log_unit_debug(UNIT(m
)->id
,
601 "%s changed %s -> %s",
603 mount_state_to_string(old_state
),
604 mount_state_to_string(state
));
606 unit_notify(UNIT(m
), state_translation_table
[old_state
], state_translation_table
[state
], m
->reload_result
== MOUNT_SUCCESS
);
607 m
->reload_result
= MOUNT_SUCCESS
;
610 static int mount_coldplug(Unit
*u
) {
612 MountState new_state
= MOUNT_DEAD
;
616 assert(m
->state
== MOUNT_DEAD
);
618 if (m
->deserialized_state
!= m
->state
)
619 new_state
= m
->deserialized_state
;
620 else if (m
->from_proc_self_mountinfo
)
621 new_state
= MOUNT_MOUNTED
;
623 if (new_state
== m
->state
)
626 if (new_state
== MOUNT_MOUNTING
||
627 new_state
== MOUNT_MOUNTING_DONE
||
628 new_state
== MOUNT_REMOUNTING
||
629 new_state
== MOUNT_UNMOUNTING
||
630 new_state
== MOUNT_MOUNTING_SIGTERM
||
631 new_state
== MOUNT_MOUNTING_SIGKILL
||
632 new_state
== MOUNT_UNMOUNTING_SIGTERM
||
633 new_state
== MOUNT_UNMOUNTING_SIGKILL
||
634 new_state
== MOUNT_REMOUNTING_SIGTERM
||
635 new_state
== MOUNT_REMOUNTING_SIGKILL
) {
637 if (m
->control_pid
<= 0)
640 r
= unit_watch_pid(UNIT(m
), m
->control_pid
);
644 r
= mount_arm_timer(m
);
649 mount_set_state(m
, new_state
);
653 static void mount_dump(Unit
*u
, FILE *f
, const char *prefix
) {
660 p
= get_mount_parameters(m
);
663 "%sMount State: %s\n"
667 "%sFile System Type: %s\n"
669 "%sFrom /proc/self/mountinfo: %s\n"
670 "%sFrom fragment: %s\n"
671 "%sDirectoryMode: %04o\n",
672 prefix
, mount_state_to_string(m
->state
),
673 prefix
, mount_result_to_string(m
->result
),
675 prefix
, p
? strna(p
->what
) : "n/a",
676 prefix
, p
? strna(p
->fstype
) : "n/a",
677 prefix
, p
? strna(p
->options
) : "n/a",
678 prefix
, yes_no(m
->from_proc_self_mountinfo
),
679 prefix
, yes_no(m
->from_fragment
),
680 prefix
, m
->directory_mode
);
682 if (m
->control_pid
> 0)
684 "%sControl PID: "PID_FMT
"\n",
685 prefix
, m
->control_pid
);
687 exec_context_dump(&m
->exec_context
, f
, prefix
);
688 kill_context_dump(&m
->kill_context
, f
, prefix
);
691 static int mount_spawn(Mount
*m
, ExecCommand
*c
, pid_t
*_pid
) {
694 ExecParameters exec_params
= {
695 .apply_permissions
= true,
696 .apply_chroot
= true,
697 .apply_tty_stdin
= true,
704 unit_realize_cgroup(UNIT(m
));
706 r
= unit_setup_exec_runtime(UNIT(m
));
710 r
= mount_arm_timer(m
);
714 exec_params
.environment
= UNIT(m
)->manager
->environment
;
715 exec_params
.confirm_spawn
= UNIT(m
)->manager
->confirm_spawn
;
716 exec_params
.cgroup_supported
= UNIT(m
)->manager
->cgroup_supported
;
717 exec_params
.cgroup_path
= UNIT(m
)->cgroup_path
;
718 exec_params
.cgroup_delegate
= m
->cgroup_context
.delegate
;
719 exec_params
.runtime_prefix
= manager_get_runtime_prefix(UNIT(m
)->manager
);
720 exec_params
.unit_id
= UNIT(m
)->id
;
730 r
= unit_watch_pid(UNIT(m
), pid
);
732 /* FIXME: we need to do something here */
740 m
->timer_event_source
= sd_event_source_unref(m
->timer_event_source
);
745 static void mount_enter_dead(Mount
*m
, MountResult f
) {
748 if (f
!= MOUNT_SUCCESS
)
751 exec_runtime_destroy(m
->exec_runtime
);
752 m
->exec_runtime
= exec_runtime_unref(m
->exec_runtime
);
754 exec_context_destroy_runtime_directory(&m
->exec_context
, manager_get_runtime_prefix(UNIT(m
)->manager
));
756 mount_set_state(m
, m
->result
!= MOUNT_SUCCESS
? MOUNT_FAILED
: MOUNT_DEAD
);
759 static void mount_enter_mounted(Mount
*m
, MountResult f
) {
762 if (f
!= MOUNT_SUCCESS
)
765 mount_set_state(m
, MOUNT_MOUNTED
);
768 static void mount_enter_signal(Mount
*m
, MountState state
, MountResult f
) {
773 if (f
!= MOUNT_SUCCESS
)
776 r
= unit_kill_context(
779 (state
!= MOUNT_MOUNTING_SIGTERM
&& state
!= MOUNT_UNMOUNTING_SIGTERM
&& state
!= MOUNT_REMOUNTING_SIGTERM
) ?
780 KILL_KILL
: KILL_TERMINATE
,
788 r
= mount_arm_timer(m
);
792 mount_set_state(m
, state
);
793 } else if (state
== MOUNT_REMOUNTING_SIGTERM
)
794 mount_enter_signal(m
, MOUNT_REMOUNTING_SIGKILL
, MOUNT_SUCCESS
);
795 else if (state
== MOUNT_REMOUNTING_SIGKILL
)
796 mount_enter_mounted(m
, MOUNT_SUCCESS
);
797 else if (state
== MOUNT_MOUNTING_SIGTERM
)
798 mount_enter_signal(m
, MOUNT_MOUNTING_SIGKILL
, MOUNT_SUCCESS
);
799 else if (state
== MOUNT_UNMOUNTING_SIGTERM
)
800 mount_enter_signal(m
, MOUNT_UNMOUNTING_SIGKILL
, MOUNT_SUCCESS
);
802 mount_enter_dead(m
, MOUNT_SUCCESS
);
807 log_unit_warning(UNIT(m
)->id
,
808 "%s failed to kill processes: %s", UNIT(m
)->id
, strerror(-r
));
810 if (state
== MOUNT_REMOUNTING_SIGTERM
|| state
== MOUNT_REMOUNTING_SIGKILL
)
811 mount_enter_mounted(m
, MOUNT_FAILURE_RESOURCES
);
813 mount_enter_dead(m
, MOUNT_FAILURE_RESOURCES
);
816 void warn_if_dir_nonempty(const char *unit
, const char* where
) {
822 r
= dir_is_empty(where
);
826 log_unit_struct(unit
,
828 LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING
),
829 LOG_MESSAGE("%s: Directory %s to mount over is not empty, mounting anyway.",
834 log_unit_warning(unit
,
835 "MESSAGE=Failed to check directory %s: %s",
836 where
, strerror(-r
));
839 static int fail_if_symlink(const char *unit
, const char* where
) {
842 if (is_symlink(where
) > 0) {
843 log_unit_struct(unit
,
845 LOG_MESSAGE_ID(SD_MESSAGE_OVERMOUNTING
),
846 LOG_MESSAGE("%s: Mount on symlink %s not allowed.",
856 static void mount_enter_unmounting(Mount
*m
) {
861 m
->control_command_id
= MOUNT_EXEC_UNMOUNT
;
862 m
->control_command
= m
->exec_command
+ MOUNT_EXEC_UNMOUNT
;
864 if ((r
= exec_command_set(
872 mount_unwatch_control_pid(m
);
874 if ((r
= mount_spawn(m
, m
->control_command
, &m
->control_pid
)) < 0)
877 mount_set_state(m
, MOUNT_UNMOUNTING
);
882 log_unit_warning(UNIT(m
)->id
,
883 "%s failed to run 'umount' task: %s",
884 UNIT(m
)->id
, strerror(-r
));
885 mount_enter_mounted(m
, MOUNT_FAILURE_RESOURCES
);
888 static void mount_enter_mounting(Mount
*m
) {
894 m
->control_command_id
= MOUNT_EXEC_MOUNT
;
895 m
->control_command
= m
->exec_command
+ MOUNT_EXEC_MOUNT
;
897 mkdir_p_label(m
->where
, m
->directory_mode
);
899 warn_if_dir_nonempty(m
->meta
.id
, m
->where
);
901 /* Create the source directory for bind-mounts if needed */
902 p
= get_mount_parameters_fragment(m
);
903 if (p
&& mount_is_bind(p
))
904 mkdir_p_label(p
->what
, m
->directory_mode
);
906 r
= fail_if_symlink(m
->meta
.id
, m
->where
);
910 if (m
->from_fragment
)
911 r
= exec_command_set(
914 m
->sloppy_options
? "-ns" : "-n",
915 m
->parameters_fragment
.what
,
917 "-t", m
->parameters_fragment
.fstype
? m
->parameters_fragment
.fstype
: "auto",
918 m
->parameters_fragment
.options
? "-o" : NULL
, m
->parameters_fragment
.options
,
926 mount_unwatch_control_pid(m
);
928 r
= mount_spawn(m
, m
->control_command
, &m
->control_pid
);
932 mount_set_state(m
, MOUNT_MOUNTING
);
937 log_unit_warning(UNIT(m
)->id
,
938 "%s failed to run 'mount' task: %s",
939 UNIT(m
)->id
, strerror(-r
));
940 mount_enter_dead(m
, MOUNT_FAILURE_RESOURCES
);
943 static void mount_enter_remounting(Mount
*m
) {
948 m
->control_command_id
= MOUNT_EXEC_REMOUNT
;
949 m
->control_command
= m
->exec_command
+ MOUNT_EXEC_REMOUNT
;
951 if (m
->from_fragment
) {
954 if (m
->parameters_fragment
.options
)
955 o
= strappenda("remount,", m
->parameters_fragment
.options
);
959 r
= exec_command_set(
962 m
->sloppy_options
? "-ns" : "-n",
963 m
->parameters_fragment
.what
,
965 "-t", m
->parameters_fragment
.fstype
? m
->parameters_fragment
.fstype
: "auto",
974 mount_unwatch_control_pid(m
);
976 r
= mount_spawn(m
, m
->control_command
, &m
->control_pid
);
980 mount_set_state(m
, MOUNT_REMOUNTING
);
985 log_unit_warning(UNIT(m
)->id
,
986 "%s failed to run 'remount' task: %s",
987 UNIT(m
)->id
, strerror(-r
));
988 m
->reload_result
= MOUNT_FAILURE_RESOURCES
;
989 mount_enter_mounted(m
, MOUNT_SUCCESS
);
992 static int mount_start(Unit
*u
) {
997 /* We cannot fulfill this request right now, try again later
999 if (m
->state
== MOUNT_UNMOUNTING
||
1000 m
->state
== MOUNT_UNMOUNTING_SIGTERM
||
1001 m
->state
== MOUNT_UNMOUNTING_SIGKILL
||
1002 m
->state
== MOUNT_MOUNTING_SIGTERM
||
1003 m
->state
== MOUNT_MOUNTING_SIGKILL
)
1006 /* Already on it! */
1007 if (m
->state
== MOUNT_MOUNTING
)
1010 assert(m
->state
== MOUNT_DEAD
|| m
->state
== MOUNT_FAILED
);
1012 m
->result
= MOUNT_SUCCESS
;
1013 m
->reload_result
= MOUNT_SUCCESS
;
1015 mount_enter_mounting(m
);
1019 static int mount_stop(Unit
*u
) {
1020 Mount
*m
= MOUNT(u
);
1025 if (m
->state
== MOUNT_UNMOUNTING
||
1026 m
->state
== MOUNT_UNMOUNTING_SIGKILL
||
1027 m
->state
== MOUNT_UNMOUNTING_SIGTERM
||
1028 m
->state
== MOUNT_MOUNTING_SIGTERM
||
1029 m
->state
== MOUNT_MOUNTING_SIGKILL
)
1032 assert(m
->state
== MOUNT_MOUNTING
||
1033 m
->state
== MOUNT_MOUNTING_DONE
||
1034 m
->state
== MOUNT_MOUNTED
||
1035 m
->state
== MOUNT_REMOUNTING
||
1036 m
->state
== MOUNT_REMOUNTING_SIGTERM
||
1037 m
->state
== MOUNT_REMOUNTING_SIGKILL
);
1039 mount_enter_unmounting(m
);
1043 static int mount_reload(Unit
*u
) {
1044 Mount
*m
= MOUNT(u
);
1048 if (m
->state
== MOUNT_MOUNTING_DONE
)
1051 assert(m
->state
== MOUNT_MOUNTED
);
1053 mount_enter_remounting(m
);
1057 static int mount_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
1058 Mount
*m
= MOUNT(u
);
1064 unit_serialize_item(u
, f
, "state", mount_state_to_string(m
->state
));
1065 unit_serialize_item(u
, f
, "result", mount_result_to_string(m
->result
));
1066 unit_serialize_item(u
, f
, "reload-result", mount_result_to_string(m
->reload_result
));
1068 if (m
->control_pid
> 0)
1069 unit_serialize_item_format(u
, f
, "control-pid", PID_FMT
, m
->control_pid
);
1071 if (m
->control_command_id
>= 0)
1072 unit_serialize_item(u
, f
, "control-command", mount_exec_command_to_string(m
->control_command_id
));
1077 static int mount_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
1078 Mount
*m
= MOUNT(u
);
1085 if (streq(key
, "state")) {
1088 if ((state
= mount_state_from_string(value
)) < 0)
1089 log_unit_debug(u
->id
, "Failed to parse state value %s", value
);
1091 m
->deserialized_state
= state
;
1092 } else if (streq(key
, "result")) {
1095 f
= mount_result_from_string(value
);
1097 log_unit_debug(UNIT(m
)->id
,
1098 "Failed to parse result value %s", value
);
1099 else if (f
!= MOUNT_SUCCESS
)
1102 } else if (streq(key
, "reload-result")) {
1105 f
= mount_result_from_string(value
);
1107 log_unit_debug(UNIT(m
)->id
,
1108 "Failed to parse reload result value %s", value
);
1109 else if (f
!= MOUNT_SUCCESS
)
1110 m
->reload_result
= f
;
1112 } else if (streq(key
, "control-pid")) {
1115 if (parse_pid(value
, &pid
) < 0)
1116 log_unit_debug(UNIT(m
)->id
,
1117 "Failed to parse control-pid value %s", value
);
1119 m
->control_pid
= pid
;
1120 } else if (streq(key
, "control-command")) {
1121 MountExecCommand id
;
1123 if ((id
= mount_exec_command_from_string(value
)) < 0)
1124 log_unit_debug(UNIT(m
)->id
,
1125 "Failed to parse exec-command value %s", value
);
1127 m
->control_command_id
= id
;
1128 m
->control_command
= m
->exec_command
+ id
;
1131 log_unit_debug(UNIT(m
)->id
,
1132 "Unknown serialization key '%s'", key
);
1137 _pure_
static UnitActiveState
mount_active_state(Unit
*u
) {
1140 return state_translation_table
[MOUNT(u
)->state
];
1143 _pure_
static const char *mount_sub_state_to_string(Unit
*u
) {
1146 return mount_state_to_string(MOUNT(u
)->state
);
1149 _pure_
static bool mount_check_gc(Unit
*u
) {
1150 Mount
*m
= MOUNT(u
);
1154 return m
->from_proc_self_mountinfo
;
1157 static void mount_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
1158 Mount
*m
= MOUNT(u
);
1164 if (pid
!= m
->control_pid
)
1169 if (is_clean_exit(code
, status
, NULL
))
1171 else if (code
== CLD_EXITED
)
1172 f
= MOUNT_FAILURE_EXIT_CODE
;
1173 else if (code
== CLD_KILLED
)
1174 f
= MOUNT_FAILURE_SIGNAL
;
1175 else if (code
== CLD_DUMPED
)
1176 f
= MOUNT_FAILURE_CORE_DUMP
;
1178 assert_not_reached("Unknown code");
1180 if (f
!= MOUNT_SUCCESS
)
1183 if (m
->control_command
) {
1184 exec_status_exit(&m
->control_command
->exec_status
, &m
->exec_context
, pid
, code
, status
);
1186 m
->control_command
= NULL
;
1187 m
->control_command_id
= _MOUNT_EXEC_COMMAND_INVALID
;
1190 log_unit_full(u
->id
,
1191 f
== MOUNT_SUCCESS
? LOG_DEBUG
: LOG_NOTICE
,
1192 "%s mount process exited, code=%s status=%i",
1193 u
->id
, sigchld_code_to_string(code
), status
);
1195 /* Note that mount(8) returning and the kernel sending us a
1196 * mount table change event might happen out-of-order. If an
1197 * operation succeed we assume the kernel will follow soon too
1198 * and already change into the resulting state. If it fails
1199 * we check if the kernel still knows about the mount. and
1200 * change state accordingly. */
1204 case MOUNT_MOUNTING
:
1205 case MOUNT_MOUNTING_DONE
:
1206 case MOUNT_MOUNTING_SIGKILL
:
1207 case MOUNT_MOUNTING_SIGTERM
:
1209 if (f
== MOUNT_SUCCESS
)
1210 mount_enter_mounted(m
, f
);
1211 else if (m
->from_proc_self_mountinfo
)
1212 mount_enter_mounted(m
, f
);
1214 mount_enter_dead(m
, f
);
1217 case MOUNT_REMOUNTING
:
1218 case MOUNT_REMOUNTING_SIGKILL
:
1219 case MOUNT_REMOUNTING_SIGTERM
:
1221 m
->reload_result
= f
;
1222 if (m
->from_proc_self_mountinfo
)
1223 mount_enter_mounted(m
, MOUNT_SUCCESS
);
1225 mount_enter_dead(m
, MOUNT_SUCCESS
);
1229 case MOUNT_UNMOUNTING
:
1230 case MOUNT_UNMOUNTING_SIGKILL
:
1231 case MOUNT_UNMOUNTING_SIGTERM
:
1233 if (f
== MOUNT_SUCCESS
)
1234 mount_enter_dead(m
, f
);
1235 else if (m
->from_proc_self_mountinfo
)
1236 mount_enter_mounted(m
, f
);
1238 mount_enter_dead(m
, f
);
1242 assert_not_reached("Uh, control process died at wrong time.");
1245 /* Notify clients about changed exit status */
1246 unit_add_to_dbus_queue(u
);
1249 static int mount_dispatch_timer(sd_event_source
*source
, usec_t usec
, void *userdata
) {
1250 Mount
*m
= MOUNT(userdata
);
1253 assert(m
->timer_event_source
== source
);
1257 case MOUNT_MOUNTING
:
1258 case MOUNT_MOUNTING_DONE
:
1259 log_unit_warning(UNIT(m
)->id
,
1260 "%s mounting timed out. Stopping.", UNIT(m
)->id
);
1261 mount_enter_signal(m
, MOUNT_MOUNTING_SIGTERM
, MOUNT_FAILURE_TIMEOUT
);
1264 case MOUNT_REMOUNTING
:
1265 log_unit_warning(UNIT(m
)->id
,
1266 "%s remounting timed out. Stopping.", UNIT(m
)->id
);
1267 m
->reload_result
= MOUNT_FAILURE_TIMEOUT
;
1268 mount_enter_mounted(m
, MOUNT_SUCCESS
);
1271 case MOUNT_UNMOUNTING
:
1272 log_unit_warning(UNIT(m
)->id
,
1273 "%s unmounting timed out. Stopping.", UNIT(m
)->id
);
1274 mount_enter_signal(m
, MOUNT_UNMOUNTING_SIGTERM
, MOUNT_FAILURE_TIMEOUT
);
1277 case MOUNT_MOUNTING_SIGTERM
:
1278 if (m
->kill_context
.send_sigkill
) {
1279 log_unit_warning(UNIT(m
)->id
,
1280 "%s mounting timed out. Killing.", UNIT(m
)->id
);
1281 mount_enter_signal(m
, MOUNT_MOUNTING_SIGKILL
, MOUNT_FAILURE_TIMEOUT
);
1283 log_unit_warning(UNIT(m
)->id
,
1284 "%s mounting timed out. Skipping SIGKILL. Ignoring.",
1287 if (m
->from_proc_self_mountinfo
)
1288 mount_enter_mounted(m
, MOUNT_FAILURE_TIMEOUT
);
1290 mount_enter_dead(m
, MOUNT_FAILURE_TIMEOUT
);
1294 case MOUNT_REMOUNTING_SIGTERM
:
1295 if (m
->kill_context
.send_sigkill
) {
1296 log_unit_warning(UNIT(m
)->id
,
1297 "%s remounting timed out. Killing.", UNIT(m
)->id
);
1298 mount_enter_signal(m
, MOUNT_REMOUNTING_SIGKILL
, MOUNT_FAILURE_TIMEOUT
);
1300 log_unit_warning(UNIT(m
)->id
,
1301 "%s remounting timed out. Skipping SIGKILL. Ignoring.",
1304 if (m
->from_proc_self_mountinfo
)
1305 mount_enter_mounted(m
, MOUNT_FAILURE_TIMEOUT
);
1307 mount_enter_dead(m
, MOUNT_FAILURE_TIMEOUT
);
1311 case MOUNT_UNMOUNTING_SIGTERM
:
1312 if (m
->kill_context
.send_sigkill
) {
1313 log_unit_warning(UNIT(m
)->id
,
1314 "%s unmounting timed out. Killing.", UNIT(m
)->id
);
1315 mount_enter_signal(m
, MOUNT_UNMOUNTING_SIGKILL
, MOUNT_FAILURE_TIMEOUT
);
1317 log_unit_warning(UNIT(m
)->id
,
1318 "%s unmounting timed out. Skipping SIGKILL. Ignoring.",
1321 if (m
->from_proc_self_mountinfo
)
1322 mount_enter_mounted(m
, MOUNT_FAILURE_TIMEOUT
);
1324 mount_enter_dead(m
, MOUNT_FAILURE_TIMEOUT
);
1328 case MOUNT_MOUNTING_SIGKILL
:
1329 case MOUNT_REMOUNTING_SIGKILL
:
1330 case MOUNT_UNMOUNTING_SIGKILL
:
1331 log_unit_warning(UNIT(m
)->id
,
1332 "%s mount process still around after 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 assert_not_reached("Timeout at wrong time.");
1348 static int mount_add_one(
1352 const char *options
,
1356 _cleanup_free_
char *e
= NULL
, *w
= NULL
, *o
= NULL
, *f
= NULL
;
1357 bool load_extras
= false;
1359 bool delete, changed
= false;
1369 /* Ignore API mount points. They should never be referenced in
1370 * dependencies ever. */
1371 if (mount_point_is_api(where
) || mount_point_ignore(where
))
1374 if (streq(fstype
, "autofs"))
1377 /* probably some kind of swap, ignore */
1378 if (!is_path(where
))
1381 e
= unit_name_from_path(where
, ".mount");
1385 u
= manager_get_unit(m
, e
);
1389 u
= unit_new(m
, sizeof(Mount
));
1393 r
= unit_add_name(u
, e
);
1397 MOUNT(u
)->where
= strdup(where
);
1398 if (!MOUNT(u
)->where
) {
1403 u
->source_path
= strdup("/proc/self/mountinfo");
1404 if (!u
->source_path
) {
1410 if (m
->running_as
== SYSTEMD_SYSTEM
) {
1413 target
= fstype_is_network(fstype
) ? SPECIAL_REMOTE_FS_TARGET
: SPECIAL_LOCAL_FS_TARGET
;
1415 r
= unit_add_dependency_by_name(u
, UNIT_BEFORE
, target
, NULL
, true);
1419 if (should_umount(MOUNT(u
))) {
1420 r
= unit_add_dependency_by_name(u
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
1426 unit_add_to_load_queue(u
);
1431 if (!MOUNT(u
)->where
) {
1432 MOUNT(u
)->where
= strdup(where
);
1433 if (!MOUNT(u
)->where
) {
1439 if (u
->load_state
== UNIT_NOT_FOUND
) {
1440 u
->load_state
= UNIT_LOADED
;
1443 /* Load in the extras later on, after we
1444 * finished initialization of the unit */
1451 o
= strdup(options
);
1453 if (!w
|| !o
|| !f
) {
1458 p
= &MOUNT(u
)->parameters_proc_self_mountinfo
;
1460 changed
= changed
||
1461 !streq_ptr(p
->options
, options
) ||
1462 !streq_ptr(p
->what
, what
) ||
1463 !streq_ptr(p
->fstype
, fstype
);
1466 MOUNT(u
)->is_mounted
= true;
1467 MOUNT(u
)->just_mounted
= !MOUNT(u
)->from_proc_self_mountinfo
;
1468 MOUNT(u
)->just_changed
= changed
;
1471 MOUNT(u
)->from_proc_self_mountinfo
= true;
1486 r
= mount_add_extras(MOUNT(u
));
1492 unit_add_to_dbus_queue(u
);
1503 static int mount_load_proc_self_mountinfo(Manager
*m
, bool set_flags
) {
1509 rewind(m
->proc_self_mountinfo
);
1512 _cleanup_free_
char *device
= NULL
, *path
= NULL
, *options
= NULL
, *options2
= NULL
, *fstype
= NULL
, *d
= NULL
, *p
= NULL
, *o
= NULL
;
1515 k
= fscanf(m
->proc_self_mountinfo
,
1516 "%*s " /* (1) mount id */
1517 "%*s " /* (2) parent id */
1518 "%*s " /* (3) major:minor */
1519 "%*s " /* (4) root */
1520 "%ms " /* (5) mount point */
1521 "%ms" /* (6) mount options */
1522 "%*[^-]" /* (7) optional fields */
1523 "- " /* (8) separator */
1524 "%ms " /* (9) file system type */
1525 "%ms" /* (10) mount source */
1526 "%ms" /* (11) mount options 2 */
1527 "%*[^\n]", /* some rubbish at the end */
1538 log_warning("Failed to parse /proc/self/mountinfo:%u.", i
);
1542 o
= strjoin(options
, ",", options2
, NULL
);
1546 d
= cunescape(device
);
1547 p
= cunescape(path
);
1551 k
= mount_add_one(m
, d
, p
, o
, fstype
, set_flags
);
1559 static void mount_shutdown(Manager
*m
) {
1562 m
->mount_event_source
= sd_event_source_unref(m
->mount_event_source
);
1564 if (m
->proc_self_mountinfo
) {
1565 fclose(m
->proc_self_mountinfo
);
1566 m
->proc_self_mountinfo
= NULL
;
1570 static int mount_get_timeout(Unit
*u
, uint64_t *timeout
) {
1571 Mount
*m
= MOUNT(u
);
1574 if (!m
->timer_event_source
)
1577 r
= sd_event_source_get_time(m
->timer_event_source
, timeout
);
1584 static int mount_enumerate(Manager
*m
) {
1588 if (!m
->proc_self_mountinfo
) {
1589 m
->proc_self_mountinfo
= fopen("/proc/self/mountinfo", "re");
1590 if (!m
->proc_self_mountinfo
)
1593 r
= sd_event_add_io(m
->event
, &m
->mount_event_source
, fileno(m
->proc_self_mountinfo
), EPOLLPRI
, mount_dispatch_io
, m
);
1597 /* Dispatch this before we dispatch SIGCHLD, so that
1598 * we always get the events from /proc/self/mountinfo
1599 * before the SIGCHLD of /bin/mount. */
1600 r
= sd_event_source_set_priority(m
->mount_event_source
, -10);
1605 r
= mount_load_proc_self_mountinfo(m
, false);
1616 static int mount_dispatch_io(sd_event_source
*source
, int fd
, uint32_t revents
, void *userdata
) {
1617 Manager
*m
= userdata
;
1622 assert(revents
& EPOLLPRI
);
1624 /* The manager calls this for every fd event happening on the
1625 * /proc/self/mountinfo file, which informs us about mounting
1628 r
= mount_load_proc_self_mountinfo(m
, true);
1630 log_error_errno(r
, "Failed to reread /proc/self/mountinfo: %m");
1632 /* Reset flags, just in case, for later calls */
1633 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_MOUNT
]) {
1634 Mount
*mount
= MOUNT(u
);
1636 mount
->is_mounted
= mount
->just_mounted
= mount
->just_changed
= false;
1642 manager_dispatch_load_queue(m
);
1644 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_MOUNT
]) {
1645 Mount
*mount
= MOUNT(u
);
1647 if (!mount
->is_mounted
) {
1649 mount
->from_proc_self_mountinfo
= false;
1651 switch (mount
->state
) {
1654 /* This has just been unmounted by
1655 * somebody else, follow the state
1657 mount_enter_dead(mount
, MOUNT_SUCCESS
);
1664 } else if (mount
->just_mounted
|| mount
->just_changed
) {
1666 /* New or changed mount entry */
1668 switch (mount
->state
) {
1672 /* This has just been mounted by
1673 * somebody else, follow the state
1675 mount_enter_mounted(mount
, MOUNT_SUCCESS
);
1678 case MOUNT_MOUNTING
:
1679 mount_set_state(mount
, MOUNT_MOUNTING_DONE
);
1683 /* Nothing really changed, but let's
1684 * issue an notification call
1685 * nonetheless, in case somebody is
1686 * waiting for this. (e.g. file system
1687 * ro/rw remounts.) */
1688 mount_set_state(mount
, mount
->state
);
1693 /* Reset the flags for later calls */
1694 mount
->is_mounted
= mount
->just_mounted
= mount
->just_changed
= false;
1700 static void mount_reset_failed(Unit
*u
) {
1701 Mount
*m
= MOUNT(u
);
1705 if (m
->state
== MOUNT_FAILED
)
1706 mount_set_state(m
, MOUNT_DEAD
);
1708 m
->result
= MOUNT_SUCCESS
;
1709 m
->reload_result
= MOUNT_SUCCESS
;
1712 static int mount_kill(Unit
*u
, KillWho who
, int signo
, sd_bus_error
*error
) {
1713 return unit_kill_common(u
, who
, signo
, -1, MOUNT(u
)->control_pid
, error
);
1716 static const char* const mount_state_table
[_MOUNT_STATE_MAX
] = {
1717 [MOUNT_DEAD
] = "dead",
1718 [MOUNT_MOUNTING
] = "mounting",
1719 [MOUNT_MOUNTING_DONE
] = "mounting-done",
1720 [MOUNT_MOUNTED
] = "mounted",
1721 [MOUNT_REMOUNTING
] = "remounting",
1722 [MOUNT_UNMOUNTING
] = "unmounting",
1723 [MOUNT_MOUNTING_SIGTERM
] = "mounting-sigterm",
1724 [MOUNT_MOUNTING_SIGKILL
] = "mounting-sigkill",
1725 [MOUNT_REMOUNTING_SIGTERM
] = "remounting-sigterm",
1726 [MOUNT_REMOUNTING_SIGKILL
] = "remounting-sigkill",
1727 [MOUNT_UNMOUNTING_SIGTERM
] = "unmounting-sigterm",
1728 [MOUNT_UNMOUNTING_SIGKILL
] = "unmounting-sigkill",
1729 [MOUNT_FAILED
] = "failed"
1732 DEFINE_STRING_TABLE_LOOKUP(mount_state
, MountState
);
1734 static const char* const mount_exec_command_table
[_MOUNT_EXEC_COMMAND_MAX
] = {
1735 [MOUNT_EXEC_MOUNT
] = "ExecMount",
1736 [MOUNT_EXEC_UNMOUNT
] = "ExecUnmount",
1737 [MOUNT_EXEC_REMOUNT
] = "ExecRemount",
1740 DEFINE_STRING_TABLE_LOOKUP(mount_exec_command
, MountExecCommand
);
1742 static const char* const mount_result_table
[_MOUNT_RESULT_MAX
] = {
1743 [MOUNT_SUCCESS
] = "success",
1744 [MOUNT_FAILURE_RESOURCES
] = "resources",
1745 [MOUNT_FAILURE_TIMEOUT
] = "timeout",
1746 [MOUNT_FAILURE_EXIT_CODE
] = "exit-code",
1747 [MOUNT_FAILURE_SIGNAL
] = "signal",
1748 [MOUNT_FAILURE_CORE_DUMP
] = "core-dump"
1751 DEFINE_STRING_TABLE_LOOKUP(mount_result
, MountResult
);
1753 const UnitVTable mount_vtable
= {
1754 .object_size
= sizeof(Mount
),
1755 .exec_context_offset
= offsetof(Mount
, exec_context
),
1756 .cgroup_context_offset
= offsetof(Mount
, cgroup_context
),
1757 .kill_context_offset
= offsetof(Mount
, kill_context
),
1758 .exec_runtime_offset
= offsetof(Mount
, exec_runtime
),
1764 .private_section
= "Mount",
1767 .no_instances
= true,
1773 .coldplug
= mount_coldplug
,
1777 .start
= mount_start
,
1779 .reload
= mount_reload
,
1783 .serialize
= mount_serialize
,
1784 .deserialize_item
= mount_deserialize_item
,
1786 .active_state
= mount_active_state
,
1787 .sub_state_to_string
= mount_sub_state_to_string
,
1789 .check_gc
= mount_check_gc
,
1791 .sigchld_event
= mount_sigchld_event
,
1793 .reset_failed
= mount_reset_failed
,
1795 .bus_interface
= "org.freedesktop.systemd1.Mount",
1796 .bus_vtable
= bus_mount_vtable
,
1797 .bus_set_property
= bus_mount_set_property
,
1798 .bus_commit_properties
= bus_mount_commit_properties
,
1800 .get_timeout
= mount_get_timeout
,
1802 .can_transient
= true,
1804 .enumerate
= mount_enumerate
,
1805 .shutdown
= mount_shutdown
,
1807 .status_message_formats
= {
1808 .starting_stopping
= {
1809 [0] = "Mounting %s...",
1810 [1] = "Unmounting %s...",
1812 .finished_start_job
= {
1813 [JOB_DONE
] = "Mounted %s.",
1814 [JOB_FAILED
] = "Failed to mount %s.",
1815 [JOB_DEPENDENCY
] = "Dependency failed for %s.",
1816 [JOB_TIMEOUT
] = "Timed out mounting %s.",
1818 .finished_stop_job
= {
1819 [JOB_DONE
] = "Unmounted %s.",
1820 [JOB_FAILED
] = "Failed unmounting %s.",
1821 [JOB_TIMEOUT
] = "Timed out unmounting %s.",