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"
34 #include "load-fragment.h"
35 #include "load-dropin.h"
36 #include "unit-name.h"
37 #include "dbus-automount.h"
38 #include "bus-errors.h"
42 #include "path-util.h"
44 static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
45 [AUTOMOUNT_DEAD] = UNIT_INACTIVE,
46 [AUTOMOUNT_WAITING] = UNIT_ACTIVE,
47 [AUTOMOUNT_RUNNING] = UNIT_ACTIVE,
48 [AUTOMOUNT_FAILED] = UNIT_FAILED
51 static int open_dev_autofs(Manager *m);
53 static void automount_init(Unit *u) {
54 Automount *a = AUTOMOUNT(u);
57 assert(u->load_state == UNIT_STUB);
59 a->pipe_watch.fd = a->pipe_fd = -1;
60 a->pipe_watch.type = WATCH_INVALID;
62 a->directory_mode = 0755;
64 UNIT(a)->ignore_on_isolate = true;
67 static void repeat_unmout(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 unit_unwatch_fd(UNIT(a), &a->pipe_watch);
93 close_nointr_nofail(a->pipe_fd);
96 /* If we reload/reexecute things we keep the mount point
99 (UNIT(a)->manager->exit_code != MANAGER_RELOAD &&
100 UNIT(a)->manager->exit_code != MANAGER_REEXECUTE))
101 repeat_unmout(a->where);
104 static void automount_done(Unit *u) {
105 Automount *a = AUTOMOUNT(u);
110 unit_ref_unset(&a->mount);
119 int automount_add_one_mount_link(Automount *a, Mount *m) {
125 if (UNIT(a)->load_state != UNIT_LOADED ||
126 UNIT(m)->load_state != UNIT_LOADED)
129 if (!path_startswith(a->where, m->where))
132 if (path_equal(a->where, m->where))
135 if ((r = unit_add_two_dependencies(UNIT(a), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0)
141 static int automount_add_mount_links(Automount *a) {
147 LIST_FOREACH(units_by_type, other, UNIT(a)->manager->units_by_type[UNIT_MOUNT])
148 if ((r = automount_add_one_mount_link(a, MOUNT(other))) < 0)
154 static int automount_add_default_dependencies(Automount *a) {
159 if (UNIT(a)->manager->running_as == MANAGER_SYSTEM) {
161 if ((r = unit_add_dependency_by_name(UNIT(a), UNIT_BEFORE, SPECIAL_BASIC_TARGET, NULL, true)) < 0)
164 if ((r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0)
171 static int automount_verify(Automount *a) {
176 if (UNIT(a)->load_state != UNIT_LOADED)
179 if (path_equal(a->where, "/")) {
180 log_error("Cannot have an automount unit for the root directory. Refusing.");
184 if (!(e = unit_name_from_path(a->where, ".automount")))
187 b = unit_has_name(UNIT(a), e);
191 log_error("%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
198 static int automount_load(Unit *u) {
200 Automount *a = AUTOMOUNT(u);
203 assert(u->load_state == UNIT_STUB);
205 /* Load a .automount file */
206 if ((r = unit_load_fragment_and_dropin_optional(u)) < 0)
209 if (u->load_state == UNIT_LOADED) {
213 if (!(a->where = unit_name_to_path(u->id)))
216 path_kill_slashes(a->where);
218 if ((r = automount_add_mount_links(a)) < 0)
221 r = unit_load_related_unit(u, ".mount", &x);
225 unit_ref_set(&a->mount, x);
227 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(a->mount), true);
231 if (UNIT(a)->default_dependencies)
232 if ((r = automount_add_default_dependencies(a)) < 0)
236 return automount_verify(a);
239 static void automount_set_state(Automount *a, AutomountState state) {
240 AutomountState old_state;
243 old_state = a->state;
246 if (state != AUTOMOUNT_WAITING &&
247 state != AUTOMOUNT_RUNNING)
250 if (state != old_state)
251 log_debug("%s changed %s -> %s",
253 automount_state_to_string(old_state),
254 automount_state_to_string(state));
256 unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
259 static int automount_coldplug(Unit *u) {
260 Automount *a = AUTOMOUNT(u);
264 assert(a->state == AUTOMOUNT_DEAD);
266 if (a->deserialized_state != a->state) {
268 if ((r = open_dev_autofs(u->manager)) < 0)
271 if (a->deserialized_state == AUTOMOUNT_WAITING ||
272 a->deserialized_state == AUTOMOUNT_RUNNING) {
274 assert(a->pipe_fd >= 0);
276 if ((r = unit_watch_fd(UNIT(a), a->pipe_fd, EPOLLIN, &a->pipe_watch)) < 0)
280 automount_set_state(a, a->deserialized_state);
286 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
287 Automount *a = AUTOMOUNT(u);
292 "%sAutomount State: %s\n"
295 "%sDirectoryMode: %04o\n",
296 prefix, automount_state_to_string(a->state),
297 prefix, automount_result_to_string(a->result),
299 prefix, a->directory_mode);
302 static void automount_enter_dead(Automount *a, AutomountResult f) {
305 if (f != AUTOMOUNT_SUCCESS)
308 automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
311 static int open_dev_autofs(Manager *m) {
312 struct autofs_dev_ioctl param;
316 if (m->dev_autofs_fd >= 0)
317 return m->dev_autofs_fd;
319 label_fix("/dev/autofs", false);
321 if ((m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY)) < 0) {
322 log_error("Failed to open /dev/autofs: %s", strerror(errno));
326 init_autofs_dev_ioctl(¶m);
327 if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, ¶m) < 0) {
328 close_nointr_nofail(m->dev_autofs_fd);
329 m->dev_autofs_fd = -1;
333 log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
335 return m->dev_autofs_fd;
338 static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
339 struct autofs_dev_ioctl *param;
343 assert(dev_autofs_fd >= 0);
346 l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
348 if (!(param = malloc(l)))
351 init_autofs_dev_ioctl(param);
354 param->openmount.devid = devid;
355 strcpy(param->path, where);
357 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0) {
362 if (param->ioctlfd < 0) {
367 fd_cloexec(param->ioctlfd, true);
375 static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
376 uint32_t major, minor;
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;
385 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, ¶m) < 0)
388 major = param.protover.version;
390 init_autofs_dev_ioctl(¶m);
391 param.ioctlfd = ioctl_fd;
393 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, ¶m) < 0)
396 minor = param.protosubver.sub_version;
398 log_debug("Autofs protocol version %i.%i", major, minor);
402 static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) {
403 struct autofs_dev_ioctl param;
405 assert(dev_autofs_fd >= 0);
406 assert(ioctl_fd >= 0);
408 init_autofs_dev_ioctl(¶m);
409 param.ioctlfd = ioctl_fd;
410 param.timeout.timeout = sec;
412 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) < 0)
418 static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
419 struct autofs_dev_ioctl param;
421 assert(dev_autofs_fd >= 0);
422 assert(ioctl_fd >= 0);
424 init_autofs_dev_ioctl(¶m);
425 param.ioctlfd = ioctl_fd;
428 param.fail.token = token;
429 param.fail.status = status;
431 param.ready.token = token;
433 if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, ¶m) < 0)
439 int automount_send_ready(Automount *a, int status) {
446 if (set_isempty(a->tokens))
449 if ((ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id)) < 0) {
455 log_debug("Sending failure: %s", strerror(-status));
457 log_debug("Sending success.");
461 /* Autofs thankfully does not hand out 0 as a token */
462 while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) {
465 /* Autofs fun fact II:
467 * if you pass a positive status code here, the kernel will
470 if ((k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
479 close_nointr_nofail(ioctl_fd);
484 static void automount_enter_waiting(Automount *a) {
485 int p[2] = { -1, -1 };
486 char name[32], options[128];
487 bool mounted = false;
488 int r, ioctl_fd = -1, dev_autofs_fd;
492 assert(a->pipe_fd < 0);
496 set_clear(a->tokens);
498 if ((dev_autofs_fd = open_dev_autofs(UNIT(a)->manager)) < 0) {
503 /* We knowingly ignore the results of this call */
504 mkdir_p(a->where, 0555);
506 if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
511 snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp());
512 char_array_0(options);
514 snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid());
517 if (mount(name, a->where, "autofs", 0, options) < 0) {
524 close_nointr_nofail(p[1]);
527 if (stat(a->where, &st) < 0) {
532 if ((ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev)) < 0) {
537 if ((r = autofs_protocol(dev_autofs_fd, ioctl_fd)) < 0)
540 if ((r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300)) < 0)
545 * Unless we close the ioctl fd here, for some weird reason
546 * the direct mount will not receive events from the
549 close_nointr_nofail(ioctl_fd);
552 if ((r = unit_watch_fd(UNIT(a), p[0], EPOLLIN, &a->pipe_watch)) < 0)
556 a->dev_id = st.st_dev;
558 automount_set_state(a, AUTOMOUNT_WAITING);
563 assert_se(close_pipe(p) == 0);
566 close_nointr_nofail(ioctl_fd);
569 repeat_unmout(a->where);
571 log_error("Failed to initialize automounter: %s", strerror(-r));
572 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
575 static void automount_enter_runnning(Automount *a) {
581 assert(UNIT_DEREF(a->mount));
583 dbus_error_init(&error);
585 /* We don't take mount requests anymore if we are supposed to
586 * shut down anyway */
587 if (unit_pending_inactive(UNIT(a))) {
588 log_debug("Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
589 automount_send_ready(a, -EHOSTDOWN);
593 mkdir_p(a->where, a->directory_mode);
595 /* Before we do anything, let's see if somebody is playing games with us? */
596 if (lstat(a->where, &st) < 0) {
597 log_warning("%s failed to stat automount point: %m", UNIT(a)->id);
601 if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
602 log_info("%s's automount point already active?", UNIT(a)->id);
603 else if ((r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_DEREF(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) {
604 log_warning("%s failed to queue mount startup job: %s", UNIT(a)->id, bus_error(&error, r));
608 automount_set_state(a, AUTOMOUNT_RUNNING);
612 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
613 dbus_error_free(&error);
616 static int automount_start(Unit *u) {
617 Automount *a = AUTOMOUNT(u);
621 assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
623 if (path_is_mount_point(a->where, false)) {
624 log_error("Path %s is already a mount point, refusing start for %s", a->where, u->id);
628 if (UNIT_DEREF(a->mount)->load_state != UNIT_LOADED)
631 a->result = AUTOMOUNT_SUCCESS;
632 automount_enter_waiting(a);
636 static int automount_stop(Unit *u) {
637 Automount *a = AUTOMOUNT(u);
641 assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
643 automount_enter_dead(a, AUTOMOUNT_SUCCESS);
647 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
648 Automount *a = AUTOMOUNT(u);
656 unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
657 unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
658 unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
660 SET_FOREACH(p, a->tokens, i)
661 unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
663 if (a->pipe_fd >= 0) {
666 if ((copy = fdset_put_dup(fds, a->pipe_fd)) < 0)
669 unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
675 static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
676 Automount *a = AUTOMOUNT(u);
682 if (streq(key, "state")) {
683 AutomountState state;
685 if ((state = automount_state_from_string(value)) < 0)
686 log_debug("Failed to parse state value %s", value);
688 a->deserialized_state = state;
689 } else if (streq(key, "result")) {
692 f = automount_result_from_string(value);
694 log_debug("Failed to parse result value %s", value);
695 else if (f != AUTOMOUNT_SUCCESS)
698 } else if (streq(key, "dev-id")) {
701 if (safe_atou(value, &d) < 0)
702 log_debug("Failed to parse dev-id value %s", value);
704 a->dev_id = (unsigned) d;
705 } else if (streq(key, "token")) {
708 if (safe_atou(value, &token) < 0)
709 log_debug("Failed to parse token value %s", value);
712 if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func)))
715 if ((r = set_put(a->tokens, UINT_TO_PTR(token))) < 0)
718 } else if (streq(key, "pipe-fd")) {
721 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
722 log_debug("Failed to parse pipe-fd value %s", value);
725 close_nointr_nofail(a->pipe_fd);
727 a->pipe_fd = fdset_remove(fds, fd);
730 log_debug("Unknown serialization key '%s'", key);
735 static UnitActiveState automount_active_state(Unit *u) {
738 return state_translation_table[AUTOMOUNT(u)->state];
741 static const char *automount_sub_state_to_string(Unit *u) {
744 return automount_state_to_string(AUTOMOUNT(u)->state);
747 static bool automount_check_gc(Unit *u) {
748 Automount *a = AUTOMOUNT(u);
752 if (!UNIT_DEREF(a->mount))
755 return UNIT_VTABLE(UNIT_DEREF(a->mount))->check_gc(UNIT_DEREF(a->mount));
758 static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
759 Automount *a = AUTOMOUNT(u);
760 union autofs_v5_packet_union packet;
765 assert(fd == a->pipe_fd);
767 if (events != EPOLLIN) {
768 log_error("Got invalid poll event on pipe.");
772 if ((l = loop_read(a->pipe_fd, &packet, sizeof(packet), true)) != sizeof(packet)) {
773 log_error("Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
777 switch (packet.hdr.type) {
779 case autofs_ptype_missing_direct:
781 if (packet.v5_packet.pid > 0) {
784 get_process_comm(packet.v5_packet.pid, &p);
785 log_debug("Got direct mount request for %s, triggered by %lu (%s)", packet.v5_packet.name, (unsigned long) packet.v5_packet.pid, strna(p));
789 log_debug("Got direct mount request for %s", packet.v5_packet.name);
792 if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func))) {
793 log_error("Failed to allocate token set.");
797 if ((r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token))) < 0) {
798 log_error("Failed to remember token: %s", strerror(-r));
802 automount_enter_runnning(a);
806 log_error("Received unknown automount request %i", packet.hdr.type);
813 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
816 static void automount_shutdown(Manager *m) {
819 if (m->dev_autofs_fd >= 0)
820 close_nointr_nofail(m->dev_autofs_fd);
823 static void automount_reset_failed(Unit *u) {
824 Automount *a = AUTOMOUNT(u);
828 if (a->state == AUTOMOUNT_FAILED)
829 automount_set_state(a, AUTOMOUNT_DEAD);
831 a->result = AUTOMOUNT_SUCCESS;
834 static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
835 [AUTOMOUNT_DEAD] = "dead",
836 [AUTOMOUNT_WAITING] = "waiting",
837 [AUTOMOUNT_RUNNING] = "running",
838 [AUTOMOUNT_FAILED] = "failed"
841 DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
843 static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
844 [AUTOMOUNT_SUCCESS] = "success",
845 [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
848 DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
850 const UnitVTable automount_vtable = {
851 .suffix = ".automount",
852 .object_size = sizeof(Automount),
859 .no_instances = true,
861 .init = automount_init,
862 .load = automount_load,
863 .done = automount_done,
865 .coldplug = automount_coldplug,
867 .dump = automount_dump,
869 .start = automount_start,
870 .stop = automount_stop,
872 .serialize = automount_serialize,
873 .deserialize_item = automount_deserialize_item,
875 .active_state = automount_active_state,
876 .sub_state_to_string = automount_sub_state_to_string,
878 .check_gc = automount_check_gc,
880 .fd_event = automount_fd_event,
882 .reset_failed = automount_reset_failed,
884 .bus_interface = "org.freedesktop.systemd1.Automount",
885 .bus_message_handler = bus_automount_message_handler,
886 .bus_invalidating_properties = bus_automount_invalidating_properties,
888 .shutdown = automount_shutdown