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/>.
24 #include <sys/mount.h>
27 #include <sys/epoll.h>
29 #include <linux/auto_fs4.h>
30 #include <linux/auto_dev-ioctl.h>
33 #include "automount.h"
35 #include "unit-name.h"
39 #include "path-util.h"
40 #include "dbus-automount.h"
42 #include "bus-error.h"
43 #include "formats-util.h"
44 #include "process-util.h"
47 static const UnitActiveState state_translation_table
[_AUTOMOUNT_STATE_MAX
] = {
48 [AUTOMOUNT_DEAD
] = UNIT_INACTIVE
,
49 [AUTOMOUNT_WAITING
] = UNIT_ACTIVE
,
50 [AUTOMOUNT_RUNNING
] = UNIT_ACTIVE
,
51 [AUTOMOUNT_FAILED
] = UNIT_FAILED
59 static inline void expire_data_free(struct expire_data
*data
) {
63 safe_close(data
->dev_autofs_fd
);
64 safe_close(data
->ioctl_fd
);
68 DEFINE_TRIVIAL_CLEANUP_FUNC(struct expire_data
*, expire_data_free
);
70 static int open_dev_autofs(Manager
*m
);
71 static int automount_dispatch_io(sd_event_source
*s
, int fd
, uint32_t events
, void *userdata
);
73 static void automount_init(Unit
*u
) {
74 Automount
*a
= AUTOMOUNT(u
);
77 assert(u
->load_state
== UNIT_STUB
);
80 a
->directory_mode
= 0755;
81 UNIT(a
)->ignore_on_isolate
= true;
84 static void repeat_unmount(const char *path
) {
88 /* If there are multiple mounts on a mount point, this
91 if (umount2(path
, MNT_DETACH
) >= 0)
95 log_error_errno(errno
, "Failed to unmount: %m");
101 static int automount_send_ready(Automount
*a
, Set
*tokens
, int status
);
103 static void unmount_autofs(Automount
*a
) {
109 automount_send_ready(a
, a
->tokens
, -EHOSTDOWN
);
110 automount_send_ready(a
, a
->expire_tokens
, -EHOSTDOWN
);
112 a
->pipe_event_source
= sd_event_source_unref(a
->pipe_event_source
);
113 a
->pipe_fd
= safe_close(a
->pipe_fd
);
115 /* If we reload/reexecute things we keep the mount point
118 (UNIT(a
)->manager
->exit_code
!= MANAGER_RELOAD
&&
119 UNIT(a
)->manager
->exit_code
!= MANAGER_REEXECUTE
))
120 repeat_unmount(a
->where
);
123 static void automount_done(Unit
*u
) {
124 Automount
*a
= AUTOMOUNT(u
);
135 set_free(a
->expire_tokens
);
136 a
->expire_tokens
= NULL
;
138 a
->expire_event_source
= sd_event_source_unref(a
->expire_event_source
);
141 static int automount_add_mount_links(Automount
*a
) {
142 _cleanup_free_
char *parent
= NULL
;
147 r
= path_get_parent(a
->where
, &parent
);
151 return unit_require_mounts_for(UNIT(a
), parent
);
154 static int automount_add_default_dependencies(Automount
*a
) {
159 if (UNIT(a
)->manager
->running_as
!= SYSTEMD_SYSTEM
)
162 r
= unit_add_two_dependencies_by_name(UNIT(a
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
169 static int automount_verify(Automount
*a
) {
171 _cleanup_free_
char *e
= NULL
;
174 if (UNIT(a
)->load_state
!= UNIT_LOADED
)
177 if (path_equal(a
->where
, "/")) {
178 log_unit_error(UNIT(a
)->id
, "Cannot have an automount unit for the root directory. Refusing.");
182 e
= unit_name_from_path(a
->where
, ".automount");
186 b
= unit_has_name(UNIT(a
), e
);
189 log_unit_error(UNIT(a
)->id
, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a
)->id
);
196 static int automount_load(Unit
*u
) {
197 Automount
*a
= AUTOMOUNT(u
);
201 assert(u
->load_state
== UNIT_STUB
);
203 /* Load a .automount file */
204 r
= unit_load_fragment_and_dropin_optional(u
);
208 if (u
->load_state
== UNIT_LOADED
) {
212 a
->where
= unit_name_to_path(u
->id
);
217 path_kill_slashes(a
->where
);
219 r
= unit_load_related_unit(u
, ".mount", &x
);
223 r
= unit_add_two_dependencies(u
, UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true);
227 r
= automount_add_mount_links(a
);
231 if (UNIT(a
)->default_dependencies
) {
232 r
= automount_add_default_dependencies(a
);
238 return automount_verify(a
);
241 static void automount_set_state(Automount
*a
, AutomountState state
) {
242 AutomountState old_state
;
245 old_state
= a
->state
;
248 if (state
!= AUTOMOUNT_WAITING
&&
249 state
!= AUTOMOUNT_RUNNING
)
252 if (state
!= old_state
)
253 log_unit_debug(UNIT(a
)->id
,
254 "%s changed %s -> %s",
256 automount_state_to_string(old_state
),
257 automount_state_to_string(state
));
259 unit_notify(UNIT(a
), state_translation_table
[old_state
], state_translation_table
[state
], true);
262 static int automount_coldplug(Unit
*u
) {
263 Automount
*a
= AUTOMOUNT(u
);
267 assert(a
->state
== AUTOMOUNT_DEAD
);
269 if (a
->deserialized_state
!= a
->state
) {
271 r
= open_dev_autofs(u
->manager
);
275 if (a
->deserialized_state
== AUTOMOUNT_WAITING
||
276 a
->deserialized_state
== AUTOMOUNT_RUNNING
) {
278 assert(a
->pipe_fd
>= 0);
280 r
= sd_event_add_io(u
->manager
->event
, &a
->pipe_event_source
, a
->pipe_fd
, EPOLLIN
, automount_dispatch_io
, u
);
285 automount_set_state(a
, a
->deserialized_state
);
291 static void automount_dump(Unit
*u
, FILE *f
, const char *prefix
) {
292 char time_string
[FORMAT_TIMESPAN_MAX
];
293 Automount
*a
= AUTOMOUNT(u
);
298 "%sAutomount State: %s\n"
301 "%sDirectoryMode: %04o\n"
302 "%sTimeoutIdleUSec: %s\n",
303 prefix
, automount_state_to_string(a
->state
),
304 prefix
, automount_result_to_string(a
->result
),
306 prefix
, a
->directory_mode
,
307 prefix
, format_timespan(time_string
, FORMAT_TIMESPAN_MAX
, a
->timeout_idle_usec
, USEC_PER_SEC
));
310 static void automount_enter_dead(Automount
*a
, AutomountResult f
) {
313 if (f
!= AUTOMOUNT_SUCCESS
)
316 automount_set_state(a
, a
->result
!= AUTOMOUNT_SUCCESS
? AUTOMOUNT_FAILED
: AUTOMOUNT_DEAD
);
319 static int open_dev_autofs(Manager
*m
) {
320 struct autofs_dev_ioctl param
;
324 if (m
->dev_autofs_fd
>= 0)
325 return m
->dev_autofs_fd
;
327 label_fix("/dev/autofs", false, false);
329 m
->dev_autofs_fd
= open("/dev/autofs", O_CLOEXEC
|O_RDONLY
);
330 if (m
->dev_autofs_fd
< 0)
331 return log_error_errno(errno
, "Failed to open /dev/autofs: %m");
333 init_autofs_dev_ioctl(¶m
);
334 if (ioctl(m
->dev_autofs_fd
, AUTOFS_DEV_IOCTL_VERSION
, ¶m
) < 0) {
335 m
->dev_autofs_fd
= safe_close(m
->dev_autofs_fd
);
339 log_debug("Autofs kernel version %i.%i", param
.ver_major
, param
.ver_minor
);
341 return m
->dev_autofs_fd
;
344 static int open_ioctl_fd(int dev_autofs_fd
, const char *where
, dev_t devid
) {
345 struct autofs_dev_ioctl
*param
;
348 assert(dev_autofs_fd
>= 0);
351 l
= sizeof(struct autofs_dev_ioctl
) + strlen(where
) + 1;
354 init_autofs_dev_ioctl(param
);
357 param
->openmount
.devid
= devid
;
358 strcpy(param
->path
, where
);
360 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_OPENMOUNT
, param
) < 0)
363 if (param
->ioctlfd
< 0)
366 (void) fd_cloexec(param
->ioctlfd
, true);
367 return param
->ioctlfd
;
370 static int autofs_protocol(int dev_autofs_fd
, int ioctl_fd
) {
371 uint32_t major
, minor
;
372 struct autofs_dev_ioctl param
;
374 assert(dev_autofs_fd
>= 0);
375 assert(ioctl_fd
>= 0);
377 init_autofs_dev_ioctl(¶m
);
378 param
.ioctlfd
= ioctl_fd
;
380 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_PROTOVER
, ¶m
) < 0)
383 major
= param
.protover
.version
;
385 init_autofs_dev_ioctl(¶m
);
386 param
.ioctlfd
= ioctl_fd
;
388 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_PROTOSUBVER
, ¶m
) < 0)
391 minor
= param
.protosubver
.sub_version
;
393 log_debug("Autofs protocol version %i.%i", major
, minor
);
397 static int autofs_set_timeout(int dev_autofs_fd
, int ioctl_fd
, usec_t usec
) {
398 struct autofs_dev_ioctl param
;
400 assert(dev_autofs_fd
>= 0);
401 assert(ioctl_fd
>= 0);
403 init_autofs_dev_ioctl(¶m
);
404 param
.ioctlfd
= ioctl_fd
;
406 /* Convert to seconds, rounding up. */
407 param
.timeout
.timeout
= (usec
+ USEC_PER_SEC
- 1) / USEC_PER_SEC
;
409 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_TIMEOUT
, ¶m
) < 0)
415 static int autofs_send_ready(int dev_autofs_fd
, int ioctl_fd
, uint32_t token
, int status
) {
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
;
425 param
.fail
.token
= token
;
426 param
.fail
.status
= status
;
428 param
.ready
.token
= token
;
430 if (ioctl(dev_autofs_fd
, status
? AUTOFS_DEV_IOCTL_FAIL
: AUTOFS_DEV_IOCTL_READY
, ¶m
) < 0)
436 static int automount_send_ready(Automount
*a
, Set
*tokens
, int status
) {
437 _cleanup_close_
int ioctl_fd
= -1;
444 if (set_isempty(tokens
))
447 ioctl_fd
= open_ioctl_fd(UNIT(a
)->manager
->dev_autofs_fd
, a
->where
, a
->dev_id
);
452 log_unit_debug_errno(UNIT(a
)->id
, status
, "Sending failure: %m");
454 log_unit_debug(UNIT(a
)->id
, "Sending success.");
458 /* Autofs thankfully does not hand out 0 as a token */
459 while ((token
= PTR_TO_UINT(set_steal_first(tokens
)))) {
462 /* Autofs fun fact II:
464 * if you pass a positive status code here, the kernel will
467 k
= autofs_send_ready(UNIT(a
)->manager
->dev_autofs_fd
,
478 int automount_update_mount(Automount
*a
, MountState old_state
, MountState state
) {
483 case MOUNT_REMOUNTING
:
484 automount_send_ready(a
, a
->tokens
, 0);
487 case MOUNT_UNMOUNTING
:
488 case MOUNT_MOUNTING_SIGTERM
:
489 case MOUNT_MOUNTING_SIGKILL
:
490 case MOUNT_REMOUNTING_SIGTERM
:
491 case MOUNT_REMOUNTING_SIGKILL
:
492 case MOUNT_UNMOUNTING_SIGTERM
:
493 case MOUNT_UNMOUNTING_SIGKILL
:
495 if (old_state
!= state
)
496 automount_send_ready(a
, a
->tokens
, -ENODEV
);
504 automount_send_ready(a
, a
->expire_tokens
, 0);
507 case MOUNT_MOUNTING_DONE
:
508 case MOUNT_MOUNTING_SIGTERM
:
509 case MOUNT_MOUNTING_SIGKILL
:
510 case MOUNT_REMOUNTING_SIGTERM
:
511 case MOUNT_REMOUNTING_SIGKILL
:
512 case MOUNT_UNMOUNTING_SIGTERM
:
513 case MOUNT_UNMOUNTING_SIGKILL
:
515 if (old_state
!= state
)
516 automount_send_ready(a
, a
->expire_tokens
, -ENODEV
);
525 static void automount_enter_waiting(Automount
*a
) {
526 _cleanup_close_
int ioctl_fd
= -1;
527 int p
[2] = { -1, -1 };
528 char name
[sizeof("systemd-")-1 + DECIMAL_STR_MAX(pid_t
) + 1];
529 char options
[sizeof("fd=,pgrp=,minproto=5,maxproto=5,direct")-1
530 + DECIMAL_STR_MAX(int) + DECIMAL_STR_MAX(gid_t
) + 1];
531 bool mounted
= false;
532 int r
, dev_autofs_fd
;
536 assert(a
->pipe_fd
< 0);
540 set_clear(a
->tokens
);
542 dev_autofs_fd
= open_dev_autofs(UNIT(a
)->manager
);
543 if (dev_autofs_fd
< 0) {
548 /* We knowingly ignore the results of this call */
549 mkdir_p_label(a
->where
, 0555);
551 warn_if_dir_nonempty(a
->meta
.id
, a
->where
);
553 if (pipe2(p
, O_NONBLOCK
|O_CLOEXEC
) < 0) {
558 xsprintf(options
, "fd=%i,pgrp="PID_FMT
",minproto=5,maxproto=5,direct", p
[1], getpgrp());
559 xsprintf(name
, "systemd-"PID_FMT
, getpid());
560 if (mount(name
, a
->where
, "autofs", 0, options
) < 0) {
567 p
[1] = safe_close(p
[1]);
569 if (stat(a
->where
, &st
) < 0) {
574 ioctl_fd
= open_ioctl_fd(dev_autofs_fd
, a
->where
, st
.st_dev
);
580 r
= autofs_protocol(dev_autofs_fd
, ioctl_fd
);
584 r
= autofs_set_timeout(dev_autofs_fd
, ioctl_fd
, a
->timeout_idle_usec
);
590 * Unless we close the ioctl fd here, for some weird reason
591 * the direct mount will not receive events from the
594 r
= sd_event_add_io(UNIT(a
)->manager
->event
, &a
->pipe_event_source
, p
[0], EPOLLIN
, automount_dispatch_io
, a
);
599 a
->dev_id
= st
.st_dev
;
601 automount_set_state(a
, AUTOMOUNT_WAITING
);
609 repeat_unmount(a
->where
);
611 log_unit_error(UNIT(a
)->id
,
612 "Failed to initialize automounter: %s", strerror(-r
));
613 automount_enter_dead(a
, AUTOMOUNT_FAILURE_RESOURCES
);
616 static void *expire_thread(void *p
) {
617 struct autofs_dev_ioctl param
;
618 _cleanup_(expire_data_freep
) struct expire_data
*data
= (struct expire_data
*)p
;
621 assert(data
->dev_autofs_fd
>= 0);
622 assert(data
->ioctl_fd
>= 0);
624 init_autofs_dev_ioctl(¶m
);
625 param
.ioctlfd
= data
->ioctl_fd
;
628 r
= ioctl(data
->dev_autofs_fd
, AUTOFS_DEV_IOCTL_EXPIRE
, ¶m
);
632 log_warning_errno(errno
, "Failed to expire automount, ignoring: %m");
637 static int automount_start_expire(Automount
*a
);
639 static int automount_dispatch_expire(sd_event_source
*source
, usec_t usec
, void *userdata
) {
640 Automount
*a
= AUTOMOUNT(userdata
);
641 _cleanup_(expire_data_freep
) struct expire_data
*data
= NULL
;
645 assert(source
== a
->expire_event_source
);
647 data
= new0(struct expire_data
, 1);
653 data
->dev_autofs_fd
= fcntl(UNIT(a
)->manager
->dev_autofs_fd
, F_DUPFD_CLOEXEC
, 3);
654 if (data
->dev_autofs_fd
< 0)
655 return log_unit_error_errno(UNIT(a
)->id
, errno
, "Failed to duplicate autofs fd: %m");
657 data
->ioctl_fd
= open_ioctl_fd(UNIT(a
)->manager
->dev_autofs_fd
, a
->where
, a
->dev_id
);
658 if (data
->ioctl_fd
< 0)
659 return log_unit_error_errno(UNIT(a
)->id
, data
->ioctl_fd
, "Couldn't open autofs ioctl fd: %m");
661 r
= asynchronous_job(expire_thread
, data
);
663 return log_unit_error_errno(UNIT(a
)->id
, r
, "Failed to start expire job: %m");
667 return automount_start_expire(a
);
670 static int automount_start_expire(Automount
*a
) {
676 timeout
= now(CLOCK_MONOTONIC
) + MAX(a
->timeout_idle_usec
/10, USEC_PER_SEC
);
678 if (a
->expire_event_source
) {
679 r
= sd_event_source_set_time(a
->expire_event_source
, timeout
);
683 return sd_event_source_set_enabled(a
->expire_event_source
, SD_EVENT_ONESHOT
);
686 return sd_event_add_time(
687 UNIT(a
)->manager
->event
,
688 &a
->expire_event_source
,
689 CLOCK_MONOTONIC
, timeout
, 0,
690 automount_dispatch_expire
, a
);
693 static void automount_enter_runnning(Automount
*a
) {
694 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
700 /* We don't take mount requests anymore if we are supposed to
701 * shut down anyway */
702 if (unit_stop_pending(UNIT(a
))) {
703 log_unit_debug(UNIT(a
)->id
,
704 "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a
)->id
);
705 automount_send_ready(a
, a
->tokens
, -EHOSTDOWN
);
706 automount_send_ready(a
, a
->expire_tokens
, -EHOSTDOWN
);
710 mkdir_p_label(a
->where
, a
->directory_mode
);
712 /* Before we do anything, let's see if somebody is playing games with us? */
713 if (lstat(a
->where
, &st
) < 0) {
714 log_unit_warning_errno(UNIT(a
)->id
, errno
, "%s failed to stat automount point: %m", UNIT(a
)->id
);
718 if (!S_ISDIR(st
.st_mode
) || st
.st_dev
!= a
->dev_id
)
719 log_unit_info(UNIT(a
)->id
,
720 "%s's automount point already active?", UNIT(a
)->id
);
722 r
= manager_add_job(UNIT(a
)->manager
, JOB_START
, UNIT_TRIGGER(UNIT(a
)),
723 JOB_REPLACE
, true, &error
, NULL
);
725 log_unit_warning(UNIT(a
)->id
,
726 "%s failed to queue mount startup job: %s",
727 UNIT(a
)->id
, bus_error_message(&error
, r
));
732 r
= automount_start_expire(a
);
734 log_unit_warning_errno(UNIT(a
)->id
, r
, "Failed to start expiration timer, ignoring: %m");
736 automount_set_state(a
, AUTOMOUNT_RUNNING
);
740 automount_enter_dead(a
, AUTOMOUNT_FAILURE_RESOURCES
);
743 static int automount_start(Unit
*u
) {
744 Automount
*a
= AUTOMOUNT(u
);
747 assert(a
->state
== AUTOMOUNT_DEAD
|| a
->state
== AUTOMOUNT_FAILED
);
749 if (path_is_mount_point(a
->where
, false) > 0) {
750 log_unit_error(u
->id
, "Path %s is already a mount point, refusing start for %s", a
->where
, u
->id
);
754 if (UNIT_TRIGGER(u
)->load_state
!= UNIT_LOADED
)
757 a
->result
= AUTOMOUNT_SUCCESS
;
758 automount_enter_waiting(a
);
762 static int automount_stop(Unit
*u
) {
763 Automount
*a
= AUTOMOUNT(u
);
766 assert(a
->state
== AUTOMOUNT_WAITING
|| a
->state
== AUTOMOUNT_RUNNING
);
768 automount_enter_dead(a
, AUTOMOUNT_SUCCESS
);
772 static int automount_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
773 Automount
*a
= AUTOMOUNT(u
);
781 unit_serialize_item(u
, f
, "state", automount_state_to_string(a
->state
));
782 unit_serialize_item(u
, f
, "result", automount_result_to_string(a
->result
));
783 unit_serialize_item_format(u
, f
, "dev-id", "%u", (unsigned) a
->dev_id
);
785 SET_FOREACH(p
, a
->tokens
, i
)
786 unit_serialize_item_format(u
, f
, "token", "%u", PTR_TO_UINT(p
));
787 SET_FOREACH(p
, a
->expire_tokens
, i
)
788 unit_serialize_item_format(u
, f
, "expire-token", "%u", PTR_TO_UINT(p
));
790 if (a
->pipe_fd
>= 0) {
793 copy
= fdset_put_dup(fds
, a
->pipe_fd
);
797 unit_serialize_item_format(u
, f
, "pipe-fd", "%i", copy
);
803 static int automount_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
804 Automount
*a
= AUTOMOUNT(u
);
810 if (streq(key
, "state")) {
811 AutomountState state
;
813 state
= automount_state_from_string(value
);
815 log_unit_debug(u
->id
, "Failed to parse state value %s", value
);
817 a
->deserialized_state
= state
;
818 } else if (streq(key
, "result")) {
821 f
= automount_result_from_string(value
);
823 log_unit_debug(u
->id
, "Failed to parse result value %s", value
);
824 else if (f
!= AUTOMOUNT_SUCCESS
)
827 } else if (streq(key
, "dev-id")) {
830 if (safe_atou(value
, &d
) < 0)
831 log_unit_debug(u
->id
, "Failed to parse dev-id value %s", value
);
833 a
->dev_id
= (unsigned) d
;
834 } else if (streq(key
, "token")) {
837 if (safe_atou(value
, &token
) < 0)
838 log_unit_debug(u
->id
, "Failed to parse token value %s", value
);
840 r
= set_ensure_allocated(&a
->tokens
, NULL
);
846 r
= set_put(a
->tokens
, UINT_TO_PTR(token
));
848 log_unit_error_errno(u
->id
, r
, "Failed to add token to set: %m");
850 } else if (streq(key
, "expire-token")) {
853 if (safe_atou(value
, &token
) < 0)
854 log_unit_debug(u
->id
, "Failed to parse token value %s", value
);
856 r
= set_ensure_allocated(&a
->expire_tokens
, NULL
);
862 r
= set_put(a
->expire_tokens
, UINT_TO_PTR(token
));
864 log_unit_error_errno(u
->id
, r
, "Failed to add expire token to set: %m");
866 } else if (streq(key
, "pipe-fd")) {
869 if (safe_atoi(value
, &fd
) < 0 || fd
< 0 || !fdset_contains(fds
, fd
))
870 log_unit_debug(u
->id
, "Failed to parse pipe-fd value %s", value
);
872 safe_close(a
->pipe_fd
);
873 a
->pipe_fd
= fdset_remove(fds
, fd
);
876 log_unit_debug(u
->id
, "Unknown serialization key '%s'", key
);
881 static UnitActiveState
automount_active_state(Unit
*u
) {
884 return state_translation_table
[AUTOMOUNT(u
)->state
];
887 static const char *automount_sub_state_to_string(Unit
*u
) {
890 return automount_state_to_string(AUTOMOUNT(u
)->state
);
893 static bool automount_check_gc(Unit
*u
) {
896 if (!UNIT_TRIGGER(u
))
899 return UNIT_VTABLE(UNIT_TRIGGER(u
))->check_gc(UNIT_TRIGGER(u
));
902 static int automount_dispatch_io(sd_event_source
*s
, int fd
, uint32_t events
, void *userdata
) {
903 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
904 union autofs_v5_packet_union packet
;
905 Automount
*a
= AUTOMOUNT(userdata
);
909 assert(fd
== a
->pipe_fd
);
911 if (events
!= EPOLLIN
) {
912 log_unit_error(UNIT(a
)->id
, "%s: got invalid poll event %"PRIu32
" on pipe (fd=%d)",
913 UNIT(a
)->id
, events
, fd
);
917 r
= loop_read_exact(a
->pipe_fd
, &packet
, sizeof(packet
), true);
919 log_unit_error_errno(UNIT(a
)->id
, r
, "Invalid read from pipe: %m");
923 switch (packet
.hdr
.type
) {
925 case autofs_ptype_missing_direct
:
927 if (packet
.v5_packet
.pid
> 0) {
928 _cleanup_free_
char *p
= NULL
;
930 get_process_comm(packet
.v5_packet
.pid
, &p
);
931 log_unit_info(UNIT(a
)->id
,
932 "Got automount request for %s, triggered by %"PRIu32
" (%s)",
933 a
->where
, packet
.v5_packet
.pid
, strna(p
));
935 log_unit_debug(UNIT(a
)->id
, "Got direct mount request on %s", a
->where
);
937 r
= set_ensure_allocated(&a
->tokens
, NULL
);
939 log_unit_error(UNIT(a
)->id
, "Failed to allocate token set.");
943 r
= set_put(a
->tokens
, UINT_TO_PTR(packet
.v5_packet
.wait_queue_token
));
945 log_unit_error_errno(UNIT(a
)->id
, r
, "Failed to remember token: %m");
949 automount_enter_runnning(a
);
952 case autofs_ptype_expire_direct
:
953 log_unit_debug(UNIT(a
)->id
, "Got direct umount request on %s", a
->where
);
955 (void) sd_event_source_set_enabled(a
->expire_event_source
, SD_EVENT_OFF
);
957 r
= set_ensure_allocated(&a
->expire_tokens
, NULL
);
959 log_unit_error(UNIT(a
)->id
, "Failed to allocate token set.");
963 r
= set_put(a
->expire_tokens
, UINT_TO_PTR(packet
.v5_packet
.wait_queue_token
));
965 log_unit_error_errno(UNIT(a
)->id
, r
, "Failed to remember token: %m");
968 r
= manager_add_job(UNIT(a
)->manager
, JOB_STOP
, UNIT_TRIGGER(UNIT(a
)), JOB_REPLACE
, true, &error
, NULL
);
970 log_unit_warning(UNIT(a
)->id
,
971 "%s failed to queue umount startup job: %s",
972 UNIT(a
)->id
, bus_error_message(&error
, r
));
978 log_unit_error(UNIT(a
)->id
, "Received unknown automount request %i", packet
.hdr
.type
);
985 automount_enter_dead(a
, AUTOMOUNT_FAILURE_RESOURCES
);
989 static void automount_shutdown(Manager
*m
) {
992 m
->dev_autofs_fd
= safe_close(m
->dev_autofs_fd
);
995 static void automount_reset_failed(Unit
*u
) {
996 Automount
*a
= AUTOMOUNT(u
);
1000 if (a
->state
== AUTOMOUNT_FAILED
)
1001 automount_set_state(a
, AUTOMOUNT_DEAD
);
1003 a
->result
= AUTOMOUNT_SUCCESS
;
1006 static bool automount_supported(Manager
*m
) {
1007 static int supported
= -1;
1012 supported
= access("/dev/autofs", F_OK
) >= 0;
1017 static const char* const automount_state_table
[_AUTOMOUNT_STATE_MAX
] = {
1018 [AUTOMOUNT_DEAD
] = "dead",
1019 [AUTOMOUNT_WAITING
] = "waiting",
1020 [AUTOMOUNT_RUNNING
] = "running",
1021 [AUTOMOUNT_FAILED
] = "failed"
1024 DEFINE_STRING_TABLE_LOOKUP(automount_state
, AutomountState
);
1026 static const char* const automount_result_table
[_AUTOMOUNT_RESULT_MAX
] = {
1027 [AUTOMOUNT_SUCCESS
] = "success",
1028 [AUTOMOUNT_FAILURE_RESOURCES
] = "resources"
1031 DEFINE_STRING_TABLE_LOOKUP(automount_result
, AutomountResult
);
1033 const UnitVTable automount_vtable
= {
1034 .object_size
= sizeof(Automount
),
1042 .no_instances
= true,
1044 .init
= automount_init
,
1045 .load
= automount_load
,
1046 .done
= automount_done
,
1048 .coldplug
= automount_coldplug
,
1050 .dump
= automount_dump
,
1052 .start
= automount_start
,
1053 .stop
= automount_stop
,
1055 .serialize
= automount_serialize
,
1056 .deserialize_item
= automount_deserialize_item
,
1058 .active_state
= automount_active_state
,
1059 .sub_state_to_string
= automount_sub_state_to_string
,
1061 .check_gc
= automount_check_gc
,
1063 .reset_failed
= automount_reset_failed
,
1065 .bus_interface
= "org.freedesktop.systemd1.Automount",
1066 .bus_vtable
= bus_automount_vtable
,
1068 .shutdown
= automount_shutdown
,
1069 .supported
= automount_supported
,
1071 .status_message_formats
= {
1072 .finished_start_job
= {
1073 [JOB_DONE
] = "Set up automount %s.",
1074 [JOB_FAILED
] = "Failed to set up automount %s.",
1075 [JOB_DEPENDENCY
] = "Dependency failed for %s.",
1077 .finished_stop_job
= {
1078 [JOB_DONE
] = "Unset automount %s.",
1079 [JOB_FAILED
] = "Failed to unset automount %s.",