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);
93 a->pipe_fd = safe_close(a->pipe_fd);
95 /* If we reload/reexecute things we keep the mount point
98 (UNIT(a)->manager->exit_code != MANAGER_RELOAD &&
99 UNIT(a)->manager->exit_code != MANAGER_REEXECUTE))
100 repeat_unmount(a->where);
103 static void automount_done(Unit *u) {
104 Automount *a = AUTOMOUNT(u);
117 static int automount_add_mount_links(Automount *a) {
118 _cleanup_free_ char *parent = NULL;
123 r = path_get_parent(a->where, &parent);
127 return unit_require_mounts_for(UNIT(a), parent);
130 static int automount_add_default_dependencies(Automount *a) {
135 if (UNIT(a)->manager->running_as != SYSTEMD_SYSTEM)
138 r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
145 static int automount_verify(Automount *a) {
150 if (UNIT(a)->load_state != UNIT_LOADED)
153 if (path_equal(a->where, "/")) {
154 log_error_unit(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing.");
158 e = unit_name_from_path(a->where, ".automount");
162 b = unit_has_name(UNIT(a), e);
166 log_error_unit(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
173 static int automount_load(Unit *u) {
174 Automount *a = AUTOMOUNT(u);
178 assert(u->load_state == UNIT_STUB);
180 /* Load a .automount file */
181 r = unit_load_fragment_and_dropin_optional(u);
185 if (u->load_state == UNIT_LOADED) {
189 a->where = unit_name_to_path(u->id);
194 path_kill_slashes(a->where);
196 r = unit_load_related_unit(u, ".mount", &x);
200 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
204 r = automount_add_mount_links(a);
208 if (UNIT(a)->default_dependencies) {
209 r = automount_add_default_dependencies(a);
215 return automount_verify(a);
218 static void automount_set_state(Automount *a, AutomountState state) {
219 AutomountState old_state;
222 old_state = a->state;
225 if (state != AUTOMOUNT_WAITING &&
226 state != AUTOMOUNT_RUNNING)
229 if (state != old_state)
230 log_debug_unit(UNIT(a)->id,
231 "%s changed %s -> %s",
233 automount_state_to_string(old_state),
234 automount_state_to_string(state));
236 unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
239 static int automount_coldplug(Unit *u) {
240 Automount *a = AUTOMOUNT(u);
244 assert(a->state == AUTOMOUNT_DEAD);
246 if (a->deserialized_state != a->state) {
248 r = open_dev_autofs(u->manager);
252 if (a->deserialized_state == AUTOMOUNT_WAITING ||
253 a->deserialized_state == AUTOMOUNT_RUNNING) {
255 assert(a->pipe_fd >= 0);
257 r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u);
262 automount_set_state(a, a->deserialized_state);
268 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
269 Automount *a = AUTOMOUNT(u);
274 "%sAutomount State: %s\n"
277 "%sDirectoryMode: %04o\n",
278 prefix, automount_state_to_string(a->state),
279 prefix, automount_result_to_string(a->result),
281 prefix, a->directory_mode);
284 static void automount_enter_dead(Automount *a, AutomountResult f) {
287 if (f != AUTOMOUNT_SUCCESS)
290 automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
293 static int open_dev_autofs(Manager *m) {
294 struct autofs_dev_ioctl param;
298 if (m->dev_autofs_fd >= 0)
299 return m->dev_autofs_fd;
301 label_fix("/dev/autofs", false, false);
303 m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY);
304 if (m->dev_autofs_fd < 0) {
305 log_error("Failed to open /dev/autofs: %m");
309 init_autofs_dev_ioctl(¶m);
310 if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, ¶m) < 0) {
311 m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
315 log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
317 return m->dev_autofs_fd;
320 static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
321 struct autofs_dev_ioctl *param;
324 assert(dev_autofs_fd >= 0);
327 l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
330 init_autofs_dev_ioctl(param);
333 param->openmount.devid = devid;
334 strcpy(param->path, where);
336 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0)
339 if (param->ioctlfd < 0)
342 fd_cloexec(param->ioctlfd, true);
343 return param->ioctlfd;
346 static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
347 uint32_t major, minor;
348 struct autofs_dev_ioctl param;
350 assert(dev_autofs_fd >= 0);
351 assert(ioctl_fd >= 0);
353 init_autofs_dev_ioctl(¶m);
354 param.ioctlfd = ioctl_fd;
356 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, ¶m) < 0)
359 major = param.protover.version;
361 init_autofs_dev_ioctl(¶m);
362 param.ioctlfd = ioctl_fd;
364 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, ¶m) < 0)
367 minor = param.protosubver.sub_version;
369 log_debug("Autofs protocol version %i.%i", major, minor);
373 static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) {
374 struct autofs_dev_ioctl param;
376 assert(dev_autofs_fd >= 0);
377 assert(ioctl_fd >= 0);
379 init_autofs_dev_ioctl(¶m);
380 param.ioctlfd = ioctl_fd;
381 param.timeout.timeout = sec;
383 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) < 0)
389 static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
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;
399 param.fail.token = token;
400 param.fail.status = status;
402 param.ready.token = token;
404 if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, ¶m) < 0)
410 int automount_send_ready(Automount *a, int status) {
411 _cleanup_close_ int ioctl_fd = -1;
418 if (set_isempty(a->tokens))
421 ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
426 log_debug_unit(UNIT(a)->id, "Sending failure: %s", strerror(-status));
428 log_debug_unit(UNIT(a)->id, "Sending success.");
432 /* Autofs thankfully does not hand out 0 as a token */
433 while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) {
436 /* Autofs fun fact II:
438 * if you pass a positive status code here, the kernel will
441 k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
452 static void automount_enter_waiting(Automount *a) {
453 _cleanup_close_ int ioctl_fd = -1;
454 int p[2] = { -1, -1 };
455 char name[32], options[128];
456 bool mounted = false;
457 int r, dev_autofs_fd;
461 assert(a->pipe_fd < 0);
465 set_clear(a->tokens);
467 dev_autofs_fd = open_dev_autofs(UNIT(a)->manager);
468 if (dev_autofs_fd < 0) {
473 /* We knowingly ignore the results of this call */
474 mkdir_p_label(a->where, 0555);
476 warn_if_dir_nonempty(a->meta.id, a->where);
478 if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
483 snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp());
484 char_array_0(options);
486 snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid());
489 if (mount(name, a->where, "autofs", 0, options) < 0) {
496 p[1] = safe_close(p[1]);
498 if (stat(a->where, &st) < 0) {
503 ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev);
509 r = autofs_protocol(dev_autofs_fd, ioctl_fd);
513 r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300);
519 * Unless we close the ioctl fd here, for some weird reason
520 * the direct mount will not receive events from the
523 r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
528 a->dev_id = st.st_dev;
530 automount_set_state(a, AUTOMOUNT_WAITING);
538 repeat_unmount(a->where);
540 log_error_unit(UNIT(a)->id,
541 "Failed to initialize automounter: %s", strerror(-r));
542 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
545 static void automount_enter_runnning(Automount *a) {
546 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
552 /* We don't take mount requests anymore if we are supposed to
553 * shut down anyway */
554 if (unit_stop_pending(UNIT(a))) {
555 log_debug_unit(UNIT(a)->id,
556 "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
557 automount_send_ready(a, -EHOSTDOWN);
561 mkdir_p_label(a->where, a->directory_mode);
563 /* Before we do anything, let's see if somebody is playing games with us? */
564 if (lstat(a->where, &st) < 0) {
565 log_warning_unit(UNIT(a)->id,
566 "%s failed to stat automount point: %m", UNIT(a)->id);
570 if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
571 log_info_unit(UNIT(a)->id,
572 "%s's automount point already active?", UNIT(a)->id);
574 r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)),
575 JOB_REPLACE, true, &error, NULL);
577 log_warning_unit(UNIT(a)->id,
578 "%s failed to queue mount startup job: %s",
579 UNIT(a)->id, bus_error_message(&error, r));
584 automount_set_state(a, AUTOMOUNT_RUNNING);
588 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
591 static int automount_start(Unit *u) {
592 Automount *a = AUTOMOUNT(u);
595 assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
597 if (path_is_mount_point(a->where, false)) {
598 log_error_unit(u->id,
599 "Path %s is already a mount point, refusing start for %s",
604 if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
607 a->result = AUTOMOUNT_SUCCESS;
608 automount_enter_waiting(a);
612 static int automount_stop(Unit *u) {
613 Automount *a = AUTOMOUNT(u);
616 assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
618 automount_enter_dead(a, AUTOMOUNT_SUCCESS);
622 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
623 Automount *a = AUTOMOUNT(u);
631 unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
632 unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
633 unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
635 SET_FOREACH(p, a->tokens, i)
636 unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
638 if (a->pipe_fd >= 0) {
641 copy = fdset_put_dup(fds, a->pipe_fd);
645 unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
651 static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
652 Automount *a = AUTOMOUNT(u);
658 if (streq(key, "state")) {
659 AutomountState state;
661 state = automount_state_from_string(value);
663 log_debug_unit(u->id, "Failed to parse state value %s", value);
665 a->deserialized_state = state;
666 } else if (streq(key, "result")) {
669 f = automount_result_from_string(value);
671 log_debug_unit(u->id, "Failed to parse result value %s", value);
672 else if (f != AUTOMOUNT_SUCCESS)
675 } else if (streq(key, "dev-id")) {
678 if (safe_atou(value, &d) < 0)
679 log_debug_unit(u->id, "Failed to parse dev-id value %s", value);
681 a->dev_id = (unsigned) d;
682 } else if (streq(key, "token")) {
685 if (safe_atou(value, &token) < 0)
686 log_debug_unit(u->id, "Failed to parse token value %s", value);
689 if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func)))
692 r = set_put(a->tokens, UINT_TO_PTR(token));
696 } else if (streq(key, "pipe-fd")) {
699 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
700 log_debug_unit(u->id, "Failed to parse pipe-fd value %s", value);
702 safe_close(a->pipe_fd);
703 a->pipe_fd = fdset_remove(fds, fd);
706 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
711 static UnitActiveState automount_active_state(Unit *u) {
714 return state_translation_table[AUTOMOUNT(u)->state];
717 static const char *automount_sub_state_to_string(Unit *u) {
720 return automount_state_to_string(AUTOMOUNT(u)->state);
723 static bool automount_check_gc(Unit *u) {
726 if (!UNIT_TRIGGER(u))
729 return UNIT_VTABLE(UNIT_TRIGGER(u))->check_gc(UNIT_TRIGGER(u));
732 static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata) {
733 union autofs_v5_packet_union packet;
734 Automount *a = AUTOMOUNT(userdata);
739 assert(fd == a->pipe_fd);
741 if (events != EPOLLIN) {
742 log_error_unit(UNIT(a)->id, "Got invalid poll event on pipe.");
746 l = loop_read(a->pipe_fd, &packet, sizeof(packet), true);
747 if (l != sizeof(packet)) {
748 log_error_unit(UNIT(a)->id, "Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
752 switch (packet.hdr.type) {
754 case autofs_ptype_missing_direct:
756 if (packet.v5_packet.pid > 0) {
757 _cleanup_free_ char *p = NULL;
759 get_process_comm(packet.v5_packet.pid, &p);
760 log_info_unit(UNIT(a)->id,
761 "Got automount request for %s, triggered by "PID_FMT" (%s)",
762 a->where, packet.v5_packet.pid, strna(p));
764 log_debug_unit(UNIT(a)->id, "Got direct mount request on %s", a->where);
766 r = set_ensure_allocated(&a->tokens, trivial_hash_func, trivial_compare_func);
768 log_error_unit(UNIT(a)->id, "Failed to allocate token set.");
772 r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
774 log_error_unit(UNIT(a)->id, "Failed to remember token: %s", strerror(-r));
778 automount_enter_runnning(a);
782 log_error_unit(UNIT(a)->id, "Received unknown automount request %i", packet.hdr.type);
789 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
793 static void automount_shutdown(Manager *m) {
796 m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
799 static void automount_reset_failed(Unit *u) {
800 Automount *a = AUTOMOUNT(u);
804 if (a->state == AUTOMOUNT_FAILED)
805 automount_set_state(a, AUTOMOUNT_DEAD);
807 a->result = AUTOMOUNT_SUCCESS;
810 static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
811 [AUTOMOUNT_DEAD] = "dead",
812 [AUTOMOUNT_WAITING] = "waiting",
813 [AUTOMOUNT_RUNNING] = "running",
814 [AUTOMOUNT_FAILED] = "failed"
817 DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
819 static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
820 [AUTOMOUNT_SUCCESS] = "success",
821 [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
824 DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
826 const UnitVTable automount_vtable = {
827 .object_size = sizeof(Automount),
835 .no_instances = true,
837 .init = automount_init,
838 .load = automount_load,
839 .done = automount_done,
841 .coldplug = automount_coldplug,
843 .dump = automount_dump,
845 .start = automount_start,
846 .stop = automount_stop,
848 .serialize = automount_serialize,
849 .deserialize_item = automount_deserialize_item,
851 .active_state = automount_active_state,
852 .sub_state_to_string = automount_sub_state_to_string,
854 .check_gc = automount_check_gc,
856 .reset_failed = automount_reset_failed,
858 .bus_interface = "org.freedesktop.systemd1.Automount",
859 .bus_vtable = bus_automount_vtable,
861 .shutdown = automount_shutdown,
863 .status_message_formats = {
864 .finished_start_job = {
865 [JOB_DONE] = "Set up automount %s.",
866 [JOB_FAILED] = "Failed to set up automount %s.",
867 [JOB_DEPENDENCY] = "Dependency failed for %s.",
869 .finished_stop_job = {
870 [JOB_DONE] = "Unset automount %s.",
871 [JOB_FAILED] = "Failed to unset automount %s.",