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 != SYSTEMD_SYSTEM)
162 r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
169 static int automount_verify(Automount *a) {
174 if (UNIT(a)->load_state != UNIT_LOADED)
177 if (path_equal(a->where, "/")) {
178 log_error("Cannot have an automount unit for the root directory. Refusing.");
182 if (!(e = unit_name_from_path(a->where, ".automount")))
185 b = unit_has_name(UNIT(a), e);
189 log_error("%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
196 static int automount_load(Unit *u) {
198 Automount *a = AUTOMOUNT(u);
201 assert(u->load_state == UNIT_STUB);
203 /* Load a .automount file */
204 if ((r = unit_load_fragment_and_dropin_optional(u)) < 0)
207 if (u->load_state == UNIT_LOADED) {
211 if (!(a->where = unit_name_to_path(u->id)))
214 path_kill_slashes(a->where);
216 if ((r = automount_add_mount_links(a)) < 0)
219 r = unit_load_related_unit(u, ".mount", &x);
223 unit_ref_set(&a->mount, x);
225 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(a->mount), true);
229 if (UNIT(a)->default_dependencies)
230 if ((r = automount_add_default_dependencies(a)) < 0)
234 return automount_verify(a);
237 static void automount_set_state(Automount *a, AutomountState state) {
238 AutomountState old_state;
241 old_state = a->state;
244 if (state != AUTOMOUNT_WAITING &&
245 state != AUTOMOUNT_RUNNING)
248 if (state != old_state)
249 log_debug("%s changed %s -> %s",
251 automount_state_to_string(old_state),
252 automount_state_to_string(state));
254 unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
257 static int automount_coldplug(Unit *u) {
258 Automount *a = AUTOMOUNT(u);
262 assert(a->state == AUTOMOUNT_DEAD);
264 if (a->deserialized_state != a->state) {
266 if ((r = open_dev_autofs(u->manager)) < 0)
269 if (a->deserialized_state == AUTOMOUNT_WAITING ||
270 a->deserialized_state == AUTOMOUNT_RUNNING) {
272 assert(a->pipe_fd >= 0);
274 if ((r = unit_watch_fd(UNIT(a), a->pipe_fd, EPOLLIN, &a->pipe_watch)) < 0)
278 automount_set_state(a, a->deserialized_state);
284 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
285 Automount *a = AUTOMOUNT(u);
290 "%sAutomount State: %s\n"
293 "%sDirectoryMode: %04o\n",
294 prefix, automount_state_to_string(a->state),
295 prefix, automount_result_to_string(a->result),
297 prefix, a->directory_mode);
300 static void automount_enter_dead(Automount *a, AutomountResult f) {
303 if (f != AUTOMOUNT_SUCCESS)
306 automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
309 static int open_dev_autofs(Manager *m) {
310 struct autofs_dev_ioctl param;
314 if (m->dev_autofs_fd >= 0)
315 return m->dev_autofs_fd;
317 label_fix("/dev/autofs", false, false);
319 if ((m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY)) < 0) {
320 log_error("Failed to open /dev/autofs: %s", strerror(errno));
324 init_autofs_dev_ioctl(¶m);
325 if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, ¶m) < 0) {
326 close_nointr_nofail(m->dev_autofs_fd);
327 m->dev_autofs_fd = -1;
331 log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
333 return m->dev_autofs_fd;
336 static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
337 struct autofs_dev_ioctl *param;
341 assert(dev_autofs_fd >= 0);
344 l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
346 if (!(param = malloc(l)))
349 init_autofs_dev_ioctl(param);
352 param->openmount.devid = devid;
353 strcpy(param->path, where);
355 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0) {
360 if (param->ioctlfd < 0) {
365 fd_cloexec(param->ioctlfd, true);
373 static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
374 uint32_t major, minor;
375 struct autofs_dev_ioctl param;
377 assert(dev_autofs_fd >= 0);
378 assert(ioctl_fd >= 0);
380 init_autofs_dev_ioctl(¶m);
381 param.ioctlfd = ioctl_fd;
383 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, ¶m) < 0)
386 major = param.protover.version;
388 init_autofs_dev_ioctl(¶m);
389 param.ioctlfd = ioctl_fd;
391 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, ¶m) < 0)
394 minor = param.protosubver.sub_version;
396 log_debug("Autofs protocol version %i.%i", major, minor);
400 static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) {
401 struct autofs_dev_ioctl param;
403 assert(dev_autofs_fd >= 0);
404 assert(ioctl_fd >= 0);
406 init_autofs_dev_ioctl(¶m);
407 param.ioctlfd = ioctl_fd;
408 param.timeout.timeout = sec;
410 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) < 0)
416 static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
417 struct autofs_dev_ioctl param;
419 assert(dev_autofs_fd >= 0);
420 assert(ioctl_fd >= 0);
422 init_autofs_dev_ioctl(¶m);
423 param.ioctlfd = ioctl_fd;
426 param.fail.token = token;
427 param.fail.status = status;
429 param.ready.token = token;
431 if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, ¶m) < 0)
437 int automount_send_ready(Automount *a, int status) {
444 if (set_isempty(a->tokens))
447 if ((ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id)) < 0) {
453 log_debug("Sending failure: %s", strerror(-status));
455 log_debug("Sending success.");
459 /* Autofs thankfully does not hand out 0 as a token */
460 while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) {
463 /* Autofs fun fact II:
465 * if you pass a positive status code here, the kernel will
468 if ((k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
477 close_nointr_nofail(ioctl_fd);
482 static void automount_enter_waiting(Automount *a) {
483 int p[2] = { -1, -1 };
484 char name[32], options[128];
485 bool mounted = false;
486 int r, ioctl_fd = -1, dev_autofs_fd;
490 assert(a->pipe_fd < 0);
494 set_clear(a->tokens);
496 if ((dev_autofs_fd = open_dev_autofs(UNIT(a)->manager)) < 0) {
501 /* We knowingly ignore the results of this call */
502 mkdir_p_label(a->where, 0555);
504 if (dir_is_empty(a->where) <= 0)
505 log_notice("%s: Directory %s to mount over is not empty, mounting anyway. (To see the over-mounted files, please manually mount the underlying file system to a secondary location.)", a->meta.id, a->where);
507 if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
512 snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp());
513 char_array_0(options);
515 snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid());
518 if (mount(name, a->where, "autofs", 0, options) < 0) {
525 close_nointr_nofail(p[1]);
528 if (stat(a->where, &st) < 0) {
533 if ((ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev)) < 0) {
538 if ((r = autofs_protocol(dev_autofs_fd, ioctl_fd)) < 0)
541 if ((r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300)) < 0)
546 * Unless we close the ioctl fd here, for some weird reason
547 * the direct mount will not receive events from the
550 close_nointr_nofail(ioctl_fd);
553 if ((r = unit_watch_fd(UNIT(a), p[0], EPOLLIN, &a->pipe_watch)) < 0)
557 a->dev_id = st.st_dev;
559 automount_set_state(a, AUTOMOUNT_WAITING);
564 assert_se(close_pipe(p) == 0);
567 close_nointr_nofail(ioctl_fd);
570 repeat_unmout(a->where);
572 log_error("Failed to initialize automounter: %s", strerror(-r));
573 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
576 static void automount_enter_runnning(Automount *a) {
582 assert(UNIT_DEREF(a->mount));
584 dbus_error_init(&error);
586 /* We don't take mount requests anymore if we are supposed to
587 * shut down anyway */
588 if (unit_pending_inactive(UNIT(a))) {
589 log_debug("Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
590 automount_send_ready(a, -EHOSTDOWN);
594 mkdir_p_label(a->where, a->directory_mode);
596 /* Before we do anything, let's see if somebody is playing games with us? */
597 if (lstat(a->where, &st) < 0) {
598 log_warning("%s failed to stat automount point: %m", UNIT(a)->id);
602 if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
603 log_info("%s's automount point already active?", UNIT(a)->id);
604 else if ((r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_DEREF(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) {
605 log_warning("%s failed to queue mount startup job: %s", UNIT(a)->id, bus_error(&error, r));
609 automount_set_state(a, AUTOMOUNT_RUNNING);
613 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
614 dbus_error_free(&error);
617 static int automount_start(Unit *u) {
618 Automount *a = AUTOMOUNT(u);
622 assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
624 if (path_is_mount_point(a->where, false)) {
625 log_error("Path %s is already a mount point, refusing start for %s", a->where, u->id);
629 if (UNIT_DEREF(a->mount)->load_state != UNIT_LOADED)
632 a->result = AUTOMOUNT_SUCCESS;
633 automount_enter_waiting(a);
637 static int automount_stop(Unit *u) {
638 Automount *a = AUTOMOUNT(u);
642 assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
644 automount_enter_dead(a, AUTOMOUNT_SUCCESS);
648 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
649 Automount *a = AUTOMOUNT(u);
657 unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
658 unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
659 unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
661 SET_FOREACH(p, a->tokens, i)
662 unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
664 if (a->pipe_fd >= 0) {
667 if ((copy = fdset_put_dup(fds, a->pipe_fd)) < 0)
670 unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
676 static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
677 Automount *a = AUTOMOUNT(u);
683 if (streq(key, "state")) {
684 AutomountState state;
686 if ((state = automount_state_from_string(value)) < 0)
687 log_debug("Failed to parse state value %s", value);
689 a->deserialized_state = state;
690 } else if (streq(key, "result")) {
693 f = automount_result_from_string(value);
695 log_debug("Failed to parse result value %s", value);
696 else if (f != AUTOMOUNT_SUCCESS)
699 } else if (streq(key, "dev-id")) {
702 if (safe_atou(value, &d) < 0)
703 log_debug("Failed to parse dev-id value %s", value);
705 a->dev_id = (unsigned) d;
706 } else if (streq(key, "token")) {
709 if (safe_atou(value, &token) < 0)
710 log_debug("Failed to parse token value %s", value);
713 if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func)))
716 if ((r = set_put(a->tokens, UINT_TO_PTR(token))) < 0)
719 } else if (streq(key, "pipe-fd")) {
722 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
723 log_debug("Failed to parse pipe-fd value %s", value);
726 close_nointr_nofail(a->pipe_fd);
728 a->pipe_fd = fdset_remove(fds, fd);
731 log_debug("Unknown serialization key '%s'", key);
736 static UnitActiveState automount_active_state(Unit *u) {
739 return state_translation_table[AUTOMOUNT(u)->state];
742 static const char *automount_sub_state_to_string(Unit *u) {
745 return automount_state_to_string(AUTOMOUNT(u)->state);
748 static bool automount_check_gc(Unit *u) {
749 Automount *a = AUTOMOUNT(u);
753 if (!UNIT_DEREF(a->mount))
756 return UNIT_VTABLE(UNIT_DEREF(a->mount))->check_gc(UNIT_DEREF(a->mount));
759 static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
760 Automount *a = AUTOMOUNT(u);
761 union autofs_v5_packet_union packet;
766 assert(fd == a->pipe_fd);
768 if (events != EPOLLIN) {
769 log_error("Got invalid poll event on pipe.");
773 if ((l = loop_read(a->pipe_fd, &packet, sizeof(packet), true)) != sizeof(packet)) {
774 log_error("Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
778 switch (packet.hdr.type) {
780 case autofs_ptype_missing_direct:
782 if (packet.v5_packet.pid > 0) {
785 get_process_comm(packet.v5_packet.pid, &p);
786 log_debug("Got direct mount request on %s, triggered by %lu (%s)",
787 a->where, (unsigned long) packet.v5_packet.pid, strna(p));
791 log_debug("Got direct mount request on %s", a->where);
794 if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func))) {
795 log_error("Failed to allocate token set.");
799 if ((r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token))) < 0) {
800 log_error("Failed to remember token: %s", strerror(-r));
804 automount_enter_runnning(a);
808 log_error("Received unknown automount request %i", packet.hdr.type);
815 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
818 static void automount_shutdown(Manager *m) {
821 if (m->dev_autofs_fd >= 0)
822 close_nointr_nofail(m->dev_autofs_fd);
825 static void automount_reset_failed(Unit *u) {
826 Automount *a = AUTOMOUNT(u);
830 if (a->state == AUTOMOUNT_FAILED)
831 automount_set_state(a, AUTOMOUNT_DEAD);
833 a->result = AUTOMOUNT_SUCCESS;
836 static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
837 [AUTOMOUNT_DEAD] = "dead",
838 [AUTOMOUNT_WAITING] = "waiting",
839 [AUTOMOUNT_RUNNING] = "running",
840 [AUTOMOUNT_FAILED] = "failed"
843 DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
845 static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
846 [AUTOMOUNT_SUCCESS] = "success",
847 [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
850 DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
852 const UnitVTable automount_vtable = {
853 .object_size = sizeof(Automount),
860 .no_instances = true,
862 .init = automount_init,
863 .load = automount_load,
864 .done = automount_done,
866 .coldplug = automount_coldplug,
868 .dump = automount_dump,
870 .start = automount_start,
871 .stop = automount_stop,
873 .serialize = automount_serialize,
874 .deserialize_item = automount_deserialize_item,
876 .active_state = automount_active_state,
877 .sub_state_to_string = automount_sub_state_to_string,
879 .check_gc = automount_check_gc,
881 .fd_event = automount_fd_event,
883 .reset_failed = automount_reset_failed,
885 .bus_interface = "org.freedesktop.systemd1.Automount",
886 .bus_message_handler = bus_automount_message_handler,
887 .bus_invalidating_properties = bus_automount_invalidating_properties,
889 .shutdown = automount_shutdown,
891 .status_message_formats = {
892 .finished_start_job = {
893 [JOB_DONE] = "Set up automount %s.",
894 [JOB_FAILED] = "Failed to set up automount %s.",
895 [JOB_DEPENDENCY] = "Dependency failed for %s.",
897 .finished_stop_job = {
898 [JOB_DONE] = "Unset automount %s.",
899 [JOB_FAILED] = "Failed to unset automount %s.",