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_unmount(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_unmount(a->where);
106 static void automount_done(Unit *u) {
107 Automount *a = AUTOMOUNT(u);
120 static int automount_add_mount_links(Automount *a) {
121 _cleanup_free_ char *parent = NULL;
126 r = path_get_parent(a->where, &parent);
130 return unit_require_mounts_for(UNIT(a), parent);
133 static int automount_add_default_dependencies(Automount *a) {
138 if (UNIT(a)->manager->running_as != SYSTEMD_SYSTEM)
141 r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
148 static int automount_verify(Automount *a) {
153 if (UNIT(a)->load_state != UNIT_LOADED)
156 if (path_equal(a->where, "/")) {
157 log_error_unit(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing.");
161 e = unit_name_from_path(a->where, ".automount");
165 b = unit_has_name(UNIT(a), e);
169 log_error_unit(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
176 static int automount_load(Unit *u) {
177 Automount *a = AUTOMOUNT(u);
181 assert(u->load_state == UNIT_STUB);
183 /* Load a .automount file */
184 r = unit_load_fragment_and_dropin_optional(u);
188 if (u->load_state == UNIT_LOADED) {
192 a->where = unit_name_to_path(u->id);
197 path_kill_slashes(a->where);
199 r = unit_load_related_unit(u, ".mount", &x);
203 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
207 r = automount_add_mount_links(a);
211 if (UNIT(a)->default_dependencies) {
212 r = automount_add_default_dependencies(a);
218 return automount_verify(a);
221 static void automount_set_state(Automount *a, AutomountState state) {
222 AutomountState old_state;
225 old_state = a->state;
228 if (state != AUTOMOUNT_WAITING &&
229 state != AUTOMOUNT_RUNNING)
232 if (state != old_state)
233 log_debug_unit(UNIT(a)->id,
234 "%s changed %s -> %s",
236 automount_state_to_string(old_state),
237 automount_state_to_string(state));
239 unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
242 static int automount_coldplug(Unit *u) {
243 Automount *a = AUTOMOUNT(u);
247 assert(a->state == AUTOMOUNT_DEAD);
249 if (a->deserialized_state != a->state) {
251 r = open_dev_autofs(u->manager);
255 if (a->deserialized_state == AUTOMOUNT_WAITING ||
256 a->deserialized_state == AUTOMOUNT_RUNNING) {
258 assert(a->pipe_fd >= 0);
260 r = unit_watch_fd(UNIT(a), a->pipe_fd, EPOLLIN, &a->pipe_watch);
265 automount_set_state(a, a->deserialized_state);
271 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
272 Automount *a = AUTOMOUNT(u);
277 "%sAutomount State: %s\n"
280 "%sDirectoryMode: %04o\n",
281 prefix, automount_state_to_string(a->state),
282 prefix, automount_result_to_string(a->result),
284 prefix, a->directory_mode);
287 static void automount_enter_dead(Automount *a, AutomountResult f) {
290 if (f != AUTOMOUNT_SUCCESS)
293 automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
296 static int open_dev_autofs(Manager *m) {
297 struct autofs_dev_ioctl param;
301 if (m->dev_autofs_fd >= 0)
302 return m->dev_autofs_fd;
304 label_fix("/dev/autofs", false, false);
306 m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY);
307 if (m->dev_autofs_fd < 0) {
308 log_error("Failed to open /dev/autofs: %s", strerror(errno));
312 init_autofs_dev_ioctl(¶m);
313 if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, ¶m) < 0) {
314 close_nointr_nofail(m->dev_autofs_fd);
315 m->dev_autofs_fd = -1;
319 log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
321 return m->dev_autofs_fd;
324 static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
325 struct autofs_dev_ioctl *param;
328 assert(dev_autofs_fd >= 0);
331 l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
334 init_autofs_dev_ioctl(param);
337 param->openmount.devid = devid;
338 strcpy(param->path, where);
340 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0)
343 if (param->ioctlfd < 0)
346 fd_cloexec(param->ioctlfd, true);
347 return param->ioctlfd;
350 static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
351 uint32_t major, minor;
352 struct autofs_dev_ioctl param;
354 assert(dev_autofs_fd >= 0);
355 assert(ioctl_fd >= 0);
357 init_autofs_dev_ioctl(¶m);
358 param.ioctlfd = ioctl_fd;
360 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, ¶m) < 0)
363 major = param.protover.version;
365 init_autofs_dev_ioctl(¶m);
366 param.ioctlfd = ioctl_fd;
368 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, ¶m) < 0)
371 minor = param.protosubver.sub_version;
373 log_debug("Autofs protocol version %i.%i", major, minor);
377 static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) {
378 struct autofs_dev_ioctl param;
380 assert(dev_autofs_fd >= 0);
381 assert(ioctl_fd >= 0);
383 init_autofs_dev_ioctl(¶m);
384 param.ioctlfd = ioctl_fd;
385 param.timeout.timeout = sec;
387 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) < 0)
393 static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
394 struct autofs_dev_ioctl param;
396 assert(dev_autofs_fd >= 0);
397 assert(ioctl_fd >= 0);
399 init_autofs_dev_ioctl(¶m);
400 param.ioctlfd = ioctl_fd;
403 param.fail.token = token;
404 param.fail.status = status;
406 param.ready.token = token;
408 if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, ¶m) < 0)
414 int automount_send_ready(Automount *a, int status) {
421 if (set_isempty(a->tokens))
424 ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
431 log_debug_unit(UNIT(a)->id, "Sending failure: %s", strerror(-status));
433 log_debug_unit(UNIT(a)->id, "Sending success.");
437 /* Autofs thankfully does not hand out 0 as a token */
438 while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) {
441 /* Autofs fun fact II:
443 * if you pass a positive status code here, the kernel will
446 k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
456 close_nointr_nofail(ioctl_fd);
461 static void automount_enter_waiting(Automount *a) {
462 int p[2] = { -1, -1 };
463 char name[32], options[128];
464 bool mounted = false;
465 int r, ioctl_fd = -1, dev_autofs_fd;
469 assert(a->pipe_fd < 0);
473 set_clear(a->tokens);
475 dev_autofs_fd = open_dev_autofs(UNIT(a)->manager);
476 if (dev_autofs_fd < 0) {
481 /* We knowingly ignore the results of this call */
482 mkdir_p_label(a->where, 0555);
484 warn_if_dir_nonempty(a->meta.id, a->where);
486 if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
491 snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp());
492 char_array_0(options);
494 snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid());
497 if (mount(name, a->where, "autofs", 0, options) < 0) {
504 close_nointr_nofail(p[1]);
507 if (stat(a->where, &st) < 0) {
512 ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev);
518 r = autofs_protocol(dev_autofs_fd, ioctl_fd);
522 r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300);
528 * Unless we close the ioctl fd here, for some weird reason
529 * the direct mount will not receive events from the
532 close_nointr_nofail(ioctl_fd);
535 r = unit_watch_fd(UNIT(a), p[0], EPOLLIN, &a->pipe_watch);
540 a->dev_id = st.st_dev;
542 automount_set_state(a, AUTOMOUNT_WAITING);
547 assert_se(close_pipe(p) == 0);
550 close_nointr_nofail(ioctl_fd);
553 repeat_unmount(a->where);
555 log_error_unit(UNIT(a)->id,
556 "Failed to initialize automounter: %s", strerror(-r));
557 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
560 static void automount_enter_runnning(Automount *a) {
561 _cleanup_dbus_error_free_ DBusError error;
567 dbus_error_init(&error);
569 /* We don't take mount requests anymore if we are supposed to
570 * shut down anyway */
571 if (unit_stop_pending(UNIT(a))) {
572 log_debug_unit(UNIT(a)->id,
573 "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
574 automount_send_ready(a, -EHOSTDOWN);
578 mkdir_p_label(a->where, a->directory_mode);
580 /* Before we do anything, let's see if somebody is playing games with us? */
581 if (lstat(a->where, &st) < 0) {
582 log_warning_unit(UNIT(a)->id,
583 "%s failed to stat automount point: %m", UNIT(a)->id);
587 if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
588 log_info_unit(UNIT(a)->id,
589 "%s's automount point already active?", UNIT(a)->id);
591 r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)),
592 JOB_REPLACE, true, &error, NULL);
594 log_warning_unit(UNIT(a)->id,
595 "%s failed to queue mount startup job: %s",
596 UNIT(a)->id, bus_error(&error, r));
601 automount_set_state(a, AUTOMOUNT_RUNNING);
605 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
608 static int automount_start(Unit *u) {
609 Automount *a = AUTOMOUNT(u);
612 assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
614 if (path_is_mount_point(a->where, false)) {
615 log_error_unit(u->id,
616 "Path %s is already a mount point, refusing start for %s",
621 if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
624 a->result = AUTOMOUNT_SUCCESS;
625 automount_enter_waiting(a);
629 static int automount_stop(Unit *u) {
630 Automount *a = AUTOMOUNT(u);
633 assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
635 automount_enter_dead(a, AUTOMOUNT_SUCCESS);
639 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
640 Automount *a = AUTOMOUNT(u);
648 unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
649 unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
650 unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
652 SET_FOREACH(p, a->tokens, i)
653 unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
655 if (a->pipe_fd >= 0) {
658 copy = fdset_put_dup(fds, a->pipe_fd);
662 unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
668 static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
669 Automount *a = AUTOMOUNT(u);
675 if (streq(key, "state")) {
676 AutomountState state;
678 state = automount_state_from_string(value);
680 log_debug_unit(u->id, "Failed to parse state value %s", value);
682 a->deserialized_state = state;
683 } else if (streq(key, "result")) {
686 f = automount_result_from_string(value);
688 log_debug_unit(u->id, "Failed to parse result value %s", value);
689 else if (f != AUTOMOUNT_SUCCESS)
692 } else if (streq(key, "dev-id")) {
695 if (safe_atou(value, &d) < 0)
696 log_debug_unit(u->id, "Failed to parse dev-id value %s", value);
698 a->dev_id = (unsigned) d;
699 } else if (streq(key, "token")) {
702 if (safe_atou(value, &token) < 0)
703 log_debug_unit(u->id, "Failed to parse token value %s", value);
706 if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func)))
709 r = set_put(a->tokens, UINT_TO_PTR(token));
713 } else if (streq(key, "pipe-fd")) {
716 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
717 log_debug_unit(u->id, "Failed to parse pipe-fd value %s", value);
720 close_nointr_nofail(a->pipe_fd);
722 a->pipe_fd = fdset_remove(fds, fd);
725 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
730 static UnitActiveState automount_active_state(Unit *u) {
733 return state_translation_table[AUTOMOUNT(u)->state];
736 static const char *automount_sub_state_to_string(Unit *u) {
739 return automount_state_to_string(AUTOMOUNT(u)->state);
742 static bool automount_check_gc(Unit *u) {
745 if (!UNIT_TRIGGER(u))
748 return UNIT_VTABLE(UNIT_TRIGGER(u))->check_gc(UNIT_TRIGGER(u));
751 static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
752 Automount *a = AUTOMOUNT(u);
753 union autofs_v5_packet_union packet;
758 assert(fd == a->pipe_fd);
760 if (events != EPOLLIN) {
761 log_error_unit(u->id, "Got invalid poll event on pipe.");
765 l = loop_read(a->pipe_fd, &packet, sizeof(packet), true);
766 if (l != sizeof(packet)) {
767 log_error_unit(u->id, "Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
771 switch (packet.hdr.type) {
773 case autofs_ptype_missing_direct:
775 if (packet.v5_packet.pid > 0) {
776 _cleanup_free_ char *p = NULL;
778 get_process_comm(packet.v5_packet.pid, &p);
779 log_debug_unit(u->id,
780 "Got direct mount request on %s, triggered by %lu (%s)",
781 a->where, (unsigned long) packet.v5_packet.pid, strna(p));
783 log_debug_unit(u->id, "Got direct mount request on %s", a->where);
785 r = set_ensure_allocated(&a->tokens, trivial_hash_func, trivial_compare_func);
787 log_error_unit(u->id, "Failed to allocate token set.");
791 r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
793 log_error_unit(u->id, "Failed to remember token: %s", strerror(-r));
797 automount_enter_runnning(a);
801 log_error_unit(u->id, "Received unknown automount request %i", packet.hdr.type);
808 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
811 static void automount_shutdown(Manager *m) {
814 if (m->dev_autofs_fd >= 0)
815 close_nointr_nofail(m->dev_autofs_fd);
818 static void automount_reset_failed(Unit *u) {
819 Automount *a = AUTOMOUNT(u);
823 if (a->state == AUTOMOUNT_FAILED)
824 automount_set_state(a, AUTOMOUNT_DEAD);
826 a->result = AUTOMOUNT_SUCCESS;
829 static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
830 [AUTOMOUNT_DEAD] = "dead",
831 [AUTOMOUNT_WAITING] = "waiting",
832 [AUTOMOUNT_RUNNING] = "running",
833 [AUTOMOUNT_FAILED] = "failed"
836 DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
838 static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
839 [AUTOMOUNT_SUCCESS] = "success",
840 [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
843 DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
845 const UnitVTable automount_vtable = {
846 .object_size = sizeof(Automount),
853 .no_instances = true,
855 .init = automount_init,
856 .load = automount_load,
857 .done = automount_done,
859 .coldplug = automount_coldplug,
861 .dump = automount_dump,
863 .start = automount_start,
864 .stop = automount_stop,
866 .serialize = automount_serialize,
867 .deserialize_item = automount_deserialize_item,
869 .active_state = automount_active_state,
870 .sub_state_to_string = automount_sub_state_to_string,
872 .check_gc = automount_check_gc,
874 .fd_event = automount_fd_event,
876 .reset_failed = automount_reset_failed,
878 .bus_interface = "org.freedesktop.systemd1.Automount",
879 .bus_message_handler = bus_automount_message_handler,
880 .bus_invalidating_properties = bus_automount_invalidating_properties,
882 .shutdown = automount_shutdown,
884 .status_message_formats = {
885 .finished_start_job = {
886 [JOB_DONE] = "Set up automount %s.",
887 [JOB_FAILED] = "Failed to set up automount %s.",
888 [JOB_DEPENDENCY] = "Dependency failed for %s.",
890 .finished_stop_job = {
891 [JOB_DONE] = "Unset automount %s.",
892 [JOB_FAILED] = "Failed to unset automount %s.",