1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
25 #include <sys/epoll.h>
31 #include "load-fragment.h"
32 #include "load-dropin.h"
34 #include "sd-messages.h"
37 #include "path-util.h"
38 #include "mount-setup.h"
39 #include "unit-name.h"
40 #include "dbus-mount.h"
42 #include "bus-errors.h"
43 #include "exit-status.h"
46 static const UnitActiveState state_translation_table
[_MOUNT_STATE_MAX
] = {
47 [MOUNT_DEAD
] = UNIT_INACTIVE
,
48 [MOUNT_MOUNTING
] = UNIT_ACTIVATING
,
49 [MOUNT_MOUNTING_DONE
] = UNIT_ACTIVE
,
50 [MOUNT_MOUNTED
] = UNIT_ACTIVE
,
51 [MOUNT_REMOUNTING
] = UNIT_RELOADING
,
52 [MOUNT_UNMOUNTING
] = UNIT_DEACTIVATING
,
53 [MOUNT_MOUNTING_SIGTERM
] = UNIT_DEACTIVATING
,
54 [MOUNT_MOUNTING_SIGKILL
] = UNIT_DEACTIVATING
,
55 [MOUNT_REMOUNTING_SIGTERM
] = UNIT_RELOADING
,
56 [MOUNT_REMOUNTING_SIGKILL
] = UNIT_RELOADING
,
57 [MOUNT_UNMOUNTING_SIGTERM
] = UNIT_DEACTIVATING
,
58 [MOUNT_UNMOUNTING_SIGKILL
] = UNIT_DEACTIVATING
,
59 [MOUNT_FAILED
] = UNIT_FAILED
62 static void mount_init(Unit
*u
) {
66 assert(u
->load_state
== UNIT_STUB
);
68 m
->timeout_usec
= DEFAULT_TIMEOUT_USEC
;
69 m
->directory_mode
= 0755;
71 exec_context_init(&m
->exec_context
);
73 if (unit_has_name(u
, "-.mount")) {
74 /* Don't allow start/stop for root directory */
75 UNIT(m
)->refuse_manual_start
= true;
76 UNIT(m
)->refuse_manual_stop
= true;
78 /* The stdio/kmsg bridge socket is on /, in order to avoid a
79 * dep loop, don't use kmsg logging for -.mount */
80 m
->exec_context
.std_output
= u
->manager
->default_std_output
;
81 m
->exec_context
.std_error
= u
->manager
->default_std_error
;
84 kill_context_init(&m
->kill_context
);
85 cgroup_context_init(&m
->cgroup_context
);
87 /* We need to make sure that /bin/mount is always called in
88 * the same process group as us, so that the autofs kernel
89 * side doesn't send us another mount request while we are
90 * already trying to comply its last one. */
91 m
->exec_context
.same_pgrp
= true;
93 m
->timer_watch
.type
= WATCH_INVALID
;
95 m
->control_command_id
= _MOUNT_EXEC_COMMAND_INVALID
;
97 UNIT(m
)->ignore_on_isolate
= true;
100 static void mount_unwatch_control_pid(Mount
*m
) {
103 if (m
->control_pid
<= 0)
106 unit_unwatch_pid(UNIT(m
), m
->control_pid
);
110 static void mount_parameters_done(MountParameters
*p
) {
117 p
->what
= p
->options
= p
->fstype
= NULL
;
120 static void mount_done(Unit
*u
) {
128 mount_parameters_done(&m
->parameters_proc_self_mountinfo
);
129 mount_parameters_done(&m
->parameters_fragment
);
131 cgroup_context_done(&m
->cgroup_context
);
132 exec_context_done(&m
->exec_context
, manager_is_reloading_or_reexecuting(u
->manager
));
133 exec_command_done_array(m
->exec_command
, _MOUNT_EXEC_COMMAND_MAX
);
134 m
->control_command
= NULL
;
136 mount_unwatch_control_pid(m
);
138 unit_unwatch_timer(u
, &m
->timer_watch
);
141 _pure_
static MountParameters
* get_mount_parameters_fragment(Mount
*m
) {
144 if (m
->from_fragment
)
145 return &m
->parameters_fragment
;
150 _pure_
static MountParameters
* get_mount_parameters(Mount
*m
) {
153 if (m
->from_proc_self_mountinfo
)
154 return &m
->parameters_proc_self_mountinfo
;
156 return get_mount_parameters_fragment(m
);
159 static int mount_add_mount_links(Mount
*m
) {
166 pm
= get_mount_parameters_fragment(m
);
168 /* Adds in links to other mount points that might lie below or
169 * above us in the hierarchy */
171 LIST_FOREACH(units_by_type
, other
, UNIT(m
)->manager
->units_by_type
[UNIT_MOUNT
]) {
172 Mount
*n
= MOUNT(other
);
178 if (UNIT(n
)->load_state
!= UNIT_LOADED
)
181 pn
= get_mount_parameters_fragment(n
);
183 if (path_startswith(m
->where
, n
->where
)) {
185 if ((r
= unit_add_dependency(UNIT(m
), UNIT_AFTER
, UNIT(n
), true)) < 0)
189 if ((r
= unit_add_dependency(UNIT(m
), UNIT_REQUIRES
, UNIT(n
), true)) < 0)
192 } else if (path_startswith(n
->where
, m
->where
)) {
194 if ((r
= unit_add_dependency(UNIT(n
), UNIT_AFTER
, UNIT(m
), true)) < 0)
198 if ((r
= unit_add_dependency(UNIT(n
), UNIT_REQUIRES
, UNIT(m
), true)) < 0)
201 } else if (pm
&& pm
->what
&& path_startswith(pm
->what
, n
->where
)) {
203 if ((r
= unit_add_dependency(UNIT(m
), UNIT_AFTER
, UNIT(n
), true)) < 0)
206 if ((r
= unit_add_dependency(UNIT(m
), UNIT_REQUIRES
, UNIT(n
), true)) < 0)
209 } else if (pn
&& pn
->what
&& path_startswith(pn
->what
, m
->where
)) {
211 if ((r
= unit_add_dependency(UNIT(n
), UNIT_AFTER
, UNIT(m
), true)) < 0)
214 if ((r
= unit_add_dependency(UNIT(n
), UNIT_REQUIRES
, UNIT(m
), true)) < 0)
222 static int mount_add_swap_links(Mount
*m
) {
228 LIST_FOREACH(units_by_type
, other
, UNIT(m
)->manager
->units_by_type
[UNIT_SWAP
]) {
229 r
= swap_add_one_mount_link(SWAP(other
), m
);
237 static int mount_add_path_links(Mount
*m
) {
243 LIST_FOREACH(units_by_type
, other
, UNIT(m
)->manager
->units_by_type
[UNIT_PATH
]) {
244 r
= path_add_one_mount_link(PATH(other
), m
);
252 static int mount_add_automount_links(Mount
*m
) {
258 LIST_FOREACH(units_by_type
, other
, UNIT(m
)->manager
->units_by_type
[UNIT_AUTOMOUNT
]) {
259 r
= automount_add_one_mount_link(AUTOMOUNT(other
), m
);
267 static int mount_add_socket_links(Mount
*m
) {
273 LIST_FOREACH(units_by_type
, other
, UNIT(m
)->manager
->units_by_type
[UNIT_SOCKET
]) {
274 r
= socket_add_one_mount_link(SOCKET(other
), m
);
282 static int mount_add_requires_mounts_links(Mount
*m
) {
288 LIST_FOREACH(has_requires_mounts_for
, other
, UNIT(m
)->manager
->has_requires_mounts_for
) {
289 r
= unit_add_one_mount_link(other
, m
);
297 static char* mount_test_option(const char *haystack
, const char *needle
) {
298 struct mntent me
= { .mnt_opts
= (char*) haystack
};
302 /* Like glibc's hasmntopt(), but works on a string, not a
308 return hasmntopt(&me
, needle
);
311 static bool mount_is_network(MountParameters
*p
) {
314 if (mount_test_option(p
->options
, "_netdev"))
317 if (p
->fstype
&& fstype_is_network(p
->fstype
))
323 static bool mount_is_bind(MountParameters
*p
) {
326 if (mount_test_option(p
->options
, "bind"))
329 if (p
->fstype
&& streq(p
->fstype
, "bind"))
332 if (mount_test_option(p
->options
, "rbind"))
335 if (p
->fstype
&& streq(p
->fstype
, "rbind"))
341 static bool needs_quota(MountParameters
*p
) {
344 if (mount_is_network(p
))
347 if (mount_is_bind(p
))
350 return mount_test_option(p
->options
, "usrquota") ||
351 mount_test_option(p
->options
, "grpquota") ||
352 mount_test_option(p
->options
, "quota") ||
353 mount_test_option(p
->options
, "usrjquota") ||
354 mount_test_option(p
->options
, "grpjquota");
357 static int mount_add_device_links(Mount
*m
) {
363 p
= get_mount_parameters_fragment(m
);
370 if (mount_is_bind(p
))
373 if (!is_device_path(p
->what
))
376 if (path_equal(m
->where
, "/"))
379 r
= unit_add_node_link(UNIT(m
), p
->what
, false);
384 UNIT(m
)->manager
->running_as
== SYSTEMD_SYSTEM
) {
387 /* Let's add in the fsck service */
389 /* aka SPECIAL_FSCK_SERVICE */
390 name
= unit_name_from_path_instance("systemd-fsck", p
->what
, ".service");
394 r
= manager_load_unit_prepare(UNIT(m
)->manager
, name
, NULL
, NULL
, &fsck
);
396 log_warning_unit(name
,
397 "Failed to prepare unit %s: %s", name
, strerror(-r
));
403 SERVICE(fsck
)->fsck_passno
= p
->passno
;
405 r
= unit_add_two_dependencies(UNIT(m
), UNIT_AFTER
, UNIT_REQUIRES
, fsck
, true);
413 static int mount_add_quota_links(Mount
*m
) {
419 if (UNIT(m
)->manager
->running_as
!= SYSTEMD_SYSTEM
)
422 p
= get_mount_parameters_fragment(m
);
429 r
= unit_add_two_dependencies_by_name(UNIT(m
), UNIT_BEFORE
, UNIT_WANTS
, SPECIAL_QUOTACHECK_SERVICE
, NULL
, true);
433 r
= unit_add_two_dependencies_by_name(UNIT(m
), UNIT_BEFORE
, UNIT_WANTS
, SPECIAL_QUOTAON_SERVICE
, NULL
, true);
440 static int mount_add_default_dependencies(Mount
*m
) {
441 const char *after
, *after2
, *online
;
447 if (UNIT(m
)->manager
->running_as
!= SYSTEMD_SYSTEM
)
450 p
= get_mount_parameters(m
);
455 if (path_equal(m
->where
, "/"))
458 if (mount_is_network(p
)) {
459 after
= SPECIAL_REMOTE_FS_PRE_TARGET
;
460 after2
= SPECIAL_NETWORK_TARGET
;
461 online
= SPECIAL_NETWORK_ONLINE_TARGET
;
463 after
= SPECIAL_LOCAL_FS_PRE_TARGET
;
468 r
= unit_add_dependency_by_name(UNIT(m
), UNIT_AFTER
, after
, NULL
, true);
473 r
= unit_add_dependency_by_name(UNIT(m
), UNIT_AFTER
, after2
, NULL
, true);
479 r
= unit_add_two_dependencies_by_name(UNIT(m
), UNIT_WANTS
, UNIT_AFTER
, online
, NULL
, true);
484 r
= unit_add_two_dependencies_by_name(UNIT(m
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
491 static int mount_fix_timeouts(Mount
*m
) {
493 const char *timeout
= NULL
;
502 p
= get_mount_parameters_fragment(m
);
506 /* Allow configuration how long we wait for a device that
507 * backs a mount point to show up. This is useful to support
508 * endless device timeouts for devices that show up only after
509 * user input, like crypto devices. */
511 if ((timeout
= mount_test_option(p
->options
, "comment=systemd.device-timeout")))
513 else if ((timeout
= mount_test_option(p
->options
, "x-systemd.device-timeout")))
518 t
= strndup(timeout
, strcspn(timeout
, ",;" WHITESPACE
));
522 r
= parse_sec(t
, &u
);
526 log_warning_unit(UNIT(m
)->id
,
527 "Failed to parse timeout for %s, ignoring: %s",
532 SET_FOREACH(other
, UNIT(m
)->dependencies
[UNIT_AFTER
], i
) {
533 if (other
->type
!= UNIT_DEVICE
)
536 other
->job_timeout
= u
;
542 static int mount_verify(Mount
*m
) {
547 if (UNIT(m
)->load_state
!= UNIT_LOADED
)
550 if (!m
->from_fragment
&& !m
->from_proc_self_mountinfo
)
553 if (!(e
= unit_name_from_path(m
->where
, ".mount")))
556 b
= unit_has_name(UNIT(m
), e
);
560 log_error_unit(UNIT(m
)->id
,
561 "%s's Where setting doesn't match unit name. Refusing.",
566 if (mount_point_is_api(m
->where
) || mount_point_ignore(m
->where
)) {
567 log_error_unit(UNIT(m
)->id
,
568 "Cannot create mount unit for API file system %s. Refusing.",
573 if (UNIT(m
)->fragment_path
&& !m
->parameters_fragment
.what
) {
574 log_error_unit(UNIT(m
)->id
,
575 "%s's What setting is missing. Refusing.", UNIT(m
)->id
);
579 if (m
->exec_context
.pam_name
&& m
->kill_context
.kill_mode
!= KILL_CONTROL_GROUP
) {
580 log_error_unit(UNIT(m
)->id
,
581 "%s has PAM enabled. Kill mode must be set to control-group'. Refusing.",
589 static int mount_add_extras(Mount
*m
) {
593 if (UNIT(m
)->fragment_path
)
594 m
->from_fragment
= true;
597 m
->where
= unit_name_to_path(u
->id
);
602 path_kill_slashes(m
->where
);
604 r
= unit_add_exec_dependencies(u
, &m
->exec_context
);
608 if (!UNIT(m
)->description
) {
609 r
= unit_set_description(u
, m
->where
);
614 r
= mount_add_device_links(m
);
618 r
= mount_add_mount_links(m
);
622 r
= mount_add_socket_links(m
);
626 r
= mount_add_swap_links(m
);
630 r
= mount_add_path_links(m
);
634 r
= mount_add_requires_mounts_links(m
);
638 r
= mount_add_automount_links(m
);
642 r
= mount_add_quota_links(m
);
646 if (UNIT(m
)->default_dependencies
) {
647 r
= mount_add_default_dependencies(m
);
652 r
= unit_add_default_slice(u
);
656 r
= mount_fix_timeouts(m
);
663 static int mount_load(Unit
*u
) {
668 assert(u
->load_state
== UNIT_STUB
);
670 if (m
->from_proc_self_mountinfo
)
671 r
= unit_load_fragment_and_dropin_optional(u
);
673 r
= unit_load_fragment_and_dropin(u
);
678 /* This is a new unit? Then let's add in some extras */
679 if (u
->load_state
== UNIT_LOADED
) {
680 r
= mount_add_extras(m
);
684 r
= unit_exec_context_defaults(u
, &m
->exec_context
);
689 return mount_verify(m
);
692 static int mount_notify_automount(Mount
*m
, int status
) {
699 SET_FOREACH(p
, UNIT(m
)->dependencies
[UNIT_TRIGGERED_BY
], i
)
700 if (p
->type
== UNIT_AUTOMOUNT
) {
701 r
= automount_send_ready(AUTOMOUNT(p
), status
);
709 static void mount_set_state(Mount
*m
, MountState state
) {
710 MountState old_state
;
713 old_state
= m
->state
;
716 if (state
!= MOUNT_MOUNTING
&&
717 state
!= MOUNT_MOUNTING_DONE
&&
718 state
!= MOUNT_REMOUNTING
&&
719 state
!= MOUNT_UNMOUNTING
&&
720 state
!= MOUNT_MOUNTING_SIGTERM
&&
721 state
!= MOUNT_MOUNTING_SIGKILL
&&
722 state
!= MOUNT_UNMOUNTING_SIGTERM
&&
723 state
!= MOUNT_UNMOUNTING_SIGKILL
&&
724 state
!= MOUNT_REMOUNTING_SIGTERM
&&
725 state
!= MOUNT_REMOUNTING_SIGKILL
) {
726 unit_unwatch_timer(UNIT(m
), &m
->timer_watch
);
727 mount_unwatch_control_pid(m
);
728 m
->control_command
= NULL
;
729 m
->control_command_id
= _MOUNT_EXEC_COMMAND_INVALID
;
732 if (state
== MOUNT_MOUNTED
||
733 state
== MOUNT_REMOUNTING
)
734 mount_notify_automount(m
, 0);
735 else if (state
== MOUNT_DEAD
||
736 state
== MOUNT_UNMOUNTING
||
737 state
== MOUNT_MOUNTING_SIGTERM
||
738 state
== MOUNT_MOUNTING_SIGKILL
||
739 state
== MOUNT_REMOUNTING_SIGTERM
||
740 state
== MOUNT_REMOUNTING_SIGKILL
||
741 state
== MOUNT_UNMOUNTING_SIGTERM
||
742 state
== MOUNT_UNMOUNTING_SIGKILL
||
743 state
== MOUNT_FAILED
) {
744 if (state
!= old_state
)
745 mount_notify_automount(m
, -ENODEV
);
748 if (state
!= old_state
)
749 log_debug_unit(UNIT(m
)->id
,
750 "%s changed %s -> %s",
752 mount_state_to_string(old_state
),
753 mount_state_to_string(state
));
755 unit_notify(UNIT(m
), state_translation_table
[old_state
], state_translation_table
[state
], m
->reload_result
== MOUNT_SUCCESS
);
756 m
->reload_result
= MOUNT_SUCCESS
;
759 static int mount_coldplug(Unit
*u
) {
761 MountState new_state
= MOUNT_DEAD
;
765 assert(m
->state
== MOUNT_DEAD
);
767 if (m
->deserialized_state
!= m
->state
)
768 new_state
= m
->deserialized_state
;
769 else if (m
->from_proc_self_mountinfo
)
770 new_state
= MOUNT_MOUNTED
;
772 if (new_state
!= m
->state
) {
774 if (new_state
== MOUNT_MOUNTING
||
775 new_state
== MOUNT_MOUNTING_DONE
||
776 new_state
== MOUNT_REMOUNTING
||
777 new_state
== MOUNT_UNMOUNTING
||
778 new_state
== MOUNT_MOUNTING_SIGTERM
||
779 new_state
== MOUNT_MOUNTING_SIGKILL
||
780 new_state
== MOUNT_UNMOUNTING_SIGTERM
||
781 new_state
== MOUNT_UNMOUNTING_SIGKILL
||
782 new_state
== MOUNT_REMOUNTING_SIGTERM
||
783 new_state
== MOUNT_REMOUNTING_SIGKILL
) {
785 if (m
->control_pid
<= 0)
788 r
= unit_watch_pid(UNIT(m
), m
->control_pid
);
792 r
= unit_watch_timer(UNIT(m
), CLOCK_MONOTONIC
, true, m
->timeout_usec
, &m
->timer_watch
);
797 mount_set_state(m
, new_state
);
803 static void mount_dump(Unit
*u
, FILE *f
, const char *prefix
) {
810 p
= get_mount_parameters(m
);
813 "%sMount State: %s\n"
817 "%sFile System Type: %s\n"
819 "%sFrom /proc/self/mountinfo: %s\n"
820 "%sFrom fragment: %s\n"
821 "%sDirectoryMode: %04o\n",
822 prefix
, mount_state_to_string(m
->state
),
823 prefix
, mount_result_to_string(m
->result
),
825 prefix
, p
? strna(p
->what
) : "n/a",
826 prefix
, p
? strna(p
->fstype
) : "n/a",
827 prefix
, p
? strna(p
->options
) : "n/a",
828 prefix
, yes_no(m
->from_proc_self_mountinfo
),
829 prefix
, yes_no(m
->from_fragment
),
830 prefix
, m
->directory_mode
);
832 if (m
->control_pid
> 0)
834 "%sControl PID: %lu\n",
835 prefix
, (unsigned long) m
->control_pid
);
837 exec_context_dump(&m
->exec_context
, f
, prefix
);
838 kill_context_dump(&m
->kill_context
, f
, prefix
);
841 static int mount_spawn(Mount
*m
, ExecCommand
*c
, pid_t
*_pid
) {
849 unit_realize_cgroup(UNIT(m
));
851 r
= unit_watch_timer(UNIT(m
), CLOCK_MONOTONIC
, true, m
->timeout_usec
, &m
->timer_watch
);
859 UNIT(m
)->manager
->environment
,
863 UNIT(m
)->manager
->confirm_spawn
,
864 UNIT(m
)->cgroup_mask
,
865 UNIT(m
)->cgroup_path
,
872 r
= unit_watch_pid(UNIT(m
), pid
);
874 /* FIXME: we need to do something here */
882 unit_unwatch_timer(UNIT(m
), &m
->timer_watch
);
887 static void mount_enter_dead(Mount
*m
, MountResult f
) {
890 if (f
!= MOUNT_SUCCESS
)
893 exec_context_tmp_dirs_done(&m
->exec_context
);
894 mount_set_state(m
, m
->result
!= MOUNT_SUCCESS
? MOUNT_FAILED
: MOUNT_DEAD
);
897 static void mount_enter_mounted(Mount
*m
, MountResult f
) {
900 if (f
!= MOUNT_SUCCESS
)
903 mount_set_state(m
, MOUNT_MOUNTED
);
906 static void mount_enter_signal(Mount
*m
, MountState state
, MountResult f
) {
911 if (f
!= MOUNT_SUCCESS
)
914 r
= unit_kill_context(
917 state
!= MOUNT_MOUNTING_SIGTERM
&& state
!= MOUNT_UNMOUNTING_SIGTERM
&& state
!= MOUNT_REMOUNTING_SIGTERM
,
925 r
= unit_watch_timer(UNIT(m
), CLOCK_MONOTONIC
, true, m
->timeout_usec
, &m
->timer_watch
);
929 mount_set_state(m
, state
);
930 } else if (state
== MOUNT_REMOUNTING_SIGTERM
|| state
== MOUNT_REMOUNTING_SIGKILL
)
931 mount_enter_mounted(m
, MOUNT_SUCCESS
);
933 mount_enter_dead(m
, MOUNT_SUCCESS
);
938 log_warning_unit(UNIT(m
)->id
,
939 "%s failed to kill processes: %s", UNIT(m
)->id
, strerror(-r
));
941 if (state
== MOUNT_REMOUNTING_SIGTERM
|| state
== MOUNT_REMOUNTING_SIGKILL
)
942 mount_enter_mounted(m
, MOUNT_FAILURE_RESOURCES
);
944 mount_enter_dead(m
, MOUNT_FAILURE_RESOURCES
);
947 void warn_if_dir_nonempty(const char *unit
, const char* where
) {
951 if (dir_is_empty(where
) > 0)
954 log_struct_unit(LOG_NOTICE
,
956 "MESSAGE=%s: Directory %s to mount over is not empty, mounting anyway.",
959 MESSAGE_ID(SD_MESSAGE_OVERMOUNTING
),
963 static void mount_enter_unmounting(Mount
*m
) {
968 m
->control_command_id
= MOUNT_EXEC_UNMOUNT
;
969 m
->control_command
= m
->exec_command
+ MOUNT_EXEC_UNMOUNT
;
971 if ((r
= exec_command_set(
978 mount_unwatch_control_pid(m
);
980 if ((r
= mount_spawn(m
, m
->control_command
, &m
->control_pid
)) < 0)
983 mount_set_state(m
, MOUNT_UNMOUNTING
);
988 log_warning_unit(UNIT(m
)->id
,
989 "%s failed to run 'umount' task: %s",
990 UNIT(m
)->id
, strerror(-r
));
991 mount_enter_mounted(m
, MOUNT_FAILURE_RESOURCES
);
994 static void mount_enter_mounting(Mount
*m
) {
1000 m
->control_command_id
= MOUNT_EXEC_MOUNT
;
1001 m
->control_command
= m
->exec_command
+ MOUNT_EXEC_MOUNT
;
1003 mkdir_p_label(m
->where
, m
->directory_mode
);
1005 warn_if_dir_nonempty(m
->meta
.id
, m
->where
);
1007 /* Create the source directory for bind-mounts if needed */
1008 p
= get_mount_parameters_fragment(m
);
1009 if (p
&& mount_is_bind(p
))
1010 mkdir_p_label(p
->what
, m
->directory_mode
);
1012 if (m
->from_fragment
)
1013 r
= exec_command_set(
1016 m
->parameters_fragment
.what
,
1018 "-t", m
->parameters_fragment
.fstype
? m
->parameters_fragment
.fstype
: "auto",
1019 m
->parameters_fragment
.options
? "-o" : NULL
, m
->parameters_fragment
.options
,
1027 mount_unwatch_control_pid(m
);
1029 r
= mount_spawn(m
, m
->control_command
, &m
->control_pid
);
1033 mount_set_state(m
, MOUNT_MOUNTING
);
1038 log_warning_unit(UNIT(m
)->id
,
1039 "%s failed to run 'mount' task: %s",
1040 UNIT(m
)->id
, strerror(-r
));
1041 mount_enter_dead(m
, MOUNT_FAILURE_RESOURCES
);
1044 static void mount_enter_mounting_done(Mount
*m
) {
1047 mount_set_state(m
, MOUNT_MOUNTING_DONE
);
1050 static void mount_enter_remounting(Mount
*m
) {
1055 m
->control_command_id
= MOUNT_EXEC_REMOUNT
;
1056 m
->control_command
= m
->exec_command
+ MOUNT_EXEC_REMOUNT
;
1058 if (m
->from_fragment
) {
1062 if (m
->parameters_fragment
.options
) {
1063 if (!(buf
= strappend("remount,", m
->parameters_fragment
.options
))) {
1072 r
= exec_command_set(
1075 m
->parameters_fragment
.what
,
1077 "-t", m
->parameters_fragment
.fstype
? m
->parameters_fragment
.fstype
: "auto",
1088 mount_unwatch_control_pid(m
);
1090 if ((r
= mount_spawn(m
, m
->control_command
, &m
->control_pid
)) < 0)
1093 mount_set_state(m
, MOUNT_REMOUNTING
);
1098 log_warning_unit(UNIT(m
)->id
,
1099 "%s failed to run 'remount' task: %s",
1100 UNIT(m
)->id
, strerror(-r
));
1101 m
->reload_result
= MOUNT_FAILURE_RESOURCES
;
1102 mount_enter_mounted(m
, MOUNT_SUCCESS
);
1105 static int mount_start(Unit
*u
) {
1106 Mount
*m
= MOUNT(u
);
1110 /* We cannot fulfill this request right now, try again later
1112 if (m
->state
== MOUNT_UNMOUNTING
||
1113 m
->state
== MOUNT_UNMOUNTING_SIGTERM
||
1114 m
->state
== MOUNT_UNMOUNTING_SIGKILL
||
1115 m
->state
== MOUNT_MOUNTING_SIGTERM
||
1116 m
->state
== MOUNT_MOUNTING_SIGKILL
)
1119 /* Already on it! */
1120 if (m
->state
== MOUNT_MOUNTING
)
1123 assert(m
->state
== MOUNT_DEAD
|| m
->state
== MOUNT_FAILED
);
1125 m
->result
= MOUNT_SUCCESS
;
1126 m
->reload_result
= MOUNT_SUCCESS
;
1128 mount_enter_mounting(m
);
1132 static int mount_stop(Unit
*u
) {
1133 Mount
*m
= MOUNT(u
);
1138 if (m
->state
== MOUNT_UNMOUNTING
||
1139 m
->state
== MOUNT_UNMOUNTING_SIGKILL
||
1140 m
->state
== MOUNT_UNMOUNTING_SIGTERM
||
1141 m
->state
== MOUNT_MOUNTING_SIGTERM
||
1142 m
->state
== MOUNT_MOUNTING_SIGKILL
)
1145 assert(m
->state
== MOUNT_MOUNTING
||
1146 m
->state
== MOUNT_MOUNTING_DONE
||
1147 m
->state
== MOUNT_MOUNTED
||
1148 m
->state
== MOUNT_REMOUNTING
||
1149 m
->state
== MOUNT_REMOUNTING_SIGTERM
||
1150 m
->state
== MOUNT_REMOUNTING_SIGKILL
);
1152 mount_enter_unmounting(m
);
1156 static int mount_reload(Unit
*u
) {
1157 Mount
*m
= MOUNT(u
);
1161 if (m
->state
== MOUNT_MOUNTING_DONE
)
1164 assert(m
->state
== MOUNT_MOUNTED
);
1166 mount_enter_remounting(m
);
1170 static int mount_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
1171 Mount
*m
= MOUNT(u
);
1177 unit_serialize_item(u
, f
, "state", mount_state_to_string(m
->state
));
1178 unit_serialize_item(u
, f
, "result", mount_result_to_string(m
->result
));
1179 unit_serialize_item(u
, f
, "reload-result", mount_result_to_string(m
->reload_result
));
1181 if (m
->control_pid
> 0)
1182 unit_serialize_item_format(u
, f
, "control-pid", "%lu", (unsigned long) m
->control_pid
);
1184 if (m
->control_command_id
>= 0)
1185 unit_serialize_item(u
, f
, "control-command", mount_exec_command_to_string(m
->control_command_id
));
1187 exec_context_serialize(&m
->exec_context
, UNIT(m
), f
);
1192 static int mount_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
1193 Mount
*m
= MOUNT(u
);
1200 if (streq(key
, "state")) {
1203 if ((state
= mount_state_from_string(value
)) < 0)
1204 log_debug_unit(u
->id
, "Failed to parse state value %s", value
);
1206 m
->deserialized_state
= state
;
1207 } else if (streq(key
, "result")) {
1210 f
= mount_result_from_string(value
);
1212 log_debug_unit(UNIT(m
)->id
,
1213 "Failed to parse result value %s", value
);
1214 else if (f
!= MOUNT_SUCCESS
)
1217 } else if (streq(key
, "reload-result")) {
1220 f
= mount_result_from_string(value
);
1222 log_debug_unit(UNIT(m
)->id
,
1223 "Failed to parse reload result value %s", value
);
1224 else if (f
!= MOUNT_SUCCESS
)
1225 m
->reload_result
= f
;
1227 } else if (streq(key
, "control-pid")) {
1230 if (parse_pid(value
, &pid
) < 0)
1231 log_debug_unit(UNIT(m
)->id
,
1232 "Failed to parse control-pid value %s", value
);
1234 m
->control_pid
= pid
;
1235 } else if (streq(key
, "control-command")) {
1236 MountExecCommand id
;
1238 if ((id
= mount_exec_command_from_string(value
)) < 0)
1239 log_debug_unit(UNIT(m
)->id
,
1240 "Failed to parse exec-command value %s", value
);
1242 m
->control_command_id
= id
;
1243 m
->control_command
= m
->exec_command
+ id
;
1245 } else if (streq(key
, "tmp-dir")) {
1252 m
->exec_context
.tmp_dir
= t
;
1253 } else if (streq(key
, "var-tmp-dir")) {
1260 m
->exec_context
.var_tmp_dir
= t
;
1262 log_debug_unit(UNIT(m
)->id
,
1263 "Unknown serialization key '%s'", key
);
1268 _pure_
static UnitActiveState
mount_active_state(Unit
*u
) {
1271 return state_translation_table
[MOUNT(u
)->state
];
1274 _pure_
static const char *mount_sub_state_to_string(Unit
*u
) {
1277 return mount_state_to_string(MOUNT(u
)->state
);
1280 _pure_
static bool mount_check_gc(Unit
*u
) {
1281 Mount
*m
= MOUNT(u
);
1285 return m
->from_proc_self_mountinfo
;
1288 static void mount_sigchld_event(Unit
*u
, pid_t pid
, int code
, int status
) {
1289 Mount
*m
= MOUNT(u
);
1295 if (pid
!= m
->control_pid
)
1300 if (is_clean_exit(code
, status
, NULL
))
1302 else if (code
== CLD_EXITED
)
1303 f
= MOUNT_FAILURE_EXIT_CODE
;
1304 else if (code
== CLD_KILLED
)
1305 f
= MOUNT_FAILURE_SIGNAL
;
1306 else if (code
== CLD_DUMPED
)
1307 f
= MOUNT_FAILURE_CORE_DUMP
;
1309 assert_not_reached("Unknown code");
1311 if (f
!= MOUNT_SUCCESS
)
1314 if (m
->control_command
) {
1315 exec_status_exit(&m
->control_command
->exec_status
, &m
->exec_context
, pid
, code
, status
);
1317 m
->control_command
= NULL
;
1318 m
->control_command_id
= _MOUNT_EXEC_COMMAND_INVALID
;
1321 log_full_unit(f
== MOUNT_SUCCESS
? LOG_DEBUG
: LOG_NOTICE
, u
->id
,
1322 "%s mount process exited, code=%s status=%i",
1323 u
->id
, sigchld_code_to_string(code
), status
);
1325 /* Note that mount(8) returning and the kernel sending us a
1326 * mount table change event might happen out-of-order. If an
1327 * operation succeed we assume the kernel will follow soon too
1328 * and already change into the resulting state. If it fails
1329 * we check if the kernel still knows about the mount. and
1330 * change state accordingly. */
1334 case MOUNT_MOUNTING
:
1335 case MOUNT_MOUNTING_DONE
:
1336 case MOUNT_MOUNTING_SIGKILL
:
1337 case MOUNT_MOUNTING_SIGTERM
:
1339 if (f
== MOUNT_SUCCESS
)
1340 mount_enter_mounted(m
, f
);
1341 else if (m
->from_proc_self_mountinfo
)
1342 mount_enter_mounted(m
, f
);
1344 mount_enter_dead(m
, f
);
1347 case MOUNT_REMOUNTING
:
1348 case MOUNT_REMOUNTING_SIGKILL
:
1349 case MOUNT_REMOUNTING_SIGTERM
:
1351 m
->reload_result
= f
;
1352 if (m
->from_proc_self_mountinfo
)
1353 mount_enter_mounted(m
, MOUNT_SUCCESS
);
1355 mount_enter_dead(m
, MOUNT_SUCCESS
);
1359 case MOUNT_UNMOUNTING
:
1360 case MOUNT_UNMOUNTING_SIGKILL
:
1361 case MOUNT_UNMOUNTING_SIGTERM
:
1363 if (f
== MOUNT_SUCCESS
)
1364 mount_enter_dead(m
, f
);
1365 else if (m
->from_proc_self_mountinfo
)
1366 mount_enter_mounted(m
, f
);
1368 mount_enter_dead(m
, f
);
1372 assert_not_reached("Uh, control process died at wrong time.");
1375 /* Notify clients about changed exit status */
1376 unit_add_to_dbus_queue(u
);
1379 static void mount_timer_event(Unit
*u
, uint64_t elapsed
, Watch
*w
) {
1380 Mount
*m
= MOUNT(u
);
1383 assert(elapsed
== 1);
1384 assert(w
== &m
->timer_watch
);
1388 case MOUNT_MOUNTING
:
1389 case MOUNT_MOUNTING_DONE
:
1390 log_warning_unit(u
->id
,
1391 "%s mounting timed out. Stopping.", u
->id
);
1392 mount_enter_signal(m
, MOUNT_MOUNTING_SIGTERM
, MOUNT_FAILURE_TIMEOUT
);
1395 case MOUNT_REMOUNTING
:
1396 log_warning_unit(u
->id
,
1397 "%s remounting timed out. Stopping.", u
->id
);
1398 m
->reload_result
= MOUNT_FAILURE_TIMEOUT
;
1399 mount_enter_mounted(m
, MOUNT_SUCCESS
);
1402 case MOUNT_UNMOUNTING
:
1403 log_warning_unit(u
->id
,
1404 "%s unmounting timed out. Stopping.", u
->id
);
1405 mount_enter_signal(m
, MOUNT_UNMOUNTING_SIGTERM
, MOUNT_FAILURE_TIMEOUT
);
1408 case MOUNT_MOUNTING_SIGTERM
:
1409 if (m
->kill_context
.send_sigkill
) {
1410 log_warning_unit(u
->id
,
1411 "%s mounting timed out. Killing.", u
->id
);
1412 mount_enter_signal(m
, MOUNT_MOUNTING_SIGKILL
, MOUNT_FAILURE_TIMEOUT
);
1414 log_warning_unit(u
->id
,
1415 "%s mounting timed out. Skipping SIGKILL. Ignoring.",
1418 if (m
->from_proc_self_mountinfo
)
1419 mount_enter_mounted(m
, MOUNT_FAILURE_TIMEOUT
);
1421 mount_enter_dead(m
, MOUNT_FAILURE_TIMEOUT
);
1425 case MOUNT_REMOUNTING_SIGTERM
:
1426 if (m
->kill_context
.send_sigkill
) {
1427 log_warning_unit(u
->id
,
1428 "%s remounting timed out. Killing.", u
->id
);
1429 mount_enter_signal(m
, MOUNT_REMOUNTING_SIGKILL
, MOUNT_FAILURE_TIMEOUT
);
1431 log_warning_unit(u
->id
,
1432 "%s remounting timed out. Skipping SIGKILL. Ignoring.",
1435 if (m
->from_proc_self_mountinfo
)
1436 mount_enter_mounted(m
, MOUNT_FAILURE_TIMEOUT
);
1438 mount_enter_dead(m
, MOUNT_FAILURE_TIMEOUT
);
1442 case MOUNT_UNMOUNTING_SIGTERM
:
1443 if (m
->kill_context
.send_sigkill
) {
1444 log_warning_unit(u
->id
,
1445 "%s unmounting timed out. Killing.", u
->id
);
1446 mount_enter_signal(m
, MOUNT_UNMOUNTING_SIGKILL
, MOUNT_FAILURE_TIMEOUT
);
1448 log_warning_unit(u
->id
,
1449 "%s unmounting timed out. Skipping SIGKILL. Ignoring.",
1452 if (m
->from_proc_self_mountinfo
)
1453 mount_enter_mounted(m
, MOUNT_FAILURE_TIMEOUT
);
1455 mount_enter_dead(m
, MOUNT_FAILURE_TIMEOUT
);
1459 case MOUNT_MOUNTING_SIGKILL
:
1460 case MOUNT_REMOUNTING_SIGKILL
:
1461 case MOUNT_UNMOUNTING_SIGKILL
:
1462 log_warning_unit(u
->id
,
1463 "%s mount process still around after SIGKILL. Ignoring.",
1466 if (m
->from_proc_self_mountinfo
)
1467 mount_enter_mounted(m
, MOUNT_FAILURE_TIMEOUT
);
1469 mount_enter_dead(m
, MOUNT_FAILURE_TIMEOUT
);
1473 assert_not_reached("Timeout at wrong time.");
1477 static int mount_add_one(
1481 const char *options
,
1488 char *e
, *w
= NULL
, *o
= NULL
, *f
= NULL
;
1490 bool load_extras
= false;
1498 /* Ignore API mount points. They should never be referenced in
1499 * dependencies ever. */
1500 if (mount_point_is_api(where
) || mount_point_ignore(where
))
1503 if (streq(fstype
, "autofs"))
1506 /* probably some kind of swap, ignore */
1507 if (!is_path(where
))
1510 e
= unit_name_from_path(where
, ".mount");
1514 u
= manager_get_unit(m
, e
);
1518 u
= unit_new(m
, sizeof(Mount
));
1524 r
= unit_add_name(u
, e
);
1530 MOUNT(u
)->where
= strdup(where
);
1531 if (!MOUNT(u
)->where
) {
1536 u
->source_path
= strdup("/proc/self/mountinfo");
1537 if (!u
->source_path
) {
1542 r
= unit_add_dependency_by_name(u
, UNIT_BEFORE
, SPECIAL_LOCAL_FS_TARGET
, NULL
, true);
1546 if (!path_equal(where
, "/") &&
1547 !path_equal(where
, "/usr")) {
1548 r
= unit_add_dependency_by_name(u
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
1553 unit_add_to_load_queue(u
);
1558 if (!MOUNT(u
)->where
) {
1559 MOUNT(u
)->where
= strdup(where
);
1560 if (!MOUNT(u
)->where
) {
1566 if (u
->load_state
== UNIT_NOT_FOUND
) {
1567 u
->load_state
= UNIT_LOADED
;
1570 /* Load in the extras later on, after we
1571 * finished initialization of the unit */
1576 if (!(w
= strdup(what
)) ||
1577 !(o
= strdup(options
)) ||
1578 !(f
= strdup(fstype
))) {
1583 p
= &MOUNT(u
)->parameters_proc_self_mountinfo
;
1585 MOUNT(u
)->is_mounted
= true;
1586 MOUNT(u
)->just_mounted
= !MOUNT(u
)->from_proc_self_mountinfo
;
1587 MOUNT(u
)->just_changed
= !streq_ptr(p
->options
, o
);
1590 MOUNT(u
)->from_proc_self_mountinfo
= true;
1604 r
= mount_add_extras(MOUNT(u
));
1609 unit_add_to_dbus_queue(u
);
1624 static int mount_load_proc_self_mountinfo(Manager
*m
, bool set_flags
) {
1627 char *device
, *path
, *options
, *options2
, *fstype
, *d
, *p
, *o
;
1631 rewind(m
->proc_self_mountinfo
);
1636 device
= path
= options
= options2
= fstype
= d
= p
= o
= NULL
;
1638 if ((k
= fscanf(m
->proc_self_mountinfo
,
1639 "%*s " /* (1) mount id */
1640 "%*s " /* (2) parent id */
1641 "%*s " /* (3) major:minor */
1642 "%*s " /* (4) root */
1643 "%ms " /* (5) mount point */
1644 "%ms" /* (6) mount options */
1645 "%*[^-]" /* (7) optional fields */
1646 "- " /* (8) separator */
1647 "%ms " /* (9) file system type */
1648 "%ms" /* (10) mount source */
1649 "%ms" /* (11) mount options 2 */
1650 "%*[^\n]", /* some rubbish at the end */
1660 log_warning("Failed to parse /proc/self/mountinfo:%u.", i
);
1664 o
= strjoin(options
, ",", options2
, NULL
);
1670 if (!(d
= cunescape(device
)) ||
1671 !(p
= cunescape(path
))) {
1676 if ((k
= mount_add_one(m
, d
, p
, o
, fstype
, 0, set_flags
)) < 0)
1703 static void mount_shutdown(Manager
*m
) {
1706 if (m
->proc_self_mountinfo
) {
1707 fclose(m
->proc_self_mountinfo
);
1708 m
->proc_self_mountinfo
= NULL
;
1712 static int mount_enumerate(Manager
*m
) {
1716 if (!m
->proc_self_mountinfo
) {
1717 struct epoll_event ev
= {
1719 .data
.ptr
= &m
->mount_watch
,
1722 m
->proc_self_mountinfo
= fopen("/proc/self/mountinfo", "re");
1723 if (!m
->proc_self_mountinfo
)
1726 m
->mount_watch
.type
= WATCH_MOUNT
;
1727 m
->mount_watch
.fd
= fileno(m
->proc_self_mountinfo
);
1729 if (epoll_ctl(m
->epoll_fd
, EPOLL_CTL_ADD
, m
->mount_watch
.fd
, &ev
) < 0)
1733 r
= mount_load_proc_self_mountinfo(m
, false);
1744 void mount_fd_event(Manager
*m
, int events
) {
1749 assert(events
& EPOLLPRI
);
1751 /* The manager calls this for every fd event happening on the
1752 * /proc/self/mountinfo file, which informs us about mounting
1755 r
= mount_load_proc_self_mountinfo(m
, true);
1757 log_error("Failed to reread /proc/self/mountinfo: %s", strerror(-r
));
1759 /* Reset flags, just in case, for later calls */
1760 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_MOUNT
]) {
1761 Mount
*mount
= MOUNT(u
);
1763 mount
->is_mounted
= mount
->just_mounted
= mount
->just_changed
= false;
1769 manager_dispatch_load_queue(m
);
1771 LIST_FOREACH(units_by_type
, u
, m
->units_by_type
[UNIT_MOUNT
]) {
1772 Mount
*mount
= MOUNT(u
);
1774 if (!mount
->is_mounted
) {
1775 /* This has just been unmounted. */
1777 mount
->from_proc_self_mountinfo
= false;
1779 switch (mount
->state
) {
1782 mount_enter_dead(mount
, MOUNT_SUCCESS
);
1786 mount_set_state(mount
, mount
->state
);
1791 } else if (mount
->just_mounted
|| mount
->just_changed
) {
1793 /* New or changed mount entry */
1795 switch (mount
->state
) {
1799 mount_enter_mounted(mount
, MOUNT_SUCCESS
);
1802 case MOUNT_MOUNTING
:
1803 mount_enter_mounting_done(mount
);
1807 /* Nothing really changed, but let's
1808 * issue an notification call
1809 * nonetheless, in case somebody is
1810 * waiting for this. (e.g. file system
1811 * ro/rw remounts.) */
1812 mount_set_state(mount
, mount
->state
);
1817 /* Reset the flags for later calls */
1818 mount
->is_mounted
= mount
->just_mounted
= mount
->just_changed
= false;
1822 static void mount_reset_failed(Unit
*u
) {
1823 Mount
*m
= MOUNT(u
);
1827 if (m
->state
== MOUNT_FAILED
)
1828 mount_set_state(m
, MOUNT_DEAD
);
1830 m
->result
= MOUNT_SUCCESS
;
1831 m
->reload_result
= MOUNT_SUCCESS
;
1834 static int mount_kill(Unit
*u
, KillWho who
, int signo
, DBusError
*error
) {
1835 return unit_kill_common(u
, who
, signo
, -1, MOUNT(u
)->control_pid
, error
);
1838 static const char* const mount_state_table
[_MOUNT_STATE_MAX
] = {
1839 [MOUNT_DEAD
] = "dead",
1840 [MOUNT_MOUNTING
] = "mounting",
1841 [MOUNT_MOUNTING_DONE
] = "mounting-done",
1842 [MOUNT_MOUNTED
] = "mounted",
1843 [MOUNT_REMOUNTING
] = "remounting",
1844 [MOUNT_UNMOUNTING
] = "unmounting",
1845 [MOUNT_MOUNTING_SIGTERM
] = "mounting-sigterm",
1846 [MOUNT_MOUNTING_SIGKILL
] = "mounting-sigkill",
1847 [MOUNT_REMOUNTING_SIGTERM
] = "remounting-sigterm",
1848 [MOUNT_REMOUNTING_SIGKILL
] = "remounting-sigkill",
1849 [MOUNT_UNMOUNTING_SIGTERM
] = "unmounting-sigterm",
1850 [MOUNT_UNMOUNTING_SIGKILL
] = "unmounting-sigkill",
1851 [MOUNT_FAILED
] = "failed"
1854 DEFINE_STRING_TABLE_LOOKUP(mount_state
, MountState
);
1856 static const char* const mount_exec_command_table
[_MOUNT_EXEC_COMMAND_MAX
] = {
1857 [MOUNT_EXEC_MOUNT
] = "ExecMount",
1858 [MOUNT_EXEC_UNMOUNT
] = "ExecUnmount",
1859 [MOUNT_EXEC_REMOUNT
] = "ExecRemount",
1862 DEFINE_STRING_TABLE_LOOKUP(mount_exec_command
, MountExecCommand
);
1864 static const char* const mount_result_table
[_MOUNT_RESULT_MAX
] = {
1865 [MOUNT_SUCCESS
] = "success",
1866 [MOUNT_FAILURE_RESOURCES
] = "resources",
1867 [MOUNT_FAILURE_TIMEOUT
] = "timeout",
1868 [MOUNT_FAILURE_EXIT_CODE
] = "exit-code",
1869 [MOUNT_FAILURE_SIGNAL
] = "signal",
1870 [MOUNT_FAILURE_CORE_DUMP
] = "core-dump"
1873 DEFINE_STRING_TABLE_LOOKUP(mount_result
, MountResult
);
1875 const UnitVTable mount_vtable
= {
1876 .object_size
= sizeof(Mount
),
1883 .private_section
= "Mount",
1884 .exec_context_offset
= offsetof(Mount
, exec_context
),
1885 .cgroup_context_offset
= offsetof(Mount
, cgroup_context
),
1888 .no_instances
= true,
1894 .coldplug
= mount_coldplug
,
1898 .start
= mount_start
,
1900 .reload
= mount_reload
,
1904 .serialize
= mount_serialize
,
1905 .deserialize_item
= mount_deserialize_item
,
1907 .active_state
= mount_active_state
,
1908 .sub_state_to_string
= mount_sub_state_to_string
,
1910 .check_gc
= mount_check_gc
,
1912 .sigchld_event
= mount_sigchld_event
,
1913 .timer_event
= mount_timer_event
,
1915 .reset_failed
= mount_reset_failed
,
1917 .bus_interface
= "org.freedesktop.systemd1.Mount",
1918 .bus_message_handler
= bus_mount_message_handler
,
1919 .bus_invalidating_properties
= bus_mount_invalidating_properties
,
1920 .bus_set_property
= bus_mount_set_property
,
1921 .bus_commit_properties
= bus_mount_commit_properties
,
1923 .enumerate
= mount_enumerate
,
1924 .shutdown
= mount_shutdown
,
1926 .status_message_formats
= {
1927 .starting_stopping
= {
1928 [0] = "Mounting %s...",
1929 [1] = "Unmounting %s...",
1931 .finished_start_job
= {
1932 [JOB_DONE
] = "Mounted %s.",
1933 [JOB_FAILED
] = "Failed to mount %s.",
1934 [JOB_DEPENDENCY
] = "Dependency failed for %s.",
1935 [JOB_TIMEOUT
] = "Timed out mounting %s.",
1937 .finished_stop_job
= {
1938 [JOB_DONE
] = "Unmounted %s.",
1939 [JOB_FAILED
] = "Failed unmounting %s.",
1940 [JOB_TIMEOUT
] = "Timed out unmounting %s.",