1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
6 #include <linux/auto_dev-ioctl.h>
7 #include <linux/auto_fs4.h>
13 #include "alloc-util.h"
15 #include "automount.h"
16 #include "bus-error.h"
18 #include "dbus-automount.h"
19 #include "dbus-unit.h"
21 #include "format-util.h"
22 #include "fstab-util.h"
24 #include "label-util.h"
25 #include "mkdir-label.h"
26 #include "mount-util.h"
28 #include "mountpoint-util.h"
29 #include "parse-util.h"
30 #include "path-util.h"
31 #include "process-util.h"
32 #include "serialize.h"
34 #include "stdio-util.h"
35 #include "string-table.h"
36 #include "string-util.h"
37 #include "unit-name.h"
40 static const UnitActiveState state_translation_table
[_AUTOMOUNT_STATE_MAX
] = {
41 [AUTOMOUNT_DEAD
] = UNIT_INACTIVE
,
42 [AUTOMOUNT_WAITING
] = UNIT_ACTIVE
,
43 [AUTOMOUNT_RUNNING
] = UNIT_ACTIVE
,
44 [AUTOMOUNT_FAILED
] = UNIT_FAILED
47 static int open_dev_autofs(Manager
*m
);
48 static int automount_dispatch_io(sd_event_source
*s
, int fd
, uint32_t events
, void *userdata
);
49 static int automount_start_expire(Automount
*a
);
50 static void automount_stop_expire(Automount
*a
);
51 static int automount_send_ready(Automount
*a
, Set
*tokens
, int status
);
53 static void automount_init(Unit
*u
) {
54 Automount
*a
= ASSERT_PTR(AUTOMOUNT(u
));
56 assert(u
->load_state
== UNIT_STUB
);
59 a
->directory_mode
= 0755;
60 UNIT(a
)->ignore_on_isolate
= true;
63 static void unmount_autofs(Automount
*a
) {
71 a
->pipe_event_source
= sd_event_source_disable_unref(a
->pipe_event_source
);
72 a
->pipe_fd
= safe_close(a
->pipe_fd
);
74 /* If we reload/reexecute things we keep the mount point around */
75 if (!IN_SET(UNIT(a
)->manager
->objective
, MANAGER_RELOAD
, MANAGER_REEXECUTE
)) {
77 automount_send_ready(a
, a
->tokens
, -EHOSTDOWN
);
78 automount_send_ready(a
, a
->expire_tokens
, -EHOSTDOWN
);
81 r
= repeat_unmount(a
->where
, MNT_DETACH
|UMOUNT_NOFOLLOW
);
83 log_unit_error_errno(UNIT(a
), r
, "Failed to unmount: %m");
88 static void automount_done(Unit
*u
) {
89 Automount
*a
= ASSERT_PTR(AUTOMOUNT(u
));
93 a
->where
= mfree(a
->where
);
94 a
->extra_options
= mfree(a
->extra_options
);
96 a
->tokens
= set_free(a
->tokens
);
97 a
->expire_tokens
= set_free(a
->expire_tokens
);
99 a
->expire_event_source
= sd_event_source_disable_unref(a
->expire_event_source
);
102 static int automount_add_trigger_dependencies(Automount
*a
) {
108 r
= unit_load_related_unit(UNIT(a
), ".mount", &x
);
112 return unit_add_two_dependencies(UNIT(a
), UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true, UNIT_DEPENDENCY_IMPLICIT
);
115 static int automount_add_mount_dependencies(Automount
*a
) {
116 _cleanup_free_
char *parent
= NULL
;
121 r
= path_extract_directory(a
->where
, &parent
);
125 return unit_add_mounts_for(UNIT(a
), parent
, UNIT_DEPENDENCY_IMPLICIT
, UNIT_MOUNT_REQUIRES
);
128 static int automount_add_default_dependencies(Automount
*a
) {
133 if (!UNIT(a
)->default_dependencies
)
136 if (!MANAGER_IS_SYSTEM(UNIT(a
)->manager
))
139 r
= unit_add_dependency_by_name(UNIT(a
), UNIT_BEFORE
, SPECIAL_LOCAL_FS_TARGET
, true, UNIT_DEPENDENCY_DEFAULT
);
143 r
= unit_add_dependency_by_name(UNIT(a
), UNIT_AFTER
, SPECIAL_LOCAL_FS_PRE_TARGET
, true, UNIT_DEPENDENCY_DEFAULT
);
147 r
= unit_add_two_dependencies_by_name(UNIT(a
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, true, UNIT_DEPENDENCY_DEFAULT
);
154 static int automount_verify(Automount
*a
) {
155 static const char *const reserved_options
[] = {
164 _cleanup_free_
char *e
= NULL
;
168 assert(UNIT(a
)->load_state
== UNIT_LOADED
);
170 if (path_equal(a
->where
, "/"))
171 return log_unit_error_errno(UNIT(a
), SYNTHETIC_ERRNO(ENOEXEC
), "Cannot have an automount unit for the root directory. Refusing.");
173 r
= unit_name_from_path(a
->where
, ".automount", &e
);
175 return log_unit_error_errno(UNIT(a
), r
, "Failed to generate unit name from path: %m");
177 if (!unit_has_name(UNIT(a
), e
))
178 return log_unit_error_errno(UNIT(a
), SYNTHETIC_ERRNO(ENOEXEC
), "Where= setting doesn't match unit name. Refusing.");
180 for (size_t i
= 0; i
< ELEMENTSOF(reserved_options
); i
++)
181 if (fstab_test_option(a
->extra_options
, reserved_options
[i
]))
182 return log_unit_error_errno(
184 SYNTHETIC_ERRNO(ENOEXEC
),
185 "ExtraOptions= setting may not contain reserved option %s.",
186 reserved_options
[i
]);
191 static int automount_set_where(Automount
*a
) {
199 r
= unit_name_to_path(UNIT(a
)->id
, &a
->where
);
203 path_simplify(a
->where
);
207 static int automount_add_extras(Automount
*a
) {
210 r
= automount_set_where(a
);
214 r
= automount_add_trigger_dependencies(a
);
218 r
= automount_add_mount_dependencies(a
);
222 return automount_add_default_dependencies(a
);
225 static int automount_load(Unit
*u
) {
226 Automount
*a
= ASSERT_PTR(AUTOMOUNT(u
));
229 assert(u
->load_state
== UNIT_STUB
);
231 /* Load a .automount file */
232 r
= unit_load_fragment_and_dropin(u
, true);
236 if (u
->load_state
!= UNIT_LOADED
)
239 r
= automount_add_extras(a
);
243 return automount_verify(a
);
246 static void automount_set_state(Automount
*a
, AutomountState state
) {
247 AutomountState old_state
;
251 if (a
->state
!= state
)
252 bus_unit_send_pending_change_signal(UNIT(a
), false);
254 old_state
= a
->state
;
257 if (state
!= AUTOMOUNT_RUNNING
)
258 automount_stop_expire(a
);
260 if (!IN_SET(state
, AUTOMOUNT_WAITING
, AUTOMOUNT_RUNNING
))
263 if (state
!= old_state
)
264 log_unit_debug(UNIT(a
), "Changed %s -> %s", automount_state_to_string(old_state
), automount_state_to_string(state
));
266 unit_notify(UNIT(a
), state_translation_table
[old_state
], state_translation_table
[state
], /* reload_success = */ true);
269 static int automount_coldplug(Unit
*u
) {
270 Automount
*a
= ASSERT_PTR(AUTOMOUNT(u
));
273 assert(a
->state
== AUTOMOUNT_DEAD
);
275 if (a
->deserialized_state
== a
->state
)
278 if (IN_SET(a
->deserialized_state
, AUTOMOUNT_WAITING
, AUTOMOUNT_RUNNING
)) {
280 r
= automount_set_where(a
);
284 r
= open_dev_autofs(u
->manager
);
288 assert(a
->pipe_fd
>= 0);
290 r
= sd_event_add_io(u
->manager
->event
, &a
->pipe_event_source
, a
->pipe_fd
, EPOLLIN
, automount_dispatch_io
, u
);
294 (void) sd_event_source_set_description(a
->pipe_event_source
, "automount-io");
295 if (a
->deserialized_state
== AUTOMOUNT_RUNNING
) {
296 r
= automount_start_expire(a
);
298 log_unit_warning_errno(UNIT(a
), r
, "Failed to start expiration timer, ignoring: %m");
301 automount_set_state(a
, a
->deserialized_state
);
307 static void automount_dump(Unit
*u
, FILE *f
, const char *prefix
) {
308 Automount
*a
= ASSERT_PTR(AUTOMOUNT(u
));
311 "%sAutomount State: %s\n"
314 "%sExtraOptions: %s\n"
315 "%sDirectoryMode: %04o\n"
316 "%sTimeoutIdleUSec: %s\n",
317 prefix
, automount_state_to_string(a
->state
),
318 prefix
, automount_result_to_string(a
->result
),
320 prefix
, a
->extra_options
,
321 prefix
, a
->directory_mode
,
322 prefix
, FORMAT_TIMESPAN(a
->timeout_idle_usec
, USEC_PER_SEC
));
325 static void automount_enter_dead(Automount
*a
, AutomountResult f
) {
328 if (a
->result
== AUTOMOUNT_SUCCESS
)
331 unit_log_result(UNIT(a
), a
->result
== AUTOMOUNT_SUCCESS
, automount_result_to_string(a
->result
));
332 automount_set_state(a
, a
->result
!= AUTOMOUNT_SUCCESS
? AUTOMOUNT_FAILED
: AUTOMOUNT_DEAD
);
335 static int open_dev_autofs(Manager
*m
) {
336 struct autofs_dev_ioctl param
;
341 if (m
->dev_autofs_fd
>= 0)
342 return m
->dev_autofs_fd
;
344 (void) label_fix("/dev/autofs", 0);
346 m
->dev_autofs_fd
= open("/dev/autofs", O_CLOEXEC
|O_RDONLY
);
347 if (m
->dev_autofs_fd
< 0)
348 return log_error_errno(errno
, "Failed to open /dev/autofs: %m");
350 init_autofs_dev_ioctl(¶m
);
351 r
= RET_NERRNO(ioctl(m
->dev_autofs_fd
, AUTOFS_DEV_IOCTL_VERSION
, ¶m
));
353 m
->dev_autofs_fd
= safe_close(m
->dev_autofs_fd
);
354 return log_error_errno(r
, "Failed to issue AUTOFS_DEV_IOCTL_VERSION ioctl: %m");
357 log_debug("Autofs kernel version %u.%u", param
.ver_major
, param
.ver_minor
);
359 return m
->dev_autofs_fd
;
362 static int open_ioctl_fd(int dev_autofs_fd
, const char *where
, dev_t devid
) {
363 struct autofs_dev_ioctl
*param
;
366 assert(dev_autofs_fd
>= 0);
369 l
= sizeof(struct autofs_dev_ioctl
) + strlen(where
) + 1;
370 param
= alloca_safe(l
);
372 init_autofs_dev_ioctl(param
);
374 param
->ioctlfd
= -EBADF
;
375 param
->openmount
.devid
= devid
;
376 strcpy(param
->path
, where
);
378 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_OPENMOUNT
, param
) < 0)
381 if (param
->ioctlfd
< 0)
384 (void) fd_cloexec(param
->ioctlfd
, true);
385 return param
->ioctlfd
;
388 static int autofs_protocol(int dev_autofs_fd
, int ioctl_fd
) {
389 uint32_t major
, minor
;
390 struct autofs_dev_ioctl param
;
392 assert(dev_autofs_fd
>= 0);
393 assert(ioctl_fd
>= 0);
395 init_autofs_dev_ioctl(¶m
);
396 param
.ioctlfd
= ioctl_fd
;
398 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_PROTOVER
, ¶m
) < 0)
401 major
= param
.protover
.version
;
403 init_autofs_dev_ioctl(¶m
);
404 param
.ioctlfd
= ioctl_fd
;
406 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_PROTOSUBVER
, ¶m
) < 0)
409 minor
= param
.protosubver
.sub_version
;
411 log_debug("Autofs protocol version %u.%u", major
, minor
);
415 static int autofs_set_timeout(int dev_autofs_fd
, int ioctl_fd
, usec_t usec
) {
416 struct autofs_dev_ioctl param
;
418 assert(dev_autofs_fd
>= 0);
419 assert(ioctl_fd
>= 0);
421 init_autofs_dev_ioctl(¶m
);
422 param
.ioctlfd
= ioctl_fd
;
424 if (usec
== USEC_INFINITY
)
425 param
.timeout
.timeout
= 0;
427 /* Convert to seconds, rounding up. */
428 param
.timeout
.timeout
= DIV_ROUND_UP(usec
, USEC_PER_SEC
);
430 return RET_NERRNO(ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_TIMEOUT
, ¶m
));
433 static int autofs_send_ready(int dev_autofs_fd
, int ioctl_fd
, uint32_t token
, int status
) {
434 struct autofs_dev_ioctl param
;
436 assert(dev_autofs_fd
>= 0);
437 assert(ioctl_fd
>= 0);
439 init_autofs_dev_ioctl(¶m
);
440 param
.ioctlfd
= ioctl_fd
;
443 param
.fail
.token
= token
;
444 param
.fail
.status
= status
;
446 param
.ready
.token
= token
;
448 return RET_NERRNO(ioctl(dev_autofs_fd
, status
? AUTOFS_DEV_IOCTL_FAIL
: AUTOFS_DEV_IOCTL_READY
, ¶m
));
451 static int automount_send_ready(Automount
*a
, Set
*tokens
, int status
) {
452 _cleanup_close_
int ioctl_fd
= -EBADF
;
459 if (set_isempty(tokens
))
462 ioctl_fd
= open_ioctl_fd(UNIT(a
)->manager
->dev_autofs_fd
, a
->where
, a
->dev_id
);
467 log_unit_debug_errno(UNIT(a
), status
, "Sending failure: %m");
469 log_unit_debug(UNIT(a
), "Sending success.");
473 /* Autofs thankfully does not hand out 0 as a token */
474 while ((token
= PTR_TO_UINT(set_steal_first(tokens
)))) {
479 * if you pass a positive status code here, kernels
480 * prior to 4.12 will freeze! Yay! */
482 k
= autofs_send_ready(UNIT(a
)->manager
->dev_autofs_fd
,
493 static void automount_trigger_notify(Unit
*u
, Unit
*other
) {
494 Automount
*a
= ASSERT_PTR(AUTOMOUNT(u
));
499 /* Filter out invocations with bogus state */
500 assert(UNIT_IS_LOAD_COMPLETE(other
->load_state
));
501 assert(other
->type
== UNIT_MOUNT
);
503 /* Don't propagate state changes from the mount if we are already down */
504 if (!IN_SET(a
->state
, AUTOMOUNT_WAITING
, AUTOMOUNT_RUNNING
))
507 /* Propagate start limit hit state */
508 if (other
->start_limit_hit
) {
509 automount_enter_dead(a
, AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT
);
513 /* Don't propagate anything if there's still a job queued */
517 /* The mount is successfully established */
518 if (IN_SET(MOUNT(other
)->state
, MOUNT_MOUNTED
, MOUNT_REMOUNTING
)) {
519 (void) automount_send_ready(a
, a
->tokens
, 0);
521 r
= automount_start_expire(a
);
523 log_unit_warning_errno(UNIT(a
), r
, "Failed to start expiration timer, ignoring: %m");
525 automount_set_state(a
, AUTOMOUNT_RUNNING
);
528 if (IN_SET(MOUNT(other
)->state
,
529 MOUNT_MOUNTING
, MOUNT_MOUNTING_DONE
,
530 MOUNT_MOUNTED
, MOUNT_REMOUNTING
,
531 MOUNT_REMOUNTING_SIGTERM
, MOUNT_REMOUNTING_SIGKILL
,
532 MOUNT_UNMOUNTING_SIGTERM
, MOUNT_UNMOUNTING_SIGKILL
,
534 (void) automount_send_ready(a
, a
->expire_tokens
, -ENODEV
);
536 if (MOUNT(other
)->state
== MOUNT_DEAD
)
537 (void) automount_send_ready(a
, a
->expire_tokens
, 0);
539 /* The mount is in some unhappy state now, let's unfreeze any waiting clients */
540 if (IN_SET(MOUNT(other
)->state
,
541 MOUNT_DEAD
, MOUNT_UNMOUNTING
,
542 MOUNT_REMOUNTING_SIGTERM
, MOUNT_REMOUNTING_SIGKILL
,
543 MOUNT_UNMOUNTING_SIGTERM
, MOUNT_UNMOUNTING_SIGKILL
,
546 (void) automount_send_ready(a
, a
->tokens
, -ENODEV
);
548 automount_set_state(a
, AUTOMOUNT_WAITING
);
552 static void automount_enter_waiting(Automount
*a
) {
553 _cleanup_close_pair_
int pipe_fd
[2] = EBADF_PAIR
;
554 _cleanup_close_
int ioctl_fd
= -EBADF
;
555 char name
[STRLEN("systemd-") + DECIMAL_STR_MAX(pid_t
) + 1];
556 _cleanup_free_
char *options
= NULL
;
557 bool mounted
= false;
558 int r
, dev_autofs_fd
;
562 assert(a
->pipe_fd
< 0);
565 set_clear(a
->tokens
);
567 r
= unit_fail_if_noncanonical(UNIT(a
), a
->where
);
571 (void) mkdir_p_label(a
->where
, a
->directory_mode
);
573 unit_warn_if_dir_nonempty(UNIT(a
), a
->where
);
575 dev_autofs_fd
= open_dev_autofs(UNIT(a
)->manager
);
576 if (dev_autofs_fd
< 0)
579 if (pipe2(pipe_fd
, O_CLOEXEC
) < 0) {
580 log_unit_warning_errno(UNIT(a
), errno
, "Failed to allocate autofs pipe: %m");
583 r
= fd_nonblock(pipe_fd
[0], true);
585 log_unit_warning_errno(UNIT(a
), r
, "Failed to make read side of pipe non-blocking: %m");
591 "fd=%i,pgrp="PID_FMT
",minproto=5,maxproto=5,direct%s%s",
594 isempty(a
->extra_options
) ? "" : ",",
595 strempty(a
->extra_options
)) < 0) {
600 xsprintf(name
, "systemd-"PID_FMT
, getpid_cached());
601 r
= mount_nofollow_verbose(LOG_WARNING
, name
, a
->where
, "autofs", 0, options
);
607 pipe_fd
[1] = safe_close(pipe_fd
[1]);
609 if (stat(a
->where
, &st
) < 0) {
610 log_unit_warning_errno(UNIT(a
), errno
, "Failed to stat new automount point '%s': %m", a
->where
);
614 ioctl_fd
= open_ioctl_fd(dev_autofs_fd
, a
->where
, st
.st_dev
);
616 log_unit_warning_errno(UNIT(a
), ioctl_fd
, "Failed to open automount ioctl fd for '%s': %m", a
->where
);
620 r
= autofs_protocol(dev_autofs_fd
, ioctl_fd
);
622 log_unit_warning_errno(UNIT(a
), r
, "Failed to validate autofs protocol for '%s': %m", a
->where
);
626 r
= autofs_set_timeout(dev_autofs_fd
, ioctl_fd
, a
->timeout_idle_usec
);
628 log_unit_warning_errno(UNIT(a
), r
, "Failed to set autofs timeout for '%s': %m", a
->where
);
632 r
= sd_event_add_io(UNIT(a
)->manager
->event
, &a
->pipe_event_source
, pipe_fd
[0], EPOLLIN
, automount_dispatch_io
, a
);
634 log_unit_warning_errno(UNIT(a
), r
, "Failed to allocate IO event source for autofs mount '%s': %m", a
->where
);
638 (void) sd_event_source_set_description(a
->pipe_event_source
, "automount-io");
640 a
->pipe_fd
= TAKE_FD(pipe_fd
[0]);
641 a
->dev_id
= st
.st_dev
;
643 automount_set_state(a
, AUTOMOUNT_WAITING
);
648 r
= repeat_unmount(a
->where
, MNT_DETACH
|UMOUNT_NOFOLLOW
);
650 log_unit_warning_errno(UNIT(a
), r
, "Failed to unmount, ignoring: %m");
653 automount_enter_dead(a
, AUTOMOUNT_FAILURE_RESOURCES
);
656 static int asynchronous_expire(int dev_autofs_fd
, int ioctl_fd
) {
659 assert(dev_autofs_fd
>= 0);
660 assert(ioctl_fd
>= 0);
662 /* Issue AUTOFS_DEV_IOCTL_EXPIRE in subprocess, asynchronously. Note that we don't keep track of the
663 * child's PID, we are PID1/autoreaper after all, hence when it dies we'll automatically clean it up
666 r
= safe_fork_full("(sd-expire)",
667 /* stdio_fds= */ NULL
,
668 (int[]) { dev_autofs_fd
, ioctl_fd
},
669 /* n_except_fds= */ 2,
670 FORK_RESET_SIGNALS
|FORK_CLOSE_ALL_FDS
|FORK_REOPEN_LOG
,
677 struct autofs_dev_ioctl param
;
678 init_autofs_dev_ioctl(¶m
);
679 param
.ioctlfd
= ioctl_fd
;
681 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_EXPIRE
, ¶m
) < 0)
686 log_warning_errno(errno
, "Failed to expire automount, ignoring: %m");
691 static int automount_dispatch_expire(sd_event_source
*source
, usec_t usec
, void *userdata
) {
692 Automount
*a
= ASSERT_PTR(AUTOMOUNT(userdata
));
693 _cleanup_close_
int ioctl_fd
= -EBADF
;
696 assert(source
== a
->expire_event_source
);
698 ioctl_fd
= open_ioctl_fd(UNIT(a
)->manager
->dev_autofs_fd
, a
->where
, a
->dev_id
);
700 return log_unit_error_errno(UNIT(a
), ioctl_fd
, "Couldn't open autofs ioctl fd: %m");
702 r
= asynchronous_expire(UNIT(a
)->manager
->dev_autofs_fd
, ioctl_fd
);
704 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
= MAX(a
->timeout_idle_usec
/3, USEC_PER_SEC
);
720 if (a
->expire_event_source
) {
721 r
= sd_event_source_set_time_relative(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_relative(
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 (void) 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
, NULL
, &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
= ASSERT_PTR(AUTOMOUNT(u
));
812 assert(IN_SET(a
->state
, AUTOMOUNT_DEAD
, AUTOMOUNT_FAILED
));
814 if (path_is_mount_point(a
->where
) > 0)
815 return log_unit_error_errno(u
, SYNTHETIC_ERRNO(EEXIST
), "Path %s is already a mount point, refusing start.", a
->where
);
817 r
= unit_test_trigger_loaded(u
);
821 r
= unit_acquire_invocation_id(u
);
825 a
->result
= AUTOMOUNT_SUCCESS
;
826 automount_enter_waiting(a
);
830 static int automount_stop(Unit
*u
) {
831 Automount
*a
= ASSERT_PTR(AUTOMOUNT(u
));
833 assert(IN_SET(a
->state
, AUTOMOUNT_WAITING
, AUTOMOUNT_RUNNING
));
835 automount_enter_dead(a
, AUTOMOUNT_SUCCESS
);
839 static int automount_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
840 Automount
*a
= ASSERT_PTR(AUTOMOUNT(u
));
847 (void) serialize_item(f
, "state", automount_state_to_string(a
->state
));
848 (void) serialize_item(f
, "result", automount_result_to_string(a
->result
));
849 (void) serialize_item_format(f
, "dev-id", "%lu", (unsigned long) a
->dev_id
);
851 SET_FOREACH(p
, a
->tokens
)
852 (void) serialize_item_format(f
, "token", "%u", PTR_TO_UINT(p
));
853 SET_FOREACH(p
, a
->expire_tokens
)
854 (void) serialize_item_format(f
, "expire-token", "%u", PTR_TO_UINT(p
));
856 r
= serialize_fd(f
, fds
, "pipe-fd", a
->pipe_fd
);
863 static int automount_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
864 Automount
*a
= ASSERT_PTR(AUTOMOUNT(u
));
869 if (streq(key
, "state")) {
870 AutomountState state
;
872 state
= automount_state_from_string(value
);
874 log_unit_debug(u
, "Failed to parse state value: %s", value
);
876 a
->deserialized_state
= state
;
877 } else if (streq(key
, "result")) {
880 f
= automount_result_from_string(value
);
882 log_unit_debug(u
, "Failed to parse result value: %s", value
);
883 else if (f
!= AUTOMOUNT_SUCCESS
)
886 } else if (streq(key
, "dev-id")) {
889 if (safe_atolu(value
, &d
) < 0)
890 log_unit_debug(u
, "Failed to parse dev-id value: %s", value
);
892 a
->dev_id
= (dev_t
) d
;
894 } else if (streq(key
, "token")) {
897 if (safe_atou(value
, &token
) < 0)
898 log_unit_debug(u
, "Failed to parse token value: %s", value
);
900 r
= set_ensure_put(&a
->tokens
, NULL
, UINT_TO_PTR(token
));
902 log_unit_error_errno(u
, r
, "Failed to add token to set: %m");
904 } else if (streq(key
, "expire-token")) {
907 if (safe_atou(value
, &token
) < 0)
908 log_unit_debug(u
, "Failed to parse token value: %s", value
);
910 r
= set_ensure_put(&a
->expire_tokens
, NULL
, UINT_TO_PTR(token
));
912 log_unit_error_errno(u
, r
, "Failed to add expire token to set: %m");
914 } else if (streq(key
, "pipe-fd")) {
915 safe_close(a
->pipe_fd
);
916 a
->pipe_fd
= deserialize_fd(fds
, value
);
918 log_unit_debug(u
, "Unknown serialization key: %s", key
);
923 static UnitActiveState
automount_active_state(Unit
*u
) {
926 return state_translation_table
[AUTOMOUNT(u
)->state
];
929 static const char *automount_sub_state_to_string(Unit
*u
) {
932 return automount_state_to_string(AUTOMOUNT(u
)->state
);
935 static bool automount_may_gc(Unit
*u
) {
944 return UNIT_VTABLE(t
)->may_gc(t
);
947 static int automount_dispatch_io(sd_event_source
*s
, int fd
, uint32_t events
, void *userdata
) {
948 Automount
*a
= ASSERT_PTR(AUTOMOUNT(userdata
));
949 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
950 union autofs_v5_packet_union packet
;
954 assert(fd
== a
->pipe_fd
);
956 if (events
& (EPOLLHUP
|EPOLLERR
)) {
957 log_unit_error(UNIT(a
), "Got hangup/error on autofs pipe from kernel. Likely our automount point has been unmounted by someone or something else?");
958 automount_enter_dead(a
, AUTOMOUNT_FAILURE_UNMOUNTED
);
962 if (events
!= EPOLLIN
) {
963 log_unit_error(UNIT(a
), "Got invalid poll event %"PRIu32
" on pipe (fd=%d)", events
, fd
);
967 r
= loop_read_exact(a
->pipe_fd
, &packet
, sizeof(packet
), true);
969 log_unit_error_errno(UNIT(a
), r
, "Invalid read from pipe: %m");
973 switch (packet
.hdr
.type
) {
975 case autofs_ptype_missing_direct
:
977 if (packet
.v5_packet
.pid
> 0) {
978 _cleanup_free_
char *p
= NULL
;
980 (void) pid_get_comm(packet
.v5_packet
.pid
, &p
);
981 log_unit_info(UNIT(a
), "Got automount request for %s, triggered by %"PRIu32
" (%s)", a
->where
, packet
.v5_packet
.pid
, strna(p
));
983 log_unit_debug(UNIT(a
), "Got direct mount request on %s", a
->where
);
985 r
= set_ensure_put(&a
->tokens
, NULL
, UINT_TO_PTR(packet
.v5_packet
.wait_queue_token
));
987 log_unit_error_errno(UNIT(a
), r
, "Failed to remember token: %m");
991 automount_enter_running(a
);
994 case autofs_ptype_expire_direct
:
995 log_unit_debug(UNIT(a
), "Got direct umount request on %s", a
->where
);
997 automount_stop_expire(a
);
999 r
= set_ensure_put(&a
->expire_tokens
, NULL
, UINT_TO_PTR(packet
.v5_packet
.wait_queue_token
));
1001 log_unit_error_errno(UNIT(a
), r
, "Failed to remember token: %m");
1005 trigger
= UNIT_TRIGGER(UNIT(a
));
1007 log_unit_error(UNIT(a
), "Unit to trigger vanished.");
1011 r
= manager_add_job(UNIT(a
)->manager
, JOB_STOP
, trigger
, JOB_REPLACE
, NULL
, &error
, NULL
);
1013 log_unit_warning(UNIT(a
), "Failed to queue unmount job: %s", bus_error_message(&error
, r
));
1019 log_unit_error(UNIT(a
), "Received unknown automount request %i", packet
.hdr
.type
);
1026 automount_enter_dead(a
, AUTOMOUNT_FAILURE_RESOURCES
);
1030 static void automount_shutdown(Manager
*m
) {
1033 m
->dev_autofs_fd
= safe_close(m
->dev_autofs_fd
);
1036 static void automount_reset_failed(Unit
*u
) {
1037 Automount
*a
= ASSERT_PTR(AUTOMOUNT(u
));
1039 if (a
->state
== AUTOMOUNT_FAILED
)
1040 automount_set_state(a
, AUTOMOUNT_DEAD
);
1042 a
->result
= AUTOMOUNT_SUCCESS
;
1045 static bool automount_supported(void) {
1046 static int supported
= -1;
1049 supported
= access("/dev/autofs", F_OK
) >= 0;
1054 static int automount_can_start(Unit
*u
) {
1055 Automount
*a
= ASSERT_PTR(AUTOMOUNT(u
));
1058 r
= unit_test_start_limit(u
);
1060 automount_enter_dead(a
, AUTOMOUNT_FAILURE_START_LIMIT_HIT
);
1067 static const char* const automount_result_table
[_AUTOMOUNT_RESULT_MAX
] = {
1068 [AUTOMOUNT_SUCCESS
] = "success",
1069 [AUTOMOUNT_FAILURE_RESOURCES
] = "resources",
1070 [AUTOMOUNT_FAILURE_START_LIMIT_HIT
] = "start-limit-hit",
1071 [AUTOMOUNT_FAILURE_MOUNT_START_LIMIT_HIT
] = "mount-start-limit-hit",
1072 [AUTOMOUNT_FAILURE_UNMOUNTED
] = "unmounted",
1075 DEFINE_STRING_TABLE_LOOKUP(automount_result
, AutomountResult
);
1077 const UnitVTable automount_vtable
= {
1078 .object_size
= sizeof(Automount
),
1084 .private_section
= "Automount",
1086 .can_transient
= true,
1088 .can_trigger
= true,
1089 .exclude_from_switch_root_serialization
= true,
1091 .init
= automount_init
,
1092 .load
= automount_load
,
1093 .done
= automount_done
,
1095 .coldplug
= automount_coldplug
,
1097 .dump
= automount_dump
,
1099 .start
= automount_start
,
1100 .stop
= automount_stop
,
1102 .serialize
= automount_serialize
,
1103 .deserialize_item
= automount_deserialize_item
,
1105 .active_state
= automount_active_state
,
1106 .sub_state_to_string
= automount_sub_state_to_string
,
1108 .may_gc
= automount_may_gc
,
1110 .trigger_notify
= automount_trigger_notify
,
1112 .reset_failed
= automount_reset_failed
,
1114 .bus_set_property
= bus_automount_set_property
,
1116 .shutdown
= automount_shutdown
,
1117 .supported
= automount_supported
,
1119 .status_message_formats
= {
1120 .finished_start_job
= {
1121 [JOB_DONE
] = "Set up automount %s.",
1122 [JOB_FAILED
] = "Failed to set up automount %s.",
1124 .finished_stop_job
= {
1125 [JOB_DONE
] = "Unset automount %s.",
1126 [JOB_FAILED
] = "Failed to unset automount %s.",
1130 .can_start
= automount_can_start
,