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 "load-fragment.h"
36 #include "load-dropin.h"
37 #include "unit-name.h"
41 #include "path-util.h"
42 #include "dbus-automount.h"
44 #include "bus-error.h"
46 static const UnitActiveState state_translation_table
[_AUTOMOUNT_STATE_MAX
] = {
47 [AUTOMOUNT_DEAD
] = UNIT_INACTIVE
,
48 [AUTOMOUNT_WAITING
] = UNIT_ACTIVE
,
49 [AUTOMOUNT_RUNNING
] = UNIT_ACTIVE
,
50 [AUTOMOUNT_FAILED
] = UNIT_FAILED
53 static int open_dev_autofs(Manager
*m
);
54 static int automount_dispatch_io(sd_event_source
*s
, int fd
, uint32_t events
, void *userdata
);
56 static void automount_init(Unit
*u
) {
57 Automount
*a
= AUTOMOUNT(u
);
60 assert(u
->load_state
== UNIT_STUB
);
63 a
->directory_mode
= 0755;
64 UNIT(a
)->ignore_on_isolate
= true;
67 static void repeat_unmount(const char *path
) {
71 /* If there are multiple mounts on a mount point, this
74 if (umount2(path
, MNT_DETACH
) >= 0)
78 log_error("Failed to unmount: %m");
84 static void unmount_autofs(Automount
*a
) {
90 automount_send_ready(a
, -EHOSTDOWN
);
92 a
->pipe_event_source
= sd_event_source_unref(a
->pipe_event_source
);
94 close_nointr_nofail(a
->pipe_fd
);
97 /* If we reload/reexecute things we keep the mount point
100 (UNIT(a
)->manager
->exit_code
!= MANAGER_RELOAD
&&
101 UNIT(a
)->manager
->exit_code
!= MANAGER_REEXECUTE
))
102 repeat_unmount(a
->where
);
105 static void automount_done(Unit
*u
) {
106 Automount
*a
= AUTOMOUNT(u
);
119 static int automount_add_mount_links(Automount
*a
) {
120 _cleanup_free_
char *parent
= NULL
;
125 r
= path_get_parent(a
->where
, &parent
);
129 return unit_require_mounts_for(UNIT(a
), parent
);
132 static int automount_add_default_dependencies(Automount
*a
) {
137 if (UNIT(a
)->manager
->running_as
!= SYSTEMD_SYSTEM
)
140 r
= unit_add_two_dependencies_by_name(UNIT(a
), UNIT_BEFORE
, UNIT_CONFLICTS
, SPECIAL_UMOUNT_TARGET
, NULL
, true);
147 static int automount_verify(Automount
*a
) {
152 if (UNIT(a
)->load_state
!= UNIT_LOADED
)
155 if (path_equal(a
->where
, "/")) {
156 log_error_unit(UNIT(a
)->id
, "Cannot have an automount unit for the root directory. Refusing.");
160 e
= unit_name_from_path(a
->where
, ".automount");
164 b
= unit_has_name(UNIT(a
), e
);
168 log_error_unit(UNIT(a
)->id
, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a
)->id
);
175 static int automount_load(Unit
*u
) {
176 Automount
*a
= AUTOMOUNT(u
);
180 assert(u
->load_state
== UNIT_STUB
);
182 /* Load a .automount file */
183 r
= unit_load_fragment_and_dropin_optional(u
);
187 if (u
->load_state
== UNIT_LOADED
) {
191 a
->where
= unit_name_to_path(u
->id
);
196 path_kill_slashes(a
->where
);
198 r
= unit_load_related_unit(u
, ".mount", &x
);
202 r
= unit_add_two_dependencies(u
, UNIT_BEFORE
, UNIT_TRIGGERS
, x
, true);
206 r
= automount_add_mount_links(a
);
210 if (UNIT(a
)->default_dependencies
) {
211 r
= automount_add_default_dependencies(a
);
217 return automount_verify(a
);
220 static void automount_set_state(Automount
*a
, AutomountState state
) {
221 AutomountState old_state
;
224 old_state
= a
->state
;
227 if (state
!= AUTOMOUNT_WAITING
&&
228 state
!= AUTOMOUNT_RUNNING
)
231 if (state
!= old_state
)
232 log_debug_unit(UNIT(a
)->id
,
233 "%s changed %s -> %s",
235 automount_state_to_string(old_state
),
236 automount_state_to_string(state
));
238 unit_notify(UNIT(a
), state_translation_table
[old_state
], state_translation_table
[state
], true);
241 static int automount_coldplug(Unit
*u
) {
242 Automount
*a
= AUTOMOUNT(u
);
246 assert(a
->state
== AUTOMOUNT_DEAD
);
248 if (a
->deserialized_state
!= a
->state
) {
250 r
= open_dev_autofs(u
->manager
);
254 if (a
->deserialized_state
== AUTOMOUNT_WAITING
||
255 a
->deserialized_state
== AUTOMOUNT_RUNNING
) {
257 assert(a
->pipe_fd
>= 0);
259 r
= sd_event_add_io(u
->manager
->event
, a
->pipe_fd
, EPOLLIN
, automount_dispatch_io
, u
, &a
->pipe_event_source
);
264 automount_set_state(a
, a
->deserialized_state
);
270 static void automount_dump(Unit
*u
, FILE *f
, const char *prefix
) {
271 Automount
*a
= AUTOMOUNT(u
);
276 "%sAutomount State: %s\n"
279 "%sDirectoryMode: %04o\n",
280 prefix
, automount_state_to_string(a
->state
),
281 prefix
, automount_result_to_string(a
->result
),
283 prefix
, a
->directory_mode
);
286 static void automount_enter_dead(Automount
*a
, AutomountResult f
) {
289 if (f
!= AUTOMOUNT_SUCCESS
)
292 automount_set_state(a
, a
->result
!= AUTOMOUNT_SUCCESS
? AUTOMOUNT_FAILED
: AUTOMOUNT_DEAD
);
295 static int open_dev_autofs(Manager
*m
) {
296 struct autofs_dev_ioctl param
;
300 if (m
->dev_autofs_fd
>= 0)
301 return m
->dev_autofs_fd
;
303 label_fix("/dev/autofs", false, false);
305 m
->dev_autofs_fd
= open("/dev/autofs", O_CLOEXEC
|O_RDONLY
);
306 if (m
->dev_autofs_fd
< 0) {
307 log_error("Failed to open /dev/autofs: %m");
311 init_autofs_dev_ioctl(¶m
);
312 if (ioctl(m
->dev_autofs_fd
, AUTOFS_DEV_IOCTL_VERSION
, ¶m
) < 0) {
313 close_nointr_nofail(m
->dev_autofs_fd
);
314 m
->dev_autofs_fd
= -1;
318 log_debug("Autofs kernel version %i.%i", param
.ver_major
, param
.ver_minor
);
320 return m
->dev_autofs_fd
;
323 static int open_ioctl_fd(int dev_autofs_fd
, const char *where
, dev_t devid
) {
324 struct autofs_dev_ioctl
*param
;
327 assert(dev_autofs_fd
>= 0);
330 l
= sizeof(struct autofs_dev_ioctl
) + strlen(where
) + 1;
333 init_autofs_dev_ioctl(param
);
336 param
->openmount
.devid
= devid
;
337 strcpy(param
->path
, where
);
339 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_OPENMOUNT
, param
) < 0)
342 if (param
->ioctlfd
< 0)
345 fd_cloexec(param
->ioctlfd
, true);
346 return param
->ioctlfd
;
349 static int autofs_protocol(int dev_autofs_fd
, int ioctl_fd
) {
350 uint32_t major
, minor
;
351 struct autofs_dev_ioctl param
;
353 assert(dev_autofs_fd
>= 0);
354 assert(ioctl_fd
>= 0);
356 init_autofs_dev_ioctl(¶m
);
357 param
.ioctlfd
= ioctl_fd
;
359 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_PROTOVER
, ¶m
) < 0)
362 major
= param
.protover
.version
;
364 init_autofs_dev_ioctl(¶m
);
365 param
.ioctlfd
= ioctl_fd
;
367 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_PROTOSUBVER
, ¶m
) < 0)
370 minor
= param
.protosubver
.sub_version
;
372 log_debug("Autofs protocol version %i.%i", major
, minor
);
376 static int autofs_set_timeout(int dev_autofs_fd
, int ioctl_fd
, time_t sec
) {
377 struct autofs_dev_ioctl param
;
379 assert(dev_autofs_fd
>= 0);
380 assert(ioctl_fd
>= 0);
382 init_autofs_dev_ioctl(¶m
);
383 param
.ioctlfd
= ioctl_fd
;
384 param
.timeout
.timeout
= sec
;
386 if (ioctl(dev_autofs_fd
, AUTOFS_DEV_IOCTL_TIMEOUT
, ¶m
) < 0)
392 static int autofs_send_ready(int dev_autofs_fd
, int ioctl_fd
, uint32_t token
, int status
) {
393 struct autofs_dev_ioctl param
;
395 assert(dev_autofs_fd
>= 0);
396 assert(ioctl_fd
>= 0);
398 init_autofs_dev_ioctl(¶m
);
399 param
.ioctlfd
= ioctl_fd
;
402 param
.fail
.token
= token
;
403 param
.fail
.status
= status
;
405 param
.ready
.token
= token
;
407 if (ioctl(dev_autofs_fd
, status
? AUTOFS_DEV_IOCTL_FAIL
: AUTOFS_DEV_IOCTL_READY
, ¶m
) < 0)
413 int automount_send_ready(Automount
*a
, int status
) {
420 if (set_isempty(a
->tokens
))
423 ioctl_fd
= open_ioctl_fd(UNIT(a
)->manager
->dev_autofs_fd
, a
->where
, a
->dev_id
);
430 log_debug_unit(UNIT(a
)->id
, "Sending failure: %s", strerror(-status
));
432 log_debug_unit(UNIT(a
)->id
, "Sending success.");
436 /* Autofs thankfully does not hand out 0 as a token */
437 while ((token
= PTR_TO_UINT(set_steal_first(a
->tokens
)))) {
440 /* Autofs fun fact II:
442 * if you pass a positive status code here, the kernel will
445 k
= autofs_send_ready(UNIT(a
)->manager
->dev_autofs_fd
,
455 close_nointr_nofail(ioctl_fd
);
460 static void automount_enter_waiting(Automount
*a
) {
461 int p
[2] = { -1, -1 };
462 char name
[32], options
[128];
463 bool mounted
= false;
464 int r
, ioctl_fd
= -1, dev_autofs_fd
;
468 assert(a
->pipe_fd
< 0);
472 set_clear(a
->tokens
);
474 dev_autofs_fd
= open_dev_autofs(UNIT(a
)->manager
);
475 if (dev_autofs_fd
< 0) {
480 /* We knowingly ignore the results of this call */
481 mkdir_p_label(a
->where
, 0555);
483 warn_if_dir_nonempty(a
->meta
.id
, a
->where
);
485 if (pipe2(p
, O_NONBLOCK
|O_CLOEXEC
) < 0) {
490 snprintf(options
, sizeof(options
), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p
[1], (unsigned) getpgrp());
491 char_array_0(options
);
493 snprintf(name
, sizeof(name
), "systemd-%u", (unsigned) getpid());
496 if (mount(name
, a
->where
, "autofs", 0, options
) < 0) {
503 close_nointr_nofail(p
[1]);
506 if (stat(a
->where
, &st
) < 0) {
511 ioctl_fd
= open_ioctl_fd(dev_autofs_fd
, a
->where
, st
.st_dev
);
517 r
= autofs_protocol(dev_autofs_fd
, ioctl_fd
);
521 r
= autofs_set_timeout(dev_autofs_fd
, ioctl_fd
, 300);
527 * Unless we close the ioctl fd here, for some weird reason
528 * the direct mount will not receive events from the
531 close_nointr_nofail(ioctl_fd
);
534 r
= sd_event_add_io(UNIT(a
)->manager
->event
, p
[0], EPOLLIN
, automount_dispatch_io
, a
, &a
->pipe_event_source
);
539 a
->dev_id
= st
.st_dev
;
541 automount_set_state(a
, AUTOMOUNT_WAITING
);
546 assert_se(close_pipe(p
) == 0);
549 close_nointr_nofail(ioctl_fd
);
552 repeat_unmount(a
->where
);
554 log_error_unit(UNIT(a
)->id
,
555 "Failed to initialize automounter: %s", strerror(-r
));
556 automount_enter_dead(a
, AUTOMOUNT_FAILURE_RESOURCES
);
559 static void automount_enter_runnning(Automount
*a
) {
560 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
566 /* We don't take mount requests anymore if we are supposed to
567 * shut down anyway */
568 if (unit_stop_pending(UNIT(a
))) {
569 log_debug_unit(UNIT(a
)->id
,
570 "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a
)->id
);
571 automount_send_ready(a
, -EHOSTDOWN
);
575 mkdir_p_label(a
->where
, a
->directory_mode
);
577 /* Before we do anything, let's see if somebody is playing games with us? */
578 if (lstat(a
->where
, &st
) < 0) {
579 log_warning_unit(UNIT(a
)->id
,
580 "%s failed to stat automount point: %m", UNIT(a
)->id
);
584 if (!S_ISDIR(st
.st_mode
) || st
.st_dev
!= a
->dev_id
)
585 log_info_unit(UNIT(a
)->id
,
586 "%s's automount point already active?", UNIT(a
)->id
);
588 r
= manager_add_job(UNIT(a
)->manager
, JOB_START
, UNIT_TRIGGER(UNIT(a
)),
589 JOB_REPLACE
, true, &error
, NULL
);
591 log_warning_unit(UNIT(a
)->id
,
592 "%s failed to queue mount startup job: %s",
593 UNIT(a
)->id
, bus_error_message(&error
, r
));
598 automount_set_state(a
, AUTOMOUNT_RUNNING
);
602 automount_enter_dead(a
, AUTOMOUNT_FAILURE_RESOURCES
);
605 static int automount_start(Unit
*u
) {
606 Automount
*a
= AUTOMOUNT(u
);
609 assert(a
->state
== AUTOMOUNT_DEAD
|| a
->state
== AUTOMOUNT_FAILED
);
611 if (path_is_mount_point(a
->where
, false)) {
612 log_error_unit(u
->id
,
613 "Path %s is already a mount point, refusing start for %s",
618 if (UNIT_TRIGGER(u
)->load_state
!= UNIT_LOADED
)
621 a
->result
= AUTOMOUNT_SUCCESS
;
622 automount_enter_waiting(a
);
626 static int automount_stop(Unit
*u
) {
627 Automount
*a
= AUTOMOUNT(u
);
630 assert(a
->state
== AUTOMOUNT_WAITING
|| a
->state
== AUTOMOUNT_RUNNING
);
632 automount_enter_dead(a
, AUTOMOUNT_SUCCESS
);
636 static int automount_serialize(Unit
*u
, FILE *f
, FDSet
*fds
) {
637 Automount
*a
= AUTOMOUNT(u
);
645 unit_serialize_item(u
, f
, "state", automount_state_to_string(a
->state
));
646 unit_serialize_item(u
, f
, "result", automount_result_to_string(a
->result
));
647 unit_serialize_item_format(u
, f
, "dev-id", "%u", (unsigned) a
->dev_id
);
649 SET_FOREACH(p
, a
->tokens
, i
)
650 unit_serialize_item_format(u
, f
, "token", "%u", PTR_TO_UINT(p
));
652 if (a
->pipe_fd
>= 0) {
655 copy
= fdset_put_dup(fds
, a
->pipe_fd
);
659 unit_serialize_item_format(u
, f
, "pipe-fd", "%i", copy
);
665 static int automount_deserialize_item(Unit
*u
, const char *key
, const char *value
, FDSet
*fds
) {
666 Automount
*a
= AUTOMOUNT(u
);
672 if (streq(key
, "state")) {
673 AutomountState state
;
675 state
= automount_state_from_string(value
);
677 log_debug_unit(u
->id
, "Failed to parse state value %s", value
);
679 a
->deserialized_state
= state
;
680 } else if (streq(key
, "result")) {
683 f
= automount_result_from_string(value
);
685 log_debug_unit(u
->id
, "Failed to parse result value %s", value
);
686 else if (f
!= AUTOMOUNT_SUCCESS
)
689 } else if (streq(key
, "dev-id")) {
692 if (safe_atou(value
, &d
) < 0)
693 log_debug_unit(u
->id
, "Failed to parse dev-id value %s", value
);
695 a
->dev_id
= (unsigned) d
;
696 } else if (streq(key
, "token")) {
699 if (safe_atou(value
, &token
) < 0)
700 log_debug_unit(u
->id
, "Failed to parse token value %s", value
);
703 if (!(a
->tokens
= set_new(trivial_hash_func
, trivial_compare_func
)))
706 r
= set_put(a
->tokens
, UINT_TO_PTR(token
));
710 } else if (streq(key
, "pipe-fd")) {
713 if (safe_atoi(value
, &fd
) < 0 || fd
< 0 || !fdset_contains(fds
, fd
))
714 log_debug_unit(u
->id
, "Failed to parse pipe-fd value %s", value
);
717 close_nointr_nofail(a
->pipe_fd
);
719 a
->pipe_fd
= fdset_remove(fds
, fd
);
722 log_debug_unit(u
->id
, "Unknown serialization key '%s'", key
);
727 static UnitActiveState
automount_active_state(Unit
*u
) {
730 return state_translation_table
[AUTOMOUNT(u
)->state
];
733 static const char *automount_sub_state_to_string(Unit
*u
) {
736 return automount_state_to_string(AUTOMOUNT(u
)->state
);
739 static bool automount_check_gc(Unit
*u
) {
742 if (!UNIT_TRIGGER(u
))
745 return UNIT_VTABLE(UNIT_TRIGGER(u
))->check_gc(UNIT_TRIGGER(u
));
748 static int automount_dispatch_io(sd_event_source
*s
, int fd
, uint32_t events
, void *userdata
) {
749 union autofs_v5_packet_union packet
;
750 Automount
*a
= AUTOMOUNT(userdata
);
755 assert(fd
== a
->pipe_fd
);
757 if (events
!= EPOLLIN
) {
758 log_error_unit(UNIT(a
)->id
, "Got invalid poll event on pipe.");
762 l
= loop_read(a
->pipe_fd
, &packet
, sizeof(packet
), true);
763 if (l
!= sizeof(packet
)) {
764 log_error_unit(UNIT(a
)->id
, "Invalid read from pipe: %s", l
< 0 ? strerror(-l
) : "short read");
768 switch (packet
.hdr
.type
) {
770 case autofs_ptype_missing_direct
:
772 if (packet
.v5_packet
.pid
> 0) {
773 _cleanup_free_
char *p
= NULL
;
775 get_process_comm(packet
.v5_packet
.pid
, &p
);
776 log_info_unit(UNIT(a
)->id
,
777 "Got automount request for %s, triggered by "PID_FMT
" (%s)",
778 a
->where
, packet
.v5_packet
.pid
, strna(p
));
780 log_debug_unit(UNIT(a
)->id
, "Got direct mount request on %s", a
->where
);
782 r
= set_ensure_allocated(&a
->tokens
, trivial_hash_func
, trivial_compare_func
);
784 log_error_unit(UNIT(a
)->id
, "Failed to allocate token set.");
788 r
= set_put(a
->tokens
, UINT_TO_PTR(packet
.v5_packet
.wait_queue_token
));
790 log_error_unit(UNIT(a
)->id
, "Failed to remember token: %s", strerror(-r
));
794 automount_enter_runnning(a
);
798 log_error_unit(UNIT(a
)->id
, "Received unknown automount request %i", packet
.hdr
.type
);
805 automount_enter_dead(a
, AUTOMOUNT_FAILURE_RESOURCES
);
809 static void automount_shutdown(Manager
*m
) {
812 if (m
->dev_autofs_fd
>= 0)
813 close_nointr_nofail(m
->dev_autofs_fd
);
816 static void automount_reset_failed(Unit
*u
) {
817 Automount
*a
= AUTOMOUNT(u
);
821 if (a
->state
== AUTOMOUNT_FAILED
)
822 automount_set_state(a
, AUTOMOUNT_DEAD
);
824 a
->result
= AUTOMOUNT_SUCCESS
;
827 static const char* const automount_state_table
[_AUTOMOUNT_STATE_MAX
] = {
828 [AUTOMOUNT_DEAD
] = "dead",
829 [AUTOMOUNT_WAITING
] = "waiting",
830 [AUTOMOUNT_RUNNING
] = "running",
831 [AUTOMOUNT_FAILED
] = "failed"
834 DEFINE_STRING_TABLE_LOOKUP(automount_state
, AutomountState
);
836 static const char* const automount_result_table
[_AUTOMOUNT_RESULT_MAX
] = {
837 [AUTOMOUNT_SUCCESS
] = "success",
838 [AUTOMOUNT_FAILURE_RESOURCES
] = "resources"
841 DEFINE_STRING_TABLE_LOOKUP(automount_result
, AutomountResult
);
843 const UnitVTable automount_vtable
= {
844 .object_size
= sizeof(Automount
),
852 .no_instances
= true,
854 .init
= automount_init
,
855 .load
= automount_load
,
856 .done
= automount_done
,
858 .coldplug
= automount_coldplug
,
860 .dump
= automount_dump
,
862 .start
= automount_start
,
863 .stop
= automount_stop
,
865 .serialize
= automount_serialize
,
866 .deserialize_item
= automount_deserialize_item
,
868 .active_state
= automount_active_state
,
869 .sub_state_to_string
= automount_sub_state_to_string
,
871 .check_gc
= automount_check_gc
,
873 .reset_failed
= automount_reset_failed
,
875 .bus_interface
= "org.freedesktop.systemd1.Automount",
876 .bus_vtable
= bus_automount_vtable
,
878 .shutdown
= automount_shutdown
,
880 .status_message_formats
= {
881 .finished_start_job
= {
882 [JOB_DONE
] = "Set up automount %s.",
883 [JOB_FAILED
] = "Failed to set up automount %s.",
884 [JOB_DEPENDENCY
] = "Dependency failed for %s.",
886 .finished_stop_job
= {
887 [JOB_DONE
] = "Unset automount %s.",
888 [JOB_FAILED
] = "Failed to unset automount %s.",