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 "unit-name.h"
39 #include "path-util.h"
40 #include "dbus-automount.h"
42 #include "bus-error.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);
52 static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata);
54 static void automount_init(Unit *u) {
55 Automount *a = AUTOMOUNT(u);
58 assert(u->load_state == UNIT_STUB);
61 a->directory_mode = 0755;
62 UNIT(a)->ignore_on_isolate = true;
65 static void repeat_unmount(const char *path) {
69 /* If there are multiple mounts on a mount point, this
72 if (umount2(path, MNT_DETACH) >= 0)
76 log_error_errno(errno, "Failed to unmount: %m");
82 static void unmount_autofs(Automount *a) {
88 automount_send_ready(a, -EHOSTDOWN);
90 a->pipe_event_source = sd_event_source_unref(a->pipe_event_source);
91 a->pipe_fd = safe_close(a->pipe_fd);
93 /* If we reload/reexecute things we keep the mount point
96 (UNIT(a)->manager->exit_code != MANAGER_RELOAD &&
97 UNIT(a)->manager->exit_code != MANAGER_REEXECUTE))
98 repeat_unmount(a->where);
101 static void automount_done(Unit *u) {
102 Automount *a = AUTOMOUNT(u);
115 static int automount_add_mount_links(Automount *a) {
116 _cleanup_free_ char *parent = NULL;
121 r = path_get_parent(a->where, &parent);
125 return unit_require_mounts_for(UNIT(a), parent);
128 static int automount_add_default_dependencies(Automount *a) {
133 if (UNIT(a)->manager->running_as != SYSTEMD_SYSTEM)
136 r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
143 static int automount_verify(Automount *a) {
145 _cleanup_free_ char *e = NULL;
148 if (UNIT(a)->load_state != UNIT_LOADED)
151 if (path_equal(a->where, "/")) {
152 log_unit_error(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing.");
156 e = unit_name_from_path(a->where, ".automount");
160 b = unit_has_name(UNIT(a), e);
163 log_unit_error(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
170 static int automount_load(Unit *u) {
171 Automount *a = AUTOMOUNT(u);
175 assert(u->load_state == UNIT_STUB);
177 /* Load a .automount file */
178 r = unit_load_fragment_and_dropin_optional(u);
182 if (u->load_state == UNIT_LOADED) {
186 a->where = unit_name_to_path(u->id);
191 path_kill_slashes(a->where);
193 r = unit_load_related_unit(u, ".mount", &x);
197 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
201 r = automount_add_mount_links(a);
205 if (UNIT(a)->default_dependencies) {
206 r = automount_add_default_dependencies(a);
212 return automount_verify(a);
215 static void automount_set_state(Automount *a, AutomountState state) {
216 AutomountState old_state;
219 old_state = a->state;
222 if (state != AUTOMOUNT_WAITING &&
223 state != AUTOMOUNT_RUNNING)
226 if (state != old_state)
227 log_unit_debug(UNIT(a)->id,
228 "%s changed %s -> %s",
230 automount_state_to_string(old_state),
231 automount_state_to_string(state));
233 unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
236 static int automount_coldplug(Unit *u) {
237 Automount *a = AUTOMOUNT(u);
241 assert(a->state == AUTOMOUNT_DEAD);
243 if (a->deserialized_state != a->state) {
245 r = open_dev_autofs(u->manager);
249 if (a->deserialized_state == AUTOMOUNT_WAITING ||
250 a->deserialized_state == AUTOMOUNT_RUNNING) {
252 assert(a->pipe_fd >= 0);
254 r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u);
259 automount_set_state(a, a->deserialized_state);
265 static void automount_dump(Unit *u, FILE *f, const char *prefix) {
266 Automount *a = AUTOMOUNT(u);
271 "%sAutomount State: %s\n"
274 "%sDirectoryMode: %04o\n",
275 prefix, automount_state_to_string(a->state),
276 prefix, automount_result_to_string(a->result),
278 prefix, a->directory_mode);
281 static void automount_enter_dead(Automount *a, AutomountResult f) {
284 if (f != AUTOMOUNT_SUCCESS)
287 automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
290 static int open_dev_autofs(Manager *m) {
291 struct autofs_dev_ioctl param;
295 if (m->dev_autofs_fd >= 0)
296 return m->dev_autofs_fd;
298 label_fix("/dev/autofs", false, false);
300 m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY);
301 if (m->dev_autofs_fd < 0)
302 return log_error_errno(errno, "Failed to open /dev/autofs: %m");
304 init_autofs_dev_ioctl(¶m);
305 if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, ¶m) < 0) {
306 m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
310 log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
312 return m->dev_autofs_fd;
315 static int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
316 struct autofs_dev_ioctl *param;
319 assert(dev_autofs_fd >= 0);
322 l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
325 init_autofs_dev_ioctl(param);
328 param->openmount.devid = devid;
329 strcpy(param->path, where);
331 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0)
334 if (param->ioctlfd < 0)
337 fd_cloexec(param->ioctlfd, true);
338 return param->ioctlfd;
341 static int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
342 uint32_t major, minor;
343 struct autofs_dev_ioctl param;
345 assert(dev_autofs_fd >= 0);
346 assert(ioctl_fd >= 0);
348 init_autofs_dev_ioctl(¶m);
349 param.ioctlfd = ioctl_fd;
351 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, ¶m) < 0)
354 major = param.protover.version;
356 init_autofs_dev_ioctl(¶m);
357 param.ioctlfd = ioctl_fd;
359 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, ¶m) < 0)
362 minor = param.protosubver.sub_version;
364 log_debug("Autofs protocol version %i.%i", major, minor);
368 static int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) {
369 struct autofs_dev_ioctl param;
371 assert(dev_autofs_fd >= 0);
372 assert(ioctl_fd >= 0);
374 init_autofs_dev_ioctl(¶m);
375 param.ioctlfd = ioctl_fd;
376 param.timeout.timeout = sec;
378 if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) < 0)
384 static int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
385 struct autofs_dev_ioctl param;
387 assert(dev_autofs_fd >= 0);
388 assert(ioctl_fd >= 0);
390 init_autofs_dev_ioctl(¶m);
391 param.ioctlfd = ioctl_fd;
394 param.fail.token = token;
395 param.fail.status = status;
397 param.ready.token = token;
399 if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, ¶m) < 0)
405 int automount_send_ready(Automount *a, int status) {
406 _cleanup_close_ int ioctl_fd = -1;
413 if (set_isempty(a->tokens))
416 ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
421 log_unit_debug_errno(UNIT(a)->id, status, "Sending failure: %m");
423 log_unit_debug(UNIT(a)->id, "Sending success.");
427 /* Autofs thankfully does not hand out 0 as a token */
428 while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) {
431 /* Autofs fun fact II:
433 * if you pass a positive status code here, the kernel will
436 k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
447 static void automount_enter_waiting(Automount *a) {
448 _cleanup_close_ int ioctl_fd = -1;
449 int p[2] = { -1, -1 };
450 char name[sizeof("systemd-")-1 + DECIMAL_STR_MAX(pid_t) + 1];
451 char options[sizeof("fd=,pgrp=,minproto=5,maxproto=5,direct")-1
452 + DECIMAL_STR_MAX(int) + DECIMAL_STR_MAX(gid_t) + 1];
453 bool mounted = false;
454 int r, dev_autofs_fd;
458 assert(a->pipe_fd < 0);
462 set_clear(a->tokens);
464 dev_autofs_fd = open_dev_autofs(UNIT(a)->manager);
465 if (dev_autofs_fd < 0) {
470 /* We knowingly ignore the results of this call */
471 mkdir_p_label(a->where, 0555);
473 warn_if_dir_nonempty(a->meta.id, a->where);
475 if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
480 xsprintf(options, "fd=%i,pgrp="PID_FMT",minproto=5,maxproto=5,direct", p[1], getpgrp());
481 xsprintf(name, "systemd-"PID_FMT, getpid());
482 if (mount(name, a->where, "autofs", 0, options) < 0) {
489 p[1] = safe_close(p[1]);
491 if (stat(a->where, &st) < 0) {
496 ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev);
502 r = autofs_protocol(dev_autofs_fd, ioctl_fd);
506 r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300);
512 * Unless we close the ioctl fd here, for some weird reason
513 * the direct mount will not receive events from the
516 r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
521 a->dev_id = st.st_dev;
523 automount_set_state(a, AUTOMOUNT_WAITING);
531 repeat_unmount(a->where);
533 log_unit_error(UNIT(a)->id,
534 "Failed to initialize automounter: %s", strerror(-r));
535 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
538 static void automount_enter_runnning(Automount *a) {
539 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
545 /* We don't take mount requests anymore if we are supposed to
546 * shut down anyway */
547 if (unit_stop_pending(UNIT(a))) {
548 log_unit_debug(UNIT(a)->id,
549 "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
550 automount_send_ready(a, -EHOSTDOWN);
554 mkdir_p_label(a->where, a->directory_mode);
556 /* Before we do anything, let's see if somebody is playing games with us? */
557 if (lstat(a->where, &st) < 0) {
558 log_unit_warning(UNIT(a)->id,
559 "%s failed to stat automount point: %m", UNIT(a)->id);
563 if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
564 log_unit_info(UNIT(a)->id,
565 "%s's automount point already active?", UNIT(a)->id);
567 r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)),
568 JOB_REPLACE, true, &error, NULL);
570 log_unit_warning(UNIT(a)->id,
571 "%s failed to queue mount startup job: %s",
572 UNIT(a)->id, bus_error_message(&error, r));
577 automount_set_state(a, AUTOMOUNT_RUNNING);
581 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
584 static int automount_start(Unit *u) {
585 Automount *a = AUTOMOUNT(u);
588 assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
590 if (path_is_mount_point(a->where, false)) {
591 log_unit_error(u->id,
592 "Path %s is already a mount point, refusing start for %s",
597 if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
600 a->result = AUTOMOUNT_SUCCESS;
601 automount_enter_waiting(a);
605 static int automount_stop(Unit *u) {
606 Automount *a = AUTOMOUNT(u);
609 assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
611 automount_enter_dead(a, AUTOMOUNT_SUCCESS);
615 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
616 Automount *a = AUTOMOUNT(u);
624 unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
625 unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
626 unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
628 SET_FOREACH(p, a->tokens, i)
629 unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
631 if (a->pipe_fd >= 0) {
634 copy = fdset_put_dup(fds, a->pipe_fd);
638 unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
644 static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
645 Automount *a = AUTOMOUNT(u);
651 if (streq(key, "state")) {
652 AutomountState state;
654 state = automount_state_from_string(value);
656 log_unit_debug(u->id, "Failed to parse state value %s", value);
658 a->deserialized_state = state;
659 } else if (streq(key, "result")) {
662 f = automount_result_from_string(value);
664 log_unit_debug(u->id, "Failed to parse result value %s", value);
665 else if (f != AUTOMOUNT_SUCCESS)
668 } else if (streq(key, "dev-id")) {
671 if (safe_atou(value, &d) < 0)
672 log_unit_debug(u->id, "Failed to parse dev-id value %s", value);
674 a->dev_id = (unsigned) d;
675 } else if (streq(key, "token")) {
678 if (safe_atou(value, &token) < 0)
679 log_unit_debug(u->id, "Failed to parse token value %s", value);
682 if (!(a->tokens = set_new(NULL)))
685 r = set_put(a->tokens, UINT_TO_PTR(token));
689 } else if (streq(key, "pipe-fd")) {
692 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
693 log_unit_debug(u->id, "Failed to parse pipe-fd value %s", value);
695 safe_close(a->pipe_fd);
696 a->pipe_fd = fdset_remove(fds, fd);
699 log_unit_debug(u->id, "Unknown serialization key '%s'", key);
704 static UnitActiveState automount_active_state(Unit *u) {
707 return state_translation_table[AUTOMOUNT(u)->state];
710 static const char *automount_sub_state_to_string(Unit *u) {
713 return automount_state_to_string(AUTOMOUNT(u)->state);
716 static bool automount_check_gc(Unit *u) {
719 if (!UNIT_TRIGGER(u))
722 return UNIT_VTABLE(UNIT_TRIGGER(u))->check_gc(UNIT_TRIGGER(u));
725 static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata) {
726 union autofs_v5_packet_union packet;
727 Automount *a = AUTOMOUNT(userdata);
732 assert(fd == a->pipe_fd);
734 if (events != EPOLLIN) {
735 log_unit_error(UNIT(a)->id, "Got invalid poll event on pipe.");
739 l = loop_read(a->pipe_fd, &packet, sizeof(packet), true);
740 if (l != sizeof(packet)) {
742 log_unit_error_errno(UNIT(a)->id, l, "Invalid read from pipe: %m");
744 log_unit_error(UNIT(a)->id, "Invalid read from pipe: short read");
748 switch (packet.hdr.type) {
750 case autofs_ptype_missing_direct:
752 if (packet.v5_packet.pid > 0) {
753 _cleanup_free_ char *p = NULL;
755 get_process_comm(packet.v5_packet.pid, &p);
756 log_unit_info(UNIT(a)->id,
757 "Got automount request for %s, triggered by %"PRIu32" (%s)",
758 a->where, packet.v5_packet.pid, strna(p));
760 log_unit_debug(UNIT(a)->id, "Got direct mount request on %s", a->where);
762 r = set_ensure_allocated(&a->tokens, NULL);
764 log_unit_error(UNIT(a)->id, "Failed to allocate token set.");
768 r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
770 log_unit_error_errno(UNIT(a)->id, r, "Failed to remember token: %m");
774 automount_enter_runnning(a);
778 log_unit_error(UNIT(a)->id, "Received unknown automount request %i", packet.hdr.type);
785 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
789 static void automount_shutdown(Manager *m) {
792 m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
795 static void automount_reset_failed(Unit *u) {
796 Automount *a = AUTOMOUNT(u);
800 if (a->state == AUTOMOUNT_FAILED)
801 automount_set_state(a, AUTOMOUNT_DEAD);
803 a->result = AUTOMOUNT_SUCCESS;
806 static bool automount_supported(Manager *m) {
807 static int supported = -1;
812 supported = access("/dev/autofs", F_OK) >= 0;
817 static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
818 [AUTOMOUNT_DEAD] = "dead",
819 [AUTOMOUNT_WAITING] = "waiting",
820 [AUTOMOUNT_RUNNING] = "running",
821 [AUTOMOUNT_FAILED] = "failed"
824 DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
826 static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
827 [AUTOMOUNT_SUCCESS] = "success",
828 [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
831 DEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
833 const UnitVTable automount_vtable = {
834 .object_size = sizeof(Automount),
842 .no_instances = true,
844 .init = automount_init,
845 .load = automount_load,
846 .done = automount_done,
848 .coldplug = automount_coldplug,
850 .dump = automount_dump,
852 .start = automount_start,
853 .stop = automount_stop,
855 .serialize = automount_serialize,
856 .deserialize_item = automount_deserialize_item,
858 .active_state = automount_active_state,
859 .sub_state_to_string = automount_sub_state_to_string,
861 .check_gc = automount_check_gc,
863 .reset_failed = automount_reset_failed,
865 .bus_interface = "org.freedesktop.systemd1.Automount",
866 .bus_vtable = bus_automount_vtable,
868 .shutdown = automount_shutdown,
869 .supported = automount_supported,
871 .status_message_formats = {
872 .finished_start_job = {
873 [JOB_DONE] = "Set up automount %s.",
874 [JOB_FAILED] = "Failed to set up automount %s.",
875 [JOB_DEPENDENCY] = "Dependency failed for %s.",
877 .finished_stop_job = {
878 [JOB_DONE] = "Unset automount %s.",
879 [JOB_FAILED] = "Failed to unset automount %s.",