1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include <linux/auto_dev-ioctl.h>
25 #include <linux/auto_fs4.h>
26 #include <sys/epoll.h>
27 #include <sys/mount.h>
31 #include "alloc-util.h"
33 #include "automount.h"
34 #include "bus-error.h"
36 #include "dbus-automount.h"
38 #include "format-util.h"
42 #include "mount-util.h"
44 #include "parse-util.h"
45 #include "path-util.h"
46 #include "process-util.h"
48 #include "stdio-util.h"
49 #include "string-table.h"
50 #include "string-util.h"
51 #include "unit-name.h"
54 static const UnitActiveState state_translation_table
[_AUTOMOUNT_STATE_MAX
] = {
55 [AUTOMOUNT_DEAD
] = UNIT_INACTIVE
,
56 [AUTOMOUNT_WAITING
] = UNIT_ACTIVE
,
57 [AUTOMOUNT_RUNNING
] = UNIT_ACTIVE
,
58 [AUTOMOUNT_FAILED
] = UNIT_FAILED
66 static inline void expire_data_free(struct expire_data
*data
) {
70 safe_close(data
->dev_autofs_fd
);
71 safe_close(data
->ioctl_fd
);
75 DEFINE_TRIVIAL_CLEANUP_FUNC(struct expire_data
*, expire_data_free
);
77 static int open_dev_autofs(Manager
*m
);
78 static int automount_dispatch_io(sd_event_source
*s
, int fd
, uint32_t events
, void *userdata
);
79 static int automount_start_expire(Automount
*a
);
80 static void automount_stop_expire(Automount
*a
);
81 static int automount_send_ready(Automount
*a
, Set
*tokens
, int status
);
83 static void automount_init(Unit
*u
) {
84 Automount
*a
= AUTOMOUNT(u
);
87 assert(u
->load_state
== UNIT_STUB
);
90 a
->directory_mode
= 0755;
91 UNIT(a
)->ignore_on_isolate
= true;
94 static void unmount_autofs(Automount
*a
) {
102 a
->pipe_event_source
= sd_event_source_unref(a
->pipe_event_source
);
103 a
->pipe_fd
= safe_close(a
->pipe_fd
);
105 /* If we reload/reexecute things we keep the mount point around */
106 if (!IN_SET(UNIT(a
)->manager
->exit_code
, MANAGER_RELOAD
, MANAGER_REEXECUTE
)) {
108 automount_send_ready(a
, a
->tokens
, -EHOSTDOWN
);
109 automount_send_ready(a
, a
->expire_tokens
, -EHOSTDOWN
);
112 r
= repeat_unmount(a
->where
, MNT_DETACH
);
114 log_error_errno(r
, "Failed to unmount: %m");
119 static void automount_done(Unit
*u
) {
120 Automount
*a
= AUTOMOUNT(u
);
126 a
->where
= mfree(a
->where
);
128 a
->tokens
= set_free(a
->tokens
);
129 a
->expire_tokens
= set_free(a
->expire_tokens
);
131 a
->expire_event_source
= sd_event_source_unref(a
->expire_event_source
);
134 static int automount_add_trigger_dependencies(Automount
*a
) {
140 r
= unit_load_related_unit(UNIT(a
), ".mount", &x
);
144 return unit_add_two_dependencies(UNIT(a
), UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true, UNIT_DEPENDENCY_IMPLICIT
);
147 static int automount_add_mount_dependencies(Automount
*a
) {
148 _cleanup_free_
char *parent
= NULL
;
152 parent
= dirname_malloc(a
->where
);
156 return unit_require_mounts_for(UNIT(a
), parent
, UNIT_DEPENDENCY_IMPLICIT
);
159 static int automount_add_default_dependencies(Automount
*a
) {
164 if (!UNIT(a
)->default_dependencies
)
167 if (!MANAGER_IS_SYSTEM(UNIT(a
)->manager
))
170 r
= unit_add_two_dependencies_by_name(UNIT(a
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true, UNIT_DEPENDENCY_DEFAULT
);
177 static int automount_verify(Automount
*a
) {
178 _cleanup_free_
char *e
= NULL
;
183 if (UNIT(a
)->load_state
!= UNIT_LOADED
)
186 if (path_equal(a
->where
, "/")) {
187 log_unit_error(UNIT(a
), "Cannot have an automount unit for the root directory. Refusing.");
191 r
= unit_name_from_path(a
->where
, ".automount", &e
);
193 return log_unit_error(UNIT(a
), "Failed to generate unit name from path: %m");
195 if (!unit_has_name(UNIT(a
), e
)) {
196 log_unit_error(UNIT(a
), "Where= setting doesn't match unit name. Refusing.");
203 static int automount_set_where(Automount
*a
) {
211 r
= unit_name_to_path(UNIT(a
)->id
, &a
->where
);
215 path_kill_slashes(a
->where
);
219 static int automount_load(Unit
*u
) {
220 Automount
*a
= AUTOMOUNT(u
);
224 assert(u
->load_state
== UNIT_STUB
);
226 /* Load a .automount file */
227 r
= unit_load_fragment_and_dropin_optional(u
);
231 if (u
->load_state
== UNIT_LOADED
) {
232 r
= automount_set_where(a
);
236 r
= automount_add_trigger_dependencies(a
);
240 r
= automount_add_mount_dependencies(a
);
244 r
= automount_add_default_dependencies(a
);
249 return automount_verify(a
);
252 static void automount_set_state(Automount
*a
, AutomountState state
) {
253 AutomountState old_state
;
256 old_state
= a
->state
;
259 if (state
!= AUTOMOUNT_RUNNING
)
260 automount_stop_expire(a
);
262 if (!IN_SET(state
, AUTOMOUNT_WAITING
, AUTOMOUNT_RUNNING
))
265 if (state
!= old_state
)
266 log_unit_debug(UNIT(a
), "Changed %s -> %s", automount_state_to_string(old_state
), automount_state_to_string(state
));
268 unit_notify(UNIT(a
), state_translation_table
[old_state
], state_translation_table
[state
], true);
271 static int automount_coldplug(Unit
*u
) {
272 Automount
*a
= AUTOMOUNT(u
);
276 assert(a
->state
== AUTOMOUNT_DEAD
);
278 if (a
->deserialized_state
== a
->state
)
281 if (IN_SET(a
->deserialized_state
, AUTOMOUNT_WAITING
, AUTOMOUNT_RUNNING
)) {
283 r
= automount_set_where(a
);
287 r
= open_dev_autofs(u
->manager
);
291 assert(a
->pipe_fd
>= 0);
293 r
= sd_event_add_io(u
->manager
->event
, &a
->pipe_event_source
, a
->pipe_fd
, EPOLLIN
, automount_dispatch_io
, u
);
297 (void) sd_event_source_set_description(a
->pipe_event_source
, "automount-io");
298 if (a
->deserialized_state
== AUTOMOUNT_RUNNING
) {
299 r
= automount_start_expire(a
);
301 log_unit_warning_errno(UNIT(a
), r
, "Failed to start expiration timer, ignoring: %m");
304 automount_set_state(a
, a
->deserialized_state
);
310 static void automount_dump(Unit
*u
, FILE *f
, const char *prefix
) {
311 char time_string
[FORMAT_TIMESPAN_MAX
];
312 Automount
*a
= AUTOMOUNT(u
);
317 "%sAutomount State: %s\n"
320 "%sDirectoryMode: %04o\n"
321 "%sTimeoutIdleUSec: %s\n",
322 prefix
, automount_state_to_string(a
->state
),
323 prefix
, automount_result_to_string(a
->result
),
325 prefix
, a
->directory_mode
,
326 prefix
, format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, a
->timeout_idle_usec
, USEC_PER_SEC
));
329 static void automount_enter_dead(Automount
*a
, AutomountResult f
) {
332 if (a
->result
== AUTOMOUNT_SUCCESS
)
335 if (a
->result
!= AUTOMOUNT_SUCCESS
)
336 log_unit_warning(UNIT(a
), "Failed with result '%s'.", automount_result_to_string(a
->result
));
338 automount_set_state(a
, a
->result
!= AUTOMOUNT_SUCCESS
? AUTOMOUNT_FAILED
: AUTOMOUNT_DEAD
);
341 static int open_dev_autofs(Manager
*m
) {
342 struct autofs_dev_ioctl param
;
346 if (m
->dev_autofs_fd
>= 0)
347 return m
->dev_autofs_fd
;
349 label_fix("/dev/autofs", false, false);
351 m
->dev_autofs_fd
= open("/dev/autofs", O_CLOEXEC
|O_RDONLY
);
352 if (m
->dev_autofs_fd
< 0)
353 return log_error_errno(errno
, "Failed to open /dev/autofs: %m");
355 init_autofs_dev_ioctl(¶m
);
356 if (ioctl(m
->dev_autofs_fd
, AUTOFS_DEV_IOCTL_VERSION
, ¶m
) < 0) {
357 m
->dev_autofs_fd
= safe_close(m
->dev_autofs_fd
);
361 log_debug("Autofs kernel version %i.%i", param
.ver_major
, param
.ver_minor
);
363 return m
->dev_autofs_fd
;
366 static int open_ioctl_fd(int dev_autofs_fd
, const char *where
, dev_t devid
) {
367 struct autofs_dev_ioctl
*param
;
370 assert(dev_autofs_fd
>= 0);
373 l
= sizeof(struct autofs_dev_ioctl
) + strlen(where
) + 1;
376 init_autofs_dev_ioctl(param
);
379 param
->openmount
.devid
= devid
;
380 strcpy(param
->path
, where
);
382 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_OPENMOUNT
, param
) < 0)
385 if (param
->ioctlfd
< 0)
388 (void) fd_cloexec(param
->ioctlfd
, true);
389 return param
->ioctlfd
;
392 static int autofs_protocol(int dev_autofs_fd
, int ioctl_fd
) {
393 uint32_t major
, minor
;
394 struct autofs_dev_ioctl param
;
396 assert(dev_autofs_fd
>= 0);
397 assert(ioctl_fd
>= 0);
399 init_autofs_dev_ioctl(¶m
);
400 param
.ioctlfd
= ioctl_fd
;
402 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_PROTOVER
, ¶m
) < 0)
405 major
= param
.protover
.version
;
407 init_autofs_dev_ioctl(¶m
);
408 param
.ioctlfd
= ioctl_fd
;
410 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_PROTOSUBVER
, ¶m
) < 0)
413 minor
= param
.protosubver
.sub_version
;
415 log_debug("Autofs protocol version %i.%i", major
, minor
);
419 static int autofs_set_timeout(int dev_autofs_fd
, int ioctl_fd
, usec_t usec
) {
420 struct autofs_dev_ioctl param
;
422 assert(dev_autofs_fd
>= 0);
423 assert(ioctl_fd
>= 0);
425 init_autofs_dev_ioctl(¶m
);
426 param
.ioctlfd
= ioctl_fd
;
428 if (usec
== USEC_INFINITY
)
429 param
.timeout
.timeout
= 0;
431 /* Convert to seconds, rounding up. */
432 param
.timeout
.timeout
= (usec
+ USEC_PER_SEC
- 1) / USEC_PER_SEC
;
434 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_TIMEOUT
, ¶m
) < 0)
440 static int autofs_send_ready(int dev_autofs_fd
, int ioctl_fd
, uint32_t token
, int status
) {
441 struct autofs_dev_ioctl param
;
443 assert(dev_autofs_fd
>= 0);
444 assert(ioctl_fd
>= 0);
446 init_autofs_dev_ioctl(¶m
);
447 param
.ioctlfd
= ioctl_fd
;
450 param
.fail
.token
= token
;
451 param
.fail
.status
= status
;
453 param
.ready
.token
= token
;
455 if (ioctl(dev_autofs_fd
, status
? AUTOFS_DEV_IOCTL_FAIL
: AUTOFS_DEV_IOCTL_READY
, ¶m
) < 0)
461 static int automount_send_ready(Automount
*a
, Set
*tokens
, int status
) {
462 _cleanup_close_
int ioctl_fd
= -1;
469 if (set_isempty(tokens
))
472 ioctl_fd
= open_ioctl_fd(UNIT(a
)->manager
->dev_autofs_fd
, a
->where
, a
->dev_id
);
477 log_unit_debug_errno(UNIT(a
), status
, "Sending failure: %m");
479 log_unit_debug(UNIT(a
), "Sending success.");
483 /* Autofs thankfully does not hand out 0 as a token */
484 while ((token
= PTR_TO_UINT(set_steal_first(tokens
)))) {
489 * if you pass a positive status code here, kernels
490 * prior to 4.12 will freeze! Yay! */
492 k
= autofs_send_ready(UNIT(a
)->manager
->dev_autofs_fd
,
503 static void automount_trigger_notify(Unit
*u
, Unit
*other
) {
504 Automount
*a
= AUTOMOUNT(u
);
510 /* Filter out invocations with bogus state */
511 if (other
->load_state
!= UNIT_LOADED
|| other
->type
!= UNIT_MOUNT
)
514 /* Don't propagate state changes from the mount if we are already down */
515 if (!IN_SET(a
->state
, AUTOMOUNT_WAITING
, AUTOMOUNT_RUNNING
))
518 /* Propagate start limit hit state */
519 if (other
->start_limit_hit
) {
520 automount_enter_dead(a
, AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT
);
524 /* Don't propagate anything if there's still a job queued */
528 /* The mount is successfully established */
529 if (IN_SET(MOUNT(other
)->state
, MOUNT_MOUNTED
, MOUNT_REMOUNTING
)) {
530 (void) automount_send_ready(a
, a
->tokens
, 0);
532 r
= automount_start_expire(a
);
534 log_unit_warning_errno(UNIT(a
), r
, "Failed to start expiration timer, ignoring: %m");
536 automount_set_state(a
, AUTOMOUNT_RUNNING
);
539 if (IN_SET(MOUNT(other
)->state
,
540 MOUNT_MOUNTING
, MOUNT_MOUNTING_DONE
,
541 MOUNT_MOUNTED
, MOUNT_REMOUNTING
,
542 MOUNT_REMOUNTING_SIGTERM
, MOUNT_REMOUNTING_SIGKILL
,
543 MOUNT_UNMOUNTING_SIGTERM
, MOUNT_UNMOUNTING_SIGKILL
,
546 (void) automount_send_ready(a
, a
->expire_tokens
, -ENODEV
);
549 if (MOUNT(other
)->state
== MOUNT_DEAD
)
550 (void) automount_send_ready(a
, a
->expire_tokens
, 0);
552 /* The mount is in some unhappy state now, let's unfreeze any waiting clients */
553 if (IN_SET(MOUNT(other
)->state
,
554 MOUNT_DEAD
, MOUNT_UNMOUNTING
,
555 MOUNT_REMOUNTING_SIGTERM
, MOUNT_REMOUNTING_SIGKILL
,
556 MOUNT_UNMOUNTING_SIGTERM
, MOUNT_UNMOUNTING_SIGKILL
,
559 (void) automount_send_ready(a
, a
->tokens
, -ENODEV
);
561 automount_set_state(a
, AUTOMOUNT_WAITING
);
565 static void automount_enter_waiting(Automount
*a
) {
566 _cleanup_close_
int ioctl_fd
= -1;
567 int p
[2] = { -1, -1 };
568 char name
[sizeof("systemd-")-1 + DECIMAL_STR_MAX(pid_t
) + 1];
569 char options
[sizeof("fd=,pgrp=,minproto=5,maxproto=5,direct")-1
570 + DECIMAL_STR_MAX(int) + DECIMAL_STR_MAX(gid_t
) + 1];
571 bool mounted
= false;
572 int r
, dev_autofs_fd
;
576 assert(a
->pipe_fd
< 0);
579 set_clear(a
->tokens
);
581 r
= unit_fail_if_symlink(UNIT(a
), a
->where
);
585 (void) mkdir_p_label(a
->where
, 0555);
587 unit_warn_if_dir_nonempty(UNIT(a
), a
->where
);
589 dev_autofs_fd
= open_dev_autofs(UNIT(a
)->manager
);
590 if (dev_autofs_fd
< 0) {
595 if (pipe2(p
, O_NONBLOCK
|O_CLOEXEC
) < 0) {
600 xsprintf(options
, "fd=%i,pgrp="PID_FMT
",minproto=5,maxproto=5,direct", p
[1], getpgrp());
601 xsprintf(name
, "systemd-"PID_FMT
, getpid_cached());
602 if (mount(name
, a
->where
, "autofs", 0, options
) < 0) {
609 p
[1] = safe_close(p
[1]);
611 if (stat(a
->where
, &st
) < 0) {
616 ioctl_fd
= open_ioctl_fd(dev_autofs_fd
, a
->where
, st
.st_dev
);
622 r
= autofs_protocol(dev_autofs_fd
, ioctl_fd
);
626 r
= autofs_set_timeout(dev_autofs_fd
, ioctl_fd
, a
->timeout_idle_usec
);
630 r
= sd_event_add_io(UNIT(a
)->manager
->event
, &a
->pipe_event_source
, p
[0], EPOLLIN
, automount_dispatch_io
, a
);
634 (void) sd_event_source_set_description(a
->pipe_event_source
, "automount-io");
637 a
->dev_id
= st
.st_dev
;
639 automount_set_state(a
, AUTOMOUNT_WAITING
);
644 log_unit_error_errno(UNIT(a
), r
, "Failed to initialize automounter: %m");
649 r
= repeat_unmount(a
->where
, MNT_DETACH
);
651 log_error_errno(r
, "Failed to unmount, ignoring: %m");
654 automount_enter_dead(a
, AUTOMOUNT_FAILURE_RESOURCES
);
657 static void *expire_thread(void *p
) {
658 struct autofs_dev_ioctl param
;
659 _cleanup_(expire_data_freep
) struct expire_data
*data
= (struct expire_data
*)p
;
662 assert(data
->dev_autofs_fd
>= 0);
663 assert(data
->ioctl_fd
>= 0);
665 init_autofs_dev_ioctl(¶m
);
666 param
.ioctlfd
= data
->ioctl_fd
;
669 r
= ioctl(data
->dev_autofs_fd
, AUTOFS_DEV_IOCTL_EXPIRE
, ¶m
);
673 log_warning_errno(errno
, "Failed to expire automount, ignoring: %m");
678 static int automount_dispatch_expire(sd_event_source
*source
, usec_t usec
, void *userdata
) {
679 Automount
*a
= AUTOMOUNT(userdata
);
680 _cleanup_(expire_data_freep
) struct expire_data
*data
= NULL
;
684 assert(source
== a
->expire_event_source
);
686 data
= new0(struct expire_data
, 1);
692 data
->dev_autofs_fd
= fcntl(UNIT(a
)->manager
->dev_autofs_fd
, F_DUPFD_CLOEXEC
, 3);
693 if (data
->dev_autofs_fd
< 0)
694 return log_unit_error_errno(UNIT(a
), errno
, "Failed to duplicate autofs fd: %m");
696 data
->ioctl_fd
= open_ioctl_fd(UNIT(a
)->manager
->dev_autofs_fd
, a
->where
, a
->dev_id
);
697 if (data
->ioctl_fd
< 0)
698 return log_unit_error_errno(UNIT(a
), data
->ioctl_fd
, "Couldn't open autofs ioctl fd: %m");
700 r
= asynchronous_job(expire_thread
, data
);
702 return log_unit_error_errno(UNIT(a
), r
, "Failed to start expire job: %m");
706 return automount_start_expire(a
);
709 static int automount_start_expire(Automount
*a
) {
715 if (a
->timeout_idle_usec
== 0)
718 timeout
= now(CLOCK_MONOTONIC
) + MAX(a
->timeout_idle_usec
/3, USEC_PER_SEC
);
720 if (a
->expire_event_source
) {
721 r
= sd_event_source_set_time(a
->expire_event_source
, timeout
);
725 return sd_event_source_set_enabled(a
->expire_event_source
, SD_EVENT_ONESHOT
);
728 r
= sd_event_add_time(
729 UNIT(a
)->manager
->event
,
730 &a
->expire_event_source
,
731 CLOCK_MONOTONIC
, timeout
, 0,
732 automount_dispatch_expire
, a
);
736 (void) sd_event_source_set_description(a
->expire_event_source
, "automount-expire");
741 static void automount_stop_expire(Automount
*a
) {
744 if (!a
->expire_event_source
)
747 (void) sd_event_source_set_enabled(a
->expire_event_source
, SD_EVENT_OFF
);
750 static void automount_enter_running(Automount
*a
) {
751 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
758 /* If the user masked our unit in the meantime, fail */
759 if (UNIT(a
)->load_state
!= UNIT_LOADED
) {
760 log_unit_error(UNIT(a
), "Suppressing automount event since unit is no longer loaded.");
764 /* We don't take mount requests anymore if we are supposed to
765 * shut down anyway */
766 if (unit_stop_pending(UNIT(a
))) {
767 log_unit_debug(UNIT(a
), "Suppressing automount request since unit stop is scheduled.");
768 automount_send_ready(a
, a
->tokens
, -EHOSTDOWN
);
769 automount_send_ready(a
, a
->expire_tokens
, -EHOSTDOWN
);
773 mkdir_p_label(a
->where
, a
->directory_mode
);
775 /* Before we do anything, let's see if somebody is playing games with us? */
776 if (lstat(a
->where
, &st
) < 0) {
777 log_unit_warning_errno(UNIT(a
), errno
, "Failed to stat automount point: %m");
781 /* The mount unit may have been explicitly started before we got the
782 * autofs request. Ack it to unblock anything waiting on the mount point. */
783 if (!S_ISDIR(st
.st_mode
) || st
.st_dev
!= a
->dev_id
) {
784 log_unit_info(UNIT(a
), "Automount point already active?");
785 automount_send_ready(a
, a
->tokens
, 0);
789 trigger
= UNIT_TRIGGER(UNIT(a
));
791 log_unit_error(UNIT(a
), "Unit to trigger vanished.");
795 r
= manager_add_job(UNIT(a
)->manager
, JOB_START
, trigger
, JOB_REPLACE
, &error
, NULL
);
797 log_unit_warning(UNIT(a
), "Failed to queue mount startup job: %s", bus_error_message(&error
, r
));
801 automount_set_state(a
, AUTOMOUNT_RUNNING
);
805 automount_enter_dead(a
, AUTOMOUNT_FAILURE_RESOURCES
);
808 static int automount_start(Unit
*u
) {
809 Automount
*a
= AUTOMOUNT(u
);
814 assert(IN_SET(a
->state
, AUTOMOUNT_DEAD
, AUTOMOUNT_FAILED
));
816 if (path_is_mount_point(a
->where
, NULL
, 0) > 0) {
817 log_unit_error(u
, "Path %s is already a mount point, refusing start.", a
->where
);
821 trigger
= UNIT_TRIGGER(u
);
822 if (!trigger
|| trigger
->load_state
!= UNIT_LOADED
) {
823 log_unit_error(u
, "Refusing to start, unit to trigger not loaded.");
827 r
= unit_start_limit_test(u
);
829 automount_enter_dead(a
, AUTOMOUNT_FAILURE_START_LIMIT_HIT
);
833 r
= unit_acquire_invocation_id(u
);
837 a
->result
= AUTOMOUNT_SUCCESS
;
838 automount_enter_waiting(a
);
842 static int automount_stop(Unit
*u
) {
843 Automount
*a
= AUTOMOUNT(u
);
846 assert(IN_SET(a
->state
, AUTOMOUNT_WAITING
, AUTOMOUNT_RUNNING
));
848 automount_enter_dead(a
, AUTOMOUNT_SUCCESS
);
852 static int automount_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
853 Automount
*a
= AUTOMOUNT(u
);
862 unit_serialize_item(u
, f
, "state", automount_state_to_string(a
->state
));
863 unit_serialize_item(u
, f
, "result", automount_result_to_string(a
->result
));
864 unit_serialize_item_format(u
, f
, "dev-id", "%u", (unsigned) a
->dev_id
);
866 SET_FOREACH(p
, a
->tokens
, i
)
867 unit_serialize_item_format(u
, f
, "token", "%u", PTR_TO_UINT(p
));
868 SET_FOREACH(p
, a
->expire_tokens
, i
)
869 unit_serialize_item_format(u
, f
, "expire-token", "%u", PTR_TO_UINT(p
));
871 r
= unit_serialize_item_fd(u
, f
, fds
, "pipe-fd", a
->pipe_fd
);
878 static int automount_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
879 Automount
*a
= AUTOMOUNT(u
);
885 if (streq(key
, "state")) {
886 AutomountState state
;
888 state
= automount_state_from_string(value
);
890 log_unit_debug(u
, "Failed to parse state value: %s", value
);
892 a
->deserialized_state
= state
;
893 } else if (streq(key
, "result")) {
896 f
= automount_result_from_string(value
);
898 log_unit_debug(u
, "Failed to parse result value: %s", value
);
899 else if (f
!= AUTOMOUNT_SUCCESS
)
902 } else if (streq(key
, "dev-id")) {
905 if (safe_atou(value
, &d
) < 0)
906 log_unit_debug(u
, "Failed to parse dev-id value: %s", value
);
908 a
->dev_id
= (unsigned) d
;
909 } else if (streq(key
, "token")) {
912 if (safe_atou(value
, &token
) < 0)
913 log_unit_debug(u
, "Failed to parse token value: %s", value
);
915 r
= set_ensure_allocated(&a
->tokens
, NULL
);
921 r
= set_put(a
->tokens
, UINT_TO_PTR(token
));
923 log_unit_error_errno(u
, r
, "Failed to add token to set: %m");
925 } else if (streq(key
, "expire-token")) {
928 if (safe_atou(value
, &token
) < 0)
929 log_unit_debug(u
, "Failed to parse token value: %s", value
);
931 r
= set_ensure_allocated(&a
->expire_tokens
, NULL
);
937 r
= set_put(a
->expire_tokens
, UINT_TO_PTR(token
));
939 log_unit_error_errno(u
, r
, "Failed to add expire token to set: %m");
941 } else if (streq(key
, "pipe-fd")) {
944 if (safe_atoi(value
, &fd
) < 0 || fd
< 0 || !fdset_contains(fds
, fd
))
945 log_unit_debug(u
, "Failed to parse pipe-fd value: %s", value
);
947 safe_close(a
->pipe_fd
);
948 a
->pipe_fd
= fdset_remove(fds
, fd
);
951 log_unit_debug(u
, "Unknown serialization key: %s", key
);
956 static UnitActiveState
automount_active_state(Unit
*u
) {
959 return state_translation_table
[AUTOMOUNT(u
)->state
];
962 static const char *automount_sub_state_to_string(Unit
*u
) {
965 return automount_state_to_string(AUTOMOUNT(u
)->state
);
968 static bool automount_check_gc(Unit
*u
) {
971 if (!UNIT_TRIGGER(u
))
974 return UNIT_VTABLE(UNIT_TRIGGER(u
))->check_gc(UNIT_TRIGGER(u
));
977 static int automount_dispatch_io(sd_event_source
*s
, int fd
, uint32_t events
, void *userdata
) {
978 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
979 union autofs_v5_packet_union packet
;
980 Automount
*a
= AUTOMOUNT(userdata
);
985 assert(fd
== a
->pipe_fd
);
987 if (events
!= EPOLLIN
) {
988 log_unit_error(UNIT(a
), "Got invalid poll event %"PRIu32
" on pipe (fd=%d)", events
, fd
);
992 r
= loop_read_exact(a
->pipe_fd
, &packet
, sizeof(packet
), true);
994 log_unit_error_errno(UNIT(a
), r
, "Invalid read from pipe: %m");
998 switch (packet
.hdr
.type
) {
1000 case autofs_ptype_missing_direct
:
1002 if (packet
.v5_packet
.pid
> 0) {
1003 _cleanup_free_
char *p
= NULL
;
1005 get_process_comm(packet
.v5_packet
.pid
, &p
);
1006 log_unit_info(UNIT(a
), "Got automount request for %s, triggered by %"PRIu32
" (%s)", a
->where
, packet
.v5_packet
.pid
, strna(p
));
1008 log_unit_debug(UNIT(a
), "Got direct mount request on %s", a
->where
);
1010 r
= set_ensure_allocated(&a
->tokens
, NULL
);
1012 log_unit_error(UNIT(a
), "Failed to allocate token set.");
1016 r
= set_put(a
->tokens
, UINT_TO_PTR(packet
.v5_packet
.wait_queue_token
));
1018 log_unit_error_errno(UNIT(a
), r
, "Failed to remember token: %m");
1022 automount_enter_running(a
);
1025 case autofs_ptype_expire_direct
:
1026 log_unit_debug(UNIT(a
), "Got direct umount request on %s", a
->where
);
1028 automount_stop_expire(a
);
1030 r
= set_ensure_allocated(&a
->expire_tokens
, NULL
);
1032 log_unit_error(UNIT(a
), "Failed to allocate token set.");
1036 r
= set_put(a
->expire_tokens
, UINT_TO_PTR(packet
.v5_packet
.wait_queue_token
));
1038 log_unit_error_errno(UNIT(a
), r
, "Failed to remember token: %m");
1042 trigger
= UNIT_TRIGGER(UNIT(a
));
1044 log_unit_error(UNIT(a
), "Unit to trigger vanished.");
1048 r
= manager_add_job(UNIT(a
)->manager
, JOB_STOP
, trigger
, JOB_REPLACE
, &error
, NULL
);
1050 log_unit_warning(UNIT(a
), "Failed to queue umount startup job: %s", bus_error_message(&error
, r
));
1056 log_unit_error(UNIT(a
), "Received unknown automount request %i", packet
.hdr
.type
);
1063 automount_enter_dead(a
, AUTOMOUNT_FAILURE_RESOURCES
);
1067 static void automount_shutdown(Manager
*m
) {
1070 m
->dev_autofs_fd
= safe_close(m
->dev_autofs_fd
);
1073 static void automount_reset_failed(Unit
*u
) {
1074 Automount
*a
= AUTOMOUNT(u
);
1078 if (a
->state
== AUTOMOUNT_FAILED
)
1079 automount_set_state(a
, AUTOMOUNT_DEAD
);
1081 a
->result
= AUTOMOUNT_SUCCESS
;
1084 static bool automount_supported(void) {
1085 static int supported
= -1;
1088 supported
= access("/dev/autofs", F_OK
) >= 0;
1093 static const char* const automount_result_table
[_AUTOMOUNT_RESULT_MAX
] = {
1094 [AUTOMOUNT_SUCCESS
] = "success",
1095 [AUTOMOUNT_FAILURE_RESOURCES
] = "resources",
1096 [AUTOMOUNT_FAILURE_START_LIMIT_HIT
] = "start-limit-hit",
1097 [AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT
] = "mount-start-limit-hit",
1100 DEFINE_STRING_TABLE_LOOKUP(automount_result
, AutomountResult
);
1102 const UnitVTable automount_vtable
= {
1103 .object_size
= sizeof(Automount
),
1110 .init
= automount_init
,
1111 .load
= automount_load
,
1112 .done
= automount_done
,
1114 .coldplug
= automount_coldplug
,
1116 .dump
= automount_dump
,
1118 .start
= automount_start
,
1119 .stop
= automount_stop
,
1121 .serialize
= automount_serialize
,
1122 .deserialize_item
= automount_deserialize_item
,
1124 .active_state
= automount_active_state
,
1125 .sub_state_to_string
= automount_sub_state_to_string
,
1127 .check_gc
= automount_check_gc
,
1129 .trigger_notify
= automount_trigger_notify
,
1131 .reset_failed
= automount_reset_failed
,
1133 .bus_vtable
= bus_automount_vtable
,
1134 .bus_set_property
= bus_automount_set_property
,
1136 .can_transient
= true,
1138 .shutdown
= automount_shutdown
,
1139 .supported
= automount_supported
,
1141 .status_message_formats
= {
1142 .finished_start_job
= {
1143 [JOB_DONE
] = "Set up automount %s.",
1144 [JOB_FAILED
] = "Failed to set up automount %s.",
1146 .finished_stop_job
= {
1147 [JOB_DONE
] = "Unset automount %s.",
1148 [JOB_FAILED
] = "Failed to unset automount %s.",