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"
38 #include "dbus-automount.h"
39 #include "bus-errors.h"
43 #include "path-util.h"
44 #include "dbus-common.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);
55 static void automount_init(Unit *u) {
56 Automount *a = AUTOMOUNT(u);
59 assert(u->load_state == UNIT_STUB);
61 a->pipe_watch.fd = a->pipe_fd = -1;
62 a->pipe_watch.type = WATCH_INVALID;
64 a->directory_mode = 0755;
66 UNIT(a)->ignore_on_isolate = true;
69 static void repeat_unmout(const char *path) {
73 /* If there are multiple mounts on a mount point, this
76 if (umount2(path, MNT_DETACH) >= 0)
80 log_error("Failed to unmount: %m");
86 static void unmount_autofs(Automount *a) {
92 automount_send_ready(a, -EHOSTDOWN);
94 unit_unwatch_fd(UNIT(a), &a->pipe_watch);
95 close_nointr_nofail(a->pipe_fd);
98 /* If we reload/reexecute things we keep the mount point
101 (UNIT(a)->manager->exit_code != MANAGER_RELOAD &&
102 UNIT(a)->manager->exit_code != MANAGER_REEXECUTE))
103 repeat_unmout(a->where);
106 static void automount_done(Unit *u) {
107 Automount *a = AUTOMOUNT(u);
112 unit_ref_unset(&a->mount);
121 int automount_add_one_mount_link(Automount *a, Mount *m) {
127 if (UNIT(a)->load_state != UNIT_LOADED ||
128 UNIT(m)->load_state != UNIT_LOADED)
131 if (!path_startswith(a->where, m->where))
134 if (path_equal(a->where, m->where))
137 r = unit_add_two_dependencies(UNIT(a), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
144 static int automount_add_mount_links(Automount *a) {
150 LIST_FOREACH(units_by_type, other, UNIT(a)->manager->units_by_type[UNIT_MOUNT]) {
151 r = automount_add_one_mount_link(a, MOUNT(other));
159 static int automount_add_default_dependencies(Automount *a) {
164 if (UNIT(a)->manager->running_as != SYSTEMD_SYSTEM)
167 r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
174 static int automount_verify(Automount *a) {
179 if (UNIT(a)->load_state != UNIT_LOADED)
182 if (path_equal(a->where, "/")) {
183 log_error_unit(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing.");
187 e = unit_name_from_path(a->where, ".automount");
191 b = unit_has_name(UNIT(a), e);
195 log_error_unit(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
202 static int automount_load(Unit *u) {
204 Automount *a = AUTOMOUNT(u);
207 assert(u->load_state == UNIT_STUB);
209 /* Load a .automount file */
210 r = unit_load_fragment_and_dropin_optional(u);
214 if (u->load_state == UNIT_LOADED) {
218 a->where = unit_name_to_path(u->id);
223 path_kill_slashes(a->where);
225 r = automount_add_mount_links(a);
229 r = unit_load_related_unit(u, ".mount", &x);
233 unit_ref_set(&a->mount, x);
235 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(a->mount), true);
239 if (UNIT(a)->default_dependencies) {
240 r = automount_add_default_dependencies(a);
246 return automount_verify(a);
249 static void automount_set_state(Automount *a, AutomountState state) {
250 AutomountState old_state;
253 old_state = a->state;
256 if (state != AUTOMOUNT_WAITING &&
257 state != AUTOMOUNT_RUNNING)
260 if (state != old_state)
261 log_debug_unit(UNIT(a)->id,
262 "%s changed %s -> %s",
264 automount_state_to_string(old_state),
265 automount_state_to_string(state));
267 unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
270 static int automount_coldplug(Unit *u) {
271 Automount *a = AUTOMOUNT(u);
275 assert(a->state == AUTOMOUNT_DEAD);
277 if (a->deserialized_state != a->state) {
279 r = open_dev_autofs(u->manager);
283 if (a->deserialized_state == AUTOMOUNT_WAITING ||
284 a->deserialized_state == AUTOMOUNT_RUNNING) {
286 assert(a->pipe_fd >= 0);
288 r = unit_watch_fd(UNIT(a), a->pipe_fd, EPOLLIN, &a->pipe_watch);
293 automount_set_state(a, a->deserialized_state);
299 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
300 Automount *a = AUTOMOUNT(u);
305 "%sAutomount State: %s\n"
308 "%sDirectoryMode: %04o\n",
309 prefix, automount_state_to_string(a->state),
310 prefix, automount_result_to_string(a->result),
312 prefix, a->directory_mode);
315 static void automount_enter_dead(Automount *a, AutomountResult f) {
318 if (f != AUTOMOUNT_SUCCESS)
321 automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
324 static int open_dev_autofs(Manager *m) {
325 struct autofs_dev_ioctl param;
329 if (m->dev_autofs_fd >= 0)
330 return m->dev_autofs_fd;
332 label_fix("/dev/autofs", false, false);
334 m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY);
335 if (m->dev_autofs_fd < 0) {
336 log_error("Failed to open /dev/autofs: %s", strerror(errno));
340 init_autofs_dev_ioctl(¶m);
341 if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, ¶m) < 0) {
342 close_nointr_nofail(m->dev_autofs_fd);
343 m->dev_autofs_fd = -1;
347 log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
349 return m->dev_autofs_fd;
352 static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
353 struct autofs_dev_ioctl *param;
356 assert(dev_autofs_fd >= 0);
359 l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
362 init_autofs_dev_ioctl(param);
365 param->openmount.devid = devid;
366 strcpy(param->path, where);
368 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0)
371 if (param->ioctlfd < 0)
374 fd_cloexec(param->ioctlfd, true);
375 return param->ioctlfd;
378 static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
379 uint32_t major, minor;
380 struct autofs_dev_ioctl param;
382 assert(dev_autofs_fd >= 0);
383 assert(ioctl_fd >= 0);
385 init_autofs_dev_ioctl(¶m);
386 param.ioctlfd = ioctl_fd;
388 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, ¶m) < 0)
391 major = param.protover.version;
393 init_autofs_dev_ioctl(¶m);
394 param.ioctlfd = ioctl_fd;
396 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, ¶m) < 0)
399 minor = param.protosubver.sub_version;
401 log_debug("Autofs protocol version %i.%i", major, minor);
405 static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) {
406 struct autofs_dev_ioctl param;
408 assert(dev_autofs_fd >= 0);
409 assert(ioctl_fd >= 0);
411 init_autofs_dev_ioctl(¶m);
412 param.ioctlfd = ioctl_fd;
413 param.timeout.timeout = sec;
415 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) < 0)
421 static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
422 struct autofs_dev_ioctl param;
424 assert(dev_autofs_fd >= 0);
425 assert(ioctl_fd >= 0);
427 init_autofs_dev_ioctl(¶m);
428 param.ioctlfd = ioctl_fd;
431 param.fail.token = token;
432 param.fail.status = status;
434 param.ready.token = token;
436 if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, ¶m) < 0)
442 int automount_send_ready(Automount *a, int status) {
449 if (set_isempty(a->tokens))
452 ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
459 log_debug_unit(UNIT(a)->id, "Sending failure: %s", strerror(-status));
461 log_debug_unit(UNIT(a)->id, "Sending success.");
465 /* Autofs thankfully does not hand out 0 as a token */
466 while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) {
469 /* Autofs fun fact II:
471 * if you pass a positive status code here, the kernel will
474 k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
484 close_nointr_nofail(ioctl_fd);
489 static void automount_enter_waiting(Automount *a) {
490 int p[2] = { -1, -1 };
491 char name[32], options[128];
492 bool mounted = false;
493 int r, ioctl_fd = -1, dev_autofs_fd;
497 assert(a->pipe_fd < 0);
501 set_clear(a->tokens);
503 dev_autofs_fd = open_dev_autofs(UNIT(a)->manager);
504 if (dev_autofs_fd < 0) {
509 /* We knowingly ignore the results of this call */
510 mkdir_p_label(a->where, 0555);
512 warn_if_dir_nonempty(a->meta.id, a->where);
514 if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
519 snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp());
520 char_array_0(options);
522 snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid());
525 if (mount(name, a->where, "autofs", 0, options) < 0) {
532 close_nointr_nofail(p[1]);
535 if (stat(a->where, &st) < 0) {
540 ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev);
546 r = autofs_protocol(dev_autofs_fd, ioctl_fd);
550 r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300);
556 * Unless we close the ioctl fd here, for some weird reason
557 * the direct mount will not receive events from the
560 close_nointr_nofail(ioctl_fd);
563 r = unit_watch_fd(UNIT(a), p[0], EPOLLIN, &a->pipe_watch);
568 a->dev_id = st.st_dev;
570 automount_set_state(a, AUTOMOUNT_WAITING);
575 assert_se(close_pipe(p) == 0);
578 close_nointr_nofail(ioctl_fd);
581 repeat_unmout(a->where);
583 log_error_unit(UNIT(a)->id,
584 "Failed to initialize automounter: %s", strerror(-r));
585 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
588 static void automount_enter_runnning(Automount *a) {
591 _cleanup_dbus_error_free_ DBusError error;
594 assert(UNIT_DEREF(a->mount));
596 dbus_error_init(&error);
598 /* We don't take mount requests anymore if we are supposed to
599 * shut down anyway */
600 if (unit_pending_inactive(UNIT(a))) {
601 log_debug_unit(UNIT(a)->id,
602 "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
603 automount_send_ready(a, -EHOSTDOWN);
607 mkdir_p_label(a->where, a->directory_mode);
609 /* Before we do anything, let's see if somebody is playing games with us? */
610 if (lstat(a->where, &st) < 0) {
611 log_warning_unit(UNIT(a)->id,
612 "%s failed to stat automount point: %m", UNIT(a)->id);
616 if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
617 log_info_unit(UNIT(a)->id,
618 "%s's automount point already active?", UNIT(a)->id);
619 else if ((r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_DEREF(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) {
620 log_warning_unit(UNIT(a)->id,
621 "%s failed to queue mount startup job: %s",
622 UNIT(a)->id, bus_error(&error, r));
626 automount_set_state(a, AUTOMOUNT_RUNNING);
630 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
633 static int automount_start(Unit *u) {
634 Automount *a = AUTOMOUNT(u);
637 assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
639 if (path_is_mount_point(a->where, false)) {
640 log_error_unit(u->id,
641 "Path %s is already a mount point, refusing start for %s",
646 if (UNIT_DEREF(a->mount)->load_state != UNIT_LOADED)
649 a->result = AUTOMOUNT_SUCCESS;
650 automount_enter_waiting(a);
654 static int automount_stop(Unit *u) {
655 Automount *a = AUTOMOUNT(u);
658 assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
660 automount_enter_dead(a, AUTOMOUNT_SUCCESS);
664 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
665 Automount *a = AUTOMOUNT(u);
673 unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
674 unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
675 unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
677 SET_FOREACH(p, a->tokens, i)
678 unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
680 if (a->pipe_fd >= 0) {
683 copy = fdset_put_dup(fds, a->pipe_fd);
687 unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
693 static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
694 Automount *a = AUTOMOUNT(u);
700 if (streq(key, "state")) {
701 AutomountState state;
703 state = automount_state_from_string(value);
705 log_debug_unit(u->id, "Failed to parse state value %s", value);
707 a->deserialized_state = state;
708 } else if (streq(key, "result")) {
711 f = automount_result_from_string(value);
713 log_debug_unit(u->id, "Failed to parse result value %s", value);
714 else if (f != AUTOMOUNT_SUCCESS)
717 } else if (streq(key, "dev-id")) {
720 if (safe_atou(value, &d) < 0)
721 log_debug_unit(u->id, "Failed to parse dev-id value %s", value);
723 a->dev_id = (unsigned) d;
724 } else if (streq(key, "token")) {
727 if (safe_atou(value, &token) < 0)
728 log_debug_unit(u->id, "Failed to parse token value %s", value);
731 if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func)))
734 r = set_put(a->tokens, UINT_TO_PTR(token));
738 } else if (streq(key, "pipe-fd")) {
741 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
742 log_debug_unit(u->id, "Failed to parse pipe-fd value %s", value);
745 close_nointr_nofail(a->pipe_fd);
747 a->pipe_fd = fdset_remove(fds, fd);
750 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
755 static UnitActiveState automount_active_state(Unit *u) {
758 return state_translation_table[AUTOMOUNT(u)->state];
761 static const char *automount_sub_state_to_string(Unit *u) {
764 return automount_state_to_string(AUTOMOUNT(u)->state);
767 static bool automount_check_gc(Unit *u) {
768 Automount *a = AUTOMOUNT(u);
772 if (!UNIT_DEREF(a->mount))
775 return UNIT_VTABLE(UNIT_DEREF(a->mount))->check_gc(UNIT_DEREF(a->mount));
778 static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
779 Automount *a = AUTOMOUNT(u);
780 union autofs_v5_packet_union packet;
785 assert(fd == a->pipe_fd);
787 if (events != EPOLLIN) {
788 log_error_unit(u->id, "Got invalid poll event on pipe.");
792 l = loop_read(a->pipe_fd, &packet, sizeof(packet), true);
793 if (l != sizeof(packet)) {
794 log_error_unit(u->id, "Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
798 switch (packet.hdr.type) {
800 case autofs_ptype_missing_direct:
802 if (packet.v5_packet.pid > 0) {
803 _cleanup_free_ char *p = NULL;
805 get_process_comm(packet.v5_packet.pid, &p);
806 log_debug_unit(u->id,
807 "Got direct mount request on %s, triggered by %lu (%s)",
808 a->where, (unsigned long) packet.v5_packet.pid, strna(p));
810 log_debug_unit(u->id, "Got direct mount request on %s", a->where);
812 r = set_ensure_allocated(&a->tokens, trivial_hash_func, trivial_compare_func);
814 log_error_unit(u->id, "Failed to allocate token set.");
818 r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
820 log_error_unit(u->id, "Failed to remember token: %s", strerror(-r));
824 automount_enter_runnning(a);
828 log_error_unit(u->id, "Received unknown automount request %i", packet.hdr.type);
835 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
838 static void automount_shutdown(Manager *m) {
841 if (m->dev_autofs_fd >= 0)
842 close_nointr_nofail(m->dev_autofs_fd);
845 static void automount_reset_failed(Unit *u) {
846 Automount *a = AUTOMOUNT(u);
850 if (a->state == AUTOMOUNT_FAILED)
851 automount_set_state(a, AUTOMOUNT_DEAD);
853 a->result = AUTOMOUNT_SUCCESS;
856 static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
857 [AUTOMOUNT_DEAD] = "dead",
858 [AUTOMOUNT_WAITING] = "waiting",
859 [AUTOMOUNT_RUNNING] = "running",
860 [AUTOMOUNT_FAILED] = "failed"
863 DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
865 static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
866 [AUTOMOUNT_SUCCESS] = "success",
867 [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
870 DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
872 const UnitVTable automount_vtable = {
873 .object_size = sizeof(Automount),
880 .no_instances = true,
882 .init = automount_init,
883 .load = automount_load,
884 .done = automount_done,
886 .coldplug = automount_coldplug,
888 .dump = automount_dump,
890 .start = automount_start,
891 .stop = automount_stop,
893 .serialize = automount_serialize,
894 .deserialize_item = automount_deserialize_item,
896 .active_state = automount_active_state,
897 .sub_state_to_string = automount_sub_state_to_string,
899 .check_gc = automount_check_gc,
901 .fd_event = automount_fd_event,
903 .reset_failed = automount_reset_failed,
905 .bus_interface = "org.freedesktop.systemd1.Automount",
906 .bus_message_handler = bus_automount_message_handler,
907 .bus_invalidating_properties = bus_automount_invalidating_properties,
909 .shutdown = automount_shutdown,
911 .status_message_formats = {
912 .finished_start_job = {
913 [JOB_DONE] = "Set up automount %s.",
914 [JOB_FAILED] = "Failed to set up automount %s.",
915 [JOB_DEPENDENCY] = "Dependency failed for %s.",
917 .finished_stop_job = {
918 [JOB_DONE] = "Unset automount %s.",
919 [JOB_FAILED] = "Failed to unset automount %s.",