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"
41 #include "path-util.h"
42 #include "dbus-automount.h"
44 #include "bus-error.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);
54 static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata);
56 static void automount_init(Unit *u) {
57 Automount *a = AUTOMOUNT(u);
60 assert(u->load_state == UNIT_STUB);
63 a->directory_mode = 0755;
64 UNIT(a)->ignore_on_isolate = true;
67 static void repeat_unmount(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 a->pipe_event_source = sd_event_source_unref(a->pipe_event_source);
93 a->pipe_fd = safe_close(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_unmount(a->where);
103 static void automount_done(Unit *u) {
104 Automount *a = AUTOMOUNT(u);
117 static int automount_add_mount_links(Automount *a) {
118 _cleanup_free_ char *parent = NULL;
123 r = path_get_parent(a->where, &parent);
127 return unit_require_mounts_for(UNIT(a), parent);
130 static int automount_add_default_dependencies(Automount *a) {
135 if (UNIT(a)->manager->running_as != SYSTEMD_SYSTEM)
138 r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
145 static int automount_verify(Automount *a) {
147 _cleanup_free_ char *e = NULL;
150 if (UNIT(a)->load_state != UNIT_LOADED)
153 if (path_equal(a->where, "/")) {
154 log_error_unit(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing.");
158 e = unit_name_from_path(a->where, ".automount");
162 b = unit_has_name(UNIT(a), e);
165 log_error_unit(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
172 static int automount_load(Unit *u) {
173 Automount *a = AUTOMOUNT(u);
177 assert(u->load_state == UNIT_STUB);
179 /* Load a .automount file */
180 r = unit_load_fragment_and_dropin_optional(u);
184 if (u->load_state == UNIT_LOADED) {
188 a->where = unit_name_to_path(u->id);
193 path_kill_slashes(a->where);
195 r = unit_load_related_unit(u, ".mount", &x);
199 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
203 r = automount_add_mount_links(a);
207 if (UNIT(a)->default_dependencies) {
208 r = automount_add_default_dependencies(a);
214 return automount_verify(a);
217 static void automount_set_state(Automount *a, AutomountState state) {
218 AutomountState old_state;
221 old_state = a->state;
224 if (state != AUTOMOUNT_WAITING &&
225 state != AUTOMOUNT_RUNNING)
228 if (state != old_state)
229 log_debug_unit(UNIT(a)->id,
230 "%s changed %s -> %s",
232 automount_state_to_string(old_state),
233 automount_state_to_string(state));
235 unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
238 static int automount_coldplug(Unit *u) {
239 Automount *a = AUTOMOUNT(u);
243 assert(a->state == AUTOMOUNT_DEAD);
245 if (a->deserialized_state != a->state) {
247 r = open_dev_autofs(u->manager);
251 if (a->deserialized_state == AUTOMOUNT_WAITING ||
252 a->deserialized_state == AUTOMOUNT_RUNNING) {
254 assert(a->pipe_fd >= 0);
256 r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u);
261 automount_set_state(a, a->deserialized_state);
267 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
268 Automount *a = AUTOMOUNT(u);
273 "%sAutomount State: %s\n"
276 "%sDirectoryMode: %04o\n",
277 prefix, automount_state_to_string(a->state),
278 prefix, automount_result_to_string(a->result),
280 prefix, a->directory_mode);
283 static void automount_enter_dead(Automount *a, AutomountResult f) {
286 if (f != AUTOMOUNT_SUCCESS)
289 automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
292 static int open_dev_autofs(Manager *m) {
293 struct autofs_dev_ioctl param;
297 if (m->dev_autofs_fd >= 0)
298 return m->dev_autofs_fd;
300 label_fix("/dev/autofs", false, false);
302 m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY);
303 if (m->dev_autofs_fd < 0) {
304 log_error("Failed to open /dev/autofs: %m");
308 init_autofs_dev_ioctl(¶m);
309 if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, ¶m) < 0) {
310 m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
314 log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
316 return m->dev_autofs_fd;
319 static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
320 struct autofs_dev_ioctl *param;
323 assert(dev_autofs_fd >= 0);
326 l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
329 init_autofs_dev_ioctl(param);
332 param->openmount.devid = devid;
333 strcpy(param->path, where);
335 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0)
338 if (param->ioctlfd < 0)
341 fd_cloexec(param->ioctlfd, true);
342 return param->ioctlfd;
345 static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
346 uint32_t major, minor;
347 struct autofs_dev_ioctl param;
349 assert(dev_autofs_fd >= 0);
350 assert(ioctl_fd >= 0);
352 init_autofs_dev_ioctl(¶m);
353 param.ioctlfd = ioctl_fd;
355 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, ¶m) < 0)
358 major = param.protover.version;
360 init_autofs_dev_ioctl(¶m);
361 param.ioctlfd = ioctl_fd;
363 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, ¶m) < 0)
366 minor = param.protosubver.sub_version;
368 log_debug("Autofs protocol version %i.%i", major, minor);
372 static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) {
373 struct autofs_dev_ioctl param;
375 assert(dev_autofs_fd >= 0);
376 assert(ioctl_fd >= 0);
378 init_autofs_dev_ioctl(¶m);
379 param.ioctlfd = ioctl_fd;
380 param.timeout.timeout = sec;
382 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) < 0)
388 static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
389 struct autofs_dev_ioctl param;
391 assert(dev_autofs_fd >= 0);
392 assert(ioctl_fd >= 0);
394 init_autofs_dev_ioctl(¶m);
395 param.ioctlfd = ioctl_fd;
398 param.fail.token = token;
399 param.fail.status = status;
401 param.ready.token = token;
403 if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, ¶m) < 0)
409 int automount_send_ready(Automount *a, int status) {
410 _cleanup_close_ int ioctl_fd = -1;
417 if (set_isempty(a->tokens))
420 ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
425 log_debug_unit(UNIT(a)->id, "Sending failure: %s", strerror(-status));
427 log_debug_unit(UNIT(a)->id, "Sending success.");
431 /* Autofs thankfully does not hand out 0 as a token */
432 while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) {
435 /* Autofs fun fact II:
437 * if you pass a positive status code here, the kernel will
440 k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
451 static void automount_enter_waiting(Automount *a) {
452 _cleanup_close_ int ioctl_fd = -1;
453 int p[2] = { -1, -1 };
454 char name[32], options[128];
455 bool mounted = false;
456 int r, dev_autofs_fd;
460 assert(a->pipe_fd < 0);
464 set_clear(a->tokens);
466 dev_autofs_fd = open_dev_autofs(UNIT(a)->manager);
467 if (dev_autofs_fd < 0) {
472 /* We knowingly ignore the results of this call */
473 mkdir_p_label(a->where, 0555);
475 warn_if_dir_nonempty(a->meta.id, a->where);
477 if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
482 snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp());
483 char_array_0(options);
485 snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid());
488 if (mount(name, a->where, "autofs", 0, options) < 0) {
495 p[1] = safe_close(p[1]);
497 if (stat(a->where, &st) < 0) {
502 ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev);
508 r = autofs_protocol(dev_autofs_fd, ioctl_fd);
512 r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300);
518 * Unless we close the ioctl fd here, for some weird reason
519 * the direct mount will not receive events from the
522 r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
527 a->dev_id = st.st_dev;
529 automount_set_state(a, AUTOMOUNT_WAITING);
537 repeat_unmount(a->where);
539 log_error_unit(UNIT(a)->id,
540 "Failed to initialize automounter: %s", strerror(-r));
541 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
544 static void automount_enter_runnning(Automount *a) {
545 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
551 /* We don't take mount requests anymore if we are supposed to
552 * shut down anyway */
553 if (unit_stop_pending(UNIT(a))) {
554 log_debug_unit(UNIT(a)->id,
555 "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
556 automount_send_ready(a, -EHOSTDOWN);
560 mkdir_p_label(a->where, a->directory_mode);
562 /* Before we do anything, let's see if somebody is playing games with us? */
563 if (lstat(a->where, &st) < 0) {
564 log_warning_unit(UNIT(a)->id,
565 "%s failed to stat automount point: %m", UNIT(a)->id);
569 if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
570 log_info_unit(UNIT(a)->id,
571 "%s's automount point already active?", UNIT(a)->id);
573 r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)),
574 JOB_REPLACE, true, &error, NULL);
576 log_warning_unit(UNIT(a)->id,
577 "%s failed to queue mount startup job: %s",
578 UNIT(a)->id, bus_error_message(&error, r));
583 automount_set_state(a, AUTOMOUNT_RUNNING);
587 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
590 static int automount_start(Unit *u) {
591 Automount *a = AUTOMOUNT(u);
594 assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
596 if (path_is_mount_point(a->where, false)) {
597 log_error_unit(u->id,
598 "Path %s is already a mount point, refusing start for %s",
603 if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
606 a->result = AUTOMOUNT_SUCCESS;
607 automount_enter_waiting(a);
611 static int automount_stop(Unit *u) {
612 Automount *a = AUTOMOUNT(u);
615 assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
617 automount_enter_dead(a, AUTOMOUNT_SUCCESS);
621 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
622 Automount *a = AUTOMOUNT(u);
630 unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
631 unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
632 unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
634 SET_FOREACH(p, a->tokens, i)
635 unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
637 if (a->pipe_fd >= 0) {
640 copy = fdset_put_dup(fds, a->pipe_fd);
644 unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
650 static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
651 Automount *a = AUTOMOUNT(u);
657 if (streq(key, "state")) {
658 AutomountState state;
660 state = automount_state_from_string(value);
662 log_debug_unit(u->id, "Failed to parse state value %s", value);
664 a->deserialized_state = state;
665 } else if (streq(key, "result")) {
668 f = automount_result_from_string(value);
670 log_debug_unit(u->id, "Failed to parse result value %s", value);
671 else if (f != AUTOMOUNT_SUCCESS)
674 } else if (streq(key, "dev-id")) {
677 if (safe_atou(value, &d) < 0)
678 log_debug_unit(u->id, "Failed to parse dev-id value %s", value);
680 a->dev_id = (unsigned) d;
681 } else if (streq(key, "token")) {
684 if (safe_atou(value, &token) < 0)
685 log_debug_unit(u->id, "Failed to parse token value %s", value);
688 if (!(a->tokens = set_new(NULL)))
691 r = set_put(a->tokens, UINT_TO_PTR(token));
695 } else if (streq(key, "pipe-fd")) {
698 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
699 log_debug_unit(u->id, "Failed to parse pipe-fd value %s", value);
701 safe_close(a->pipe_fd);
702 a->pipe_fd = fdset_remove(fds, fd);
705 log_debug_unit(u->id, "Unknown serialization key '%s'", key);
710 static UnitActiveState automount_active_state(Unit *u) {
713 return state_translation_table[AUTOMOUNT(u)->state];
716 static const char *automount_sub_state_to_string(Unit *u) {
719 return automount_state_to_string(AUTOMOUNT(u)->state);
722 static bool automount_check_gc(Unit *u) {
725 if (!UNIT_TRIGGER(u))
728 return UNIT_VTABLE(UNIT_TRIGGER(u))->check_gc(UNIT_TRIGGER(u));
731 static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata) {
732 union autofs_v5_packet_union packet;
733 Automount *a = AUTOMOUNT(userdata);
738 assert(fd == a->pipe_fd);
740 if (events != EPOLLIN) {
741 log_error_unit(UNIT(a)->id, "Got invalid poll event on pipe.");
745 l = loop_read(a->pipe_fd, &packet, sizeof(packet), true);
746 if (l != sizeof(packet)) {
747 log_error_unit(UNIT(a)->id, "Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
751 switch (packet.hdr.type) {
753 case autofs_ptype_missing_direct:
755 if (packet.v5_packet.pid > 0) {
756 _cleanup_free_ char *p = NULL;
758 get_process_comm(packet.v5_packet.pid, &p);
759 log_info_unit(UNIT(a)->id,
760 "Got automount request for %s, triggered by "PID_FMT" (%s)",
761 a->where, packet.v5_packet.pid, strna(p));
763 log_debug_unit(UNIT(a)->id, "Got direct mount request on %s", a->where);
765 r = set_ensure_allocated(&a->tokens, NULL);
767 log_error_unit(UNIT(a)->id, "Failed to allocate token set.");
771 r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
773 log_error_unit(UNIT(a)->id, "Failed to remember token: %s", strerror(-r));
777 automount_enter_runnning(a);
781 log_error_unit(UNIT(a)->id, "Received unknown automount request %i", packet.hdr.type);
788 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
792 static void automount_shutdown(Manager *m) {
795 m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
798 static void automount_reset_failed(Unit *u) {
799 Automount *a = AUTOMOUNT(u);
803 if (a->state == AUTOMOUNT_FAILED)
804 automount_set_state(a, AUTOMOUNT_DEAD);
806 a->result = AUTOMOUNT_SUCCESS;
809 static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
810 [AUTOMOUNT_DEAD] = "dead",
811 [AUTOMOUNT_WAITING] = "waiting",
812 [AUTOMOUNT_RUNNING] = "running",
813 [AUTOMOUNT_FAILED] = "failed"
816 DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
818 static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
819 [AUTOMOUNT_SUCCESS] = "success",
820 [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
823 DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
825 const UnitVTable automount_vtable = {
826 .object_size = sizeof(Automount),
834 .no_instances = true,
836 .init = automount_init,
837 .load = automount_load,
838 .done = automount_done,
840 .coldplug = automount_coldplug,
842 .dump = automount_dump,
844 .start = automount_start,
845 .stop = automount_stop,
847 .serialize = automount_serialize,
848 .deserialize_item = automount_deserialize_item,
850 .active_state = automount_active_state,
851 .sub_state_to_string = automount_sub_state_to_string,
853 .check_gc = automount_check_gc,
855 .reset_failed = automount_reset_failed,
857 .bus_interface = "org.freedesktop.systemd1.Automount",
858 .bus_vtable = bus_automount_vtable,
860 .shutdown = automount_shutdown,
862 .status_message_formats = {
863 .finished_start_job = {
864 [JOB_DONE] = "Set up automount %s.",
865 [JOB_FAILED] = "Failed to set up automount %s.",
866 [JOB_DEPENDENCY] = "Dependency failed for %s.",
868 .finished_stop_job = {
869 [JOB_DONE] = "Unset automount %s.",
870 [JOB_FAILED] = "Failed to unset automount %s.",