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"
43 static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
44 [AUTOMOUNT_DEAD] = UNIT_INACTIVE,
45 [AUTOMOUNT_WAITING] = UNIT_ACTIVE,
46 [AUTOMOUNT_RUNNING] = UNIT_ACTIVE,
47 [AUTOMOUNT_FAILED] = UNIT_FAILED
50 static int open_dev_autofs(Manager *m);
52 static void automount_init(Unit *u) {
53 Automount *a = AUTOMOUNT(u);
56 assert(u->load_state == UNIT_STUB);
58 a->pipe_watch.fd = a->pipe_fd = -1;
59 a->pipe_watch.type = WATCH_INVALID;
61 a->directory_mode = 0755;
63 UNIT(a)->ignore_on_isolate = true;
66 static void repeat_unmout(const char *path) {
70 /* If there are multiple mounts on a mount point, this
73 if (umount2(path, MNT_DETACH) >= 0)
77 log_error("Failed to unmount: %m");
83 static void unmount_autofs(Automount *a) {
89 automount_send_ready(a, -EHOSTDOWN);
91 unit_unwatch_fd(UNIT(a), &a->pipe_watch);
92 close_nointr_nofail(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_unmout(a->where);
103 static void automount_done(Unit *u) {
104 Automount *a = AUTOMOUNT(u);
109 unit_ref_unset(&a->mount);
118 int automount_add_one_mount_link(Automount *a, Mount *m) {
124 if (UNIT(a)->load_state != UNIT_LOADED ||
125 UNIT(m)->load_state != UNIT_LOADED)
128 if (!path_startswith(a->where, m->where))
131 if (path_equal(a->where, m->where))
134 if ((r = unit_add_two_dependencies(UNIT(a), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true)) < 0)
140 static int automount_add_mount_links(Automount *a) {
146 LIST_FOREACH(units_by_type, other, UNIT(a)->manager->units_by_type[UNIT_MOUNT])
147 if ((r = automount_add_one_mount_link(a, MOUNT(other))) < 0)
153 static int automount_add_default_dependencies(Automount *a) {
158 if (UNIT(a)->manager->running_as == MANAGER_SYSTEM) {
160 if ((r = unit_add_dependency_by_name(UNIT(a), UNIT_BEFORE, SPECIAL_BASIC_TARGET, NULL, true)) < 0)
163 if ((r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true)) < 0)
170 static int automount_verify(Automount *a) {
175 if (UNIT(a)->load_state != UNIT_LOADED)
178 if (path_equal(a->where, "/")) {
179 log_error("Cannot have an automount unit for the root directory. Refusing.");
183 if (!(e = unit_name_from_path(a->where, ".automount")))
186 b = unit_has_name(UNIT(a), e);
190 log_error("%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
197 static int automount_load(Unit *u) {
199 Automount *a = AUTOMOUNT(u);
202 assert(u->load_state == UNIT_STUB);
204 /* Load a .automount file */
205 if ((r = unit_load_fragment_and_dropin_optional(u)) < 0)
208 if (u->load_state == UNIT_LOADED) {
212 if (!(a->where = unit_name_to_path(u->id)))
215 path_kill_slashes(a->where);
217 if ((r = automount_add_mount_links(a)) < 0)
220 r = unit_load_related_unit(u, ".mount", &x);
224 unit_ref_set(&a->mount, x);
226 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(a->mount), true);
230 if (UNIT(a)->default_dependencies)
231 if ((r = automount_add_default_dependencies(a)) < 0)
235 return automount_verify(a);
238 static void automount_set_state(Automount *a, AutomountState state) {
239 AutomountState old_state;
242 old_state = a->state;
245 if (state != AUTOMOUNT_WAITING &&
246 state != AUTOMOUNT_RUNNING)
249 if (state != old_state)
250 log_debug("%s changed %s -> %s",
252 automount_state_to_string(old_state),
253 automount_state_to_string(state));
255 unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
258 static int automount_coldplug(Unit *u) {
259 Automount *a = AUTOMOUNT(u);
263 assert(a->state == AUTOMOUNT_DEAD);
265 if (a->deserialized_state != a->state) {
267 if ((r = open_dev_autofs(u->manager)) < 0)
270 if (a->deserialized_state == AUTOMOUNT_WAITING ||
271 a->deserialized_state == AUTOMOUNT_RUNNING) {
273 assert(a->pipe_fd >= 0);
275 if ((r = unit_watch_fd(UNIT(a), a->pipe_fd, EPOLLIN, &a->pipe_watch)) < 0)
279 automount_set_state(a, a->deserialized_state);
285 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
286 Automount *a = AUTOMOUNT(u);
291 "%sAutomount State: %s\n"
294 "%sDirectoryMode: %04o\n",
295 prefix, automount_state_to_string(a->state),
296 prefix, automount_result_to_string(a->result),
298 prefix, a->directory_mode);
301 static void automount_enter_dead(Automount *a, AutomountResult f) {
304 if (f != AUTOMOUNT_SUCCESS)
307 automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
310 static int open_dev_autofs(Manager *m) {
311 struct autofs_dev_ioctl param;
315 if (m->dev_autofs_fd >= 0)
316 return m->dev_autofs_fd;
318 label_fix("/dev/autofs", false);
320 if ((m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY)) < 0) {
321 log_error("Failed to open /dev/autofs: %s", strerror(errno));
325 init_autofs_dev_ioctl(¶m);
326 if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, ¶m) < 0) {
327 close_nointr_nofail(m->dev_autofs_fd);
328 m->dev_autofs_fd = -1;
332 log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
334 return m->dev_autofs_fd;
337 static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
338 struct autofs_dev_ioctl *param;
342 assert(dev_autofs_fd >= 0);
345 l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
347 if (!(param = malloc(l)))
350 init_autofs_dev_ioctl(param);
353 param->openmount.devid = devid;
354 strcpy(param->path, where);
356 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0) {
361 if (param->ioctlfd < 0) {
366 fd_cloexec(param->ioctlfd, true);
374 static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
375 uint32_t major, minor;
376 struct autofs_dev_ioctl param;
378 assert(dev_autofs_fd >= 0);
379 assert(ioctl_fd >= 0);
381 init_autofs_dev_ioctl(¶m);
382 param.ioctlfd = ioctl_fd;
384 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, ¶m) < 0)
387 major = param.protover.version;
389 init_autofs_dev_ioctl(¶m);
390 param.ioctlfd = ioctl_fd;
392 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, ¶m) < 0)
395 minor = param.protosubver.sub_version;
397 log_debug("Autofs protocol version %i.%i", major, minor);
401 static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) {
402 struct autofs_dev_ioctl param;
404 assert(dev_autofs_fd >= 0);
405 assert(ioctl_fd >= 0);
407 init_autofs_dev_ioctl(¶m);
408 param.ioctlfd = ioctl_fd;
409 param.timeout.timeout = sec;
411 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) < 0)
417 static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
418 struct autofs_dev_ioctl param;
420 assert(dev_autofs_fd >= 0);
421 assert(ioctl_fd >= 0);
423 init_autofs_dev_ioctl(¶m);
424 param.ioctlfd = ioctl_fd;
427 param.fail.token = token;
428 param.fail.status = status;
430 param.ready.token = token;
432 if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, ¶m) < 0)
438 int automount_send_ready(Automount *a, int status) {
445 if (set_isempty(a->tokens))
448 if ((ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id)) < 0) {
454 log_debug("Sending failure: %s", strerror(-status));
456 log_debug("Sending success.");
460 /* Autofs thankfully does not hand out 0 as a token */
461 while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) {
464 /* Autofs fun fact II:
466 * if you pass a positive status code here, the kernel will
469 if ((k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
478 close_nointr_nofail(ioctl_fd);
483 static void automount_enter_waiting(Automount *a) {
484 int p[2] = { -1, -1 };
485 char name[32], options[128];
486 bool mounted = false;
487 int r, ioctl_fd = -1, dev_autofs_fd;
491 assert(a->pipe_fd < 0);
495 set_clear(a->tokens);
497 if ((dev_autofs_fd = open_dev_autofs(UNIT(a)->manager)) < 0) {
502 /* We knowingly ignore the results of this call */
503 mkdir_p(a->where, 0555);
505 if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
510 snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp());
511 char_array_0(options);
513 snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid());
516 if (mount(name, a->where, "autofs", 0, options) < 0) {
523 close_nointr_nofail(p[1]);
526 if (stat(a->where, &st) < 0) {
531 if ((ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev)) < 0) {
536 if ((r = autofs_protocol(dev_autofs_fd, ioctl_fd)) < 0)
539 if ((r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300)) < 0)
544 * Unless we close the ioctl fd here, for some weird reason
545 * the direct mount will not receive events from the
548 close_nointr_nofail(ioctl_fd);
551 if ((r = unit_watch_fd(UNIT(a), p[0], EPOLLIN, &a->pipe_watch)) < 0)
555 a->dev_id = st.st_dev;
557 automount_set_state(a, AUTOMOUNT_WAITING);
562 assert_se(close_pipe(p) == 0);
565 close_nointr_nofail(ioctl_fd);
568 repeat_unmout(a->where);
570 log_error("Failed to initialize automounter: %s", strerror(-r));
571 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
574 static void automount_enter_runnning(Automount *a) {
580 assert(UNIT_DEREF(a->mount));
582 dbus_error_init(&error);
584 /* We don't take mount requests anymore if we are supposed to
585 * shut down anyway */
586 if (unit_pending_inactive(UNIT(a))) {
587 log_debug("Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
588 automount_send_ready(a, -EHOSTDOWN);
592 mkdir_p(a->where, a->directory_mode);
594 /* Before we do anything, let's see if somebody is playing games with us? */
595 if (lstat(a->where, &st) < 0) {
596 log_warning("%s failed to stat automount point: %m", UNIT(a)->id);
600 if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
601 log_info("%s's automount point already active?", UNIT(a)->id);
602 else if ((r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_DEREF(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) {
603 log_warning("%s failed to queue mount startup job: %s", UNIT(a)->id, bus_error(&error, r));
607 automount_set_state(a, AUTOMOUNT_RUNNING);
611 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
612 dbus_error_free(&error);
615 static int automount_start(Unit *u) {
616 Automount *a = AUTOMOUNT(u);
620 assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
622 if (path_is_mount_point(a->where, false)) {
623 log_error("Path %s is already a mount point, refusing start for %s", a->where, u->id);
627 if (UNIT_DEREF(a->mount)->load_state != UNIT_LOADED)
630 a->result = AUTOMOUNT_SUCCESS;
631 automount_enter_waiting(a);
635 static int automount_stop(Unit *u) {
636 Automount *a = AUTOMOUNT(u);
640 assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
642 automount_enter_dead(a, AUTOMOUNT_SUCCESS);
646 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
647 Automount *a = AUTOMOUNT(u);
655 unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
656 unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
657 unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
659 SET_FOREACH(p, a->tokens, i)
660 unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
662 if (a->pipe_fd >= 0) {
665 if ((copy = fdset_put_dup(fds, a->pipe_fd)) < 0)
668 unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
674 static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
675 Automount *a = AUTOMOUNT(u);
681 if (streq(key, "state")) {
682 AutomountState state;
684 if ((state = automount_state_from_string(value)) < 0)
685 log_debug("Failed to parse state value %s", value);
687 a->deserialized_state = state;
688 } else if (streq(key, "result")) {
691 f = automount_result_from_string(value);
693 log_debug("Failed to parse result value %s", value);
694 else if (f != AUTOMOUNT_SUCCESS)
697 } else if (streq(key, "dev-id")) {
700 if (safe_atou(value, &d) < 0)
701 log_debug("Failed to parse dev-id value %s", value);
703 a->dev_id = (unsigned) d;
704 } else if (streq(key, "token")) {
707 if (safe_atou(value, &token) < 0)
708 log_debug("Failed to parse token value %s", value);
711 if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func)))
714 if ((r = set_put(a->tokens, UINT_TO_PTR(token))) < 0)
717 } else if (streq(key, "pipe-fd")) {
720 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
721 log_debug("Failed to parse pipe-fd value %s", value);
724 close_nointr_nofail(a->pipe_fd);
726 a->pipe_fd = fdset_remove(fds, fd);
729 log_debug("Unknown serialization key '%s'", key);
734 static UnitActiveState automount_active_state(Unit *u) {
737 return state_translation_table[AUTOMOUNT(u)->state];
740 static const char *automount_sub_state_to_string(Unit *u) {
743 return automount_state_to_string(AUTOMOUNT(u)->state);
746 static bool automount_check_gc(Unit *u) {
747 Automount *a = AUTOMOUNT(u);
751 if (!UNIT_DEREF(a->mount))
754 return UNIT_VTABLE(UNIT_DEREF(a->mount))->check_gc(UNIT_DEREF(a->mount));
757 static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
758 Automount *a = AUTOMOUNT(u);
759 union autofs_v5_packet_union packet;
764 assert(fd == a->pipe_fd);
766 if (events != EPOLLIN) {
767 log_error("Got invalid poll event on pipe.");
771 if ((l = loop_read(a->pipe_fd, &packet, sizeof(packet), true)) != sizeof(packet)) {
772 log_error("Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
776 switch (packet.hdr.type) {
778 case autofs_ptype_missing_direct:
780 if (packet.v5_packet.pid > 0) {
783 get_process_comm(packet.v5_packet.pid, &p);
784 log_debug("Got direct mount request for %s, triggered by %lu (%s)", packet.v5_packet.name, (unsigned long) packet.v5_packet.pid, strna(p));
788 log_debug("Got direct mount request for %s", packet.v5_packet.name);
791 if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func))) {
792 log_error("Failed to allocate token set.");
796 if ((r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token))) < 0) {
797 log_error("Failed to remember token: %s", strerror(-r));
801 automount_enter_runnning(a);
805 log_error("Received unknown automount request %i", packet.hdr.type);
812 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
815 static void automount_shutdown(Manager *m) {
818 if (m->dev_autofs_fd >= 0)
819 close_nointr_nofail(m->dev_autofs_fd);
822 static void automount_reset_failed(Unit *u) {
823 Automount *a = AUTOMOUNT(u);
827 if (a->state == AUTOMOUNT_FAILED)
828 automount_set_state(a, AUTOMOUNT_DEAD);
830 a->result = AUTOMOUNT_SUCCESS;
833 static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
834 [AUTOMOUNT_DEAD] = "dead",
835 [AUTOMOUNT_WAITING] = "waiting",
836 [AUTOMOUNT_RUNNING] = "running",
837 [AUTOMOUNT_FAILED] = "failed"
840 DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
842 static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
843 [AUTOMOUNT_SUCCESS] = "success",
844 [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
847 DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
849 const UnitVTable automount_vtable = {
850 .suffix = ".automount",
851 .object_size = sizeof(Automount),
858 .no_instances = true,
860 .init = automount_init,
861 .load = automount_load,
862 .done = automount_done,
864 .coldplug = automount_coldplug,
866 .dump = automount_dump,
868 .start = automount_start,
869 .stop = automount_stop,
871 .serialize = automount_serialize,
872 .deserialize_item = automount_deserialize_item,
874 .active_state = automount_active_state,
875 .sub_state_to_string = automount_sub_state_to_string,
877 .check_gc = automount_check_gc,
879 .fd_event = automount_fd_event,
881 .reset_failed = automount_reset_failed,
883 .bus_interface = "org.freedesktop.systemd1.Automount",
884 .bus_message_handler = bus_automount_message_handler,
885 .bus_invalidating_properties = bus_automount_invalidating_properties,
887 .shutdown = automount_shutdown