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 != MANAGER_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 (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
509 snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp());
510 char_array_0(options);
512 snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid());
515 if (mount(name, a->where, "autofs", 0, options) < 0) {
522 close_nointr_nofail(p[1]);
525 if (stat(a->where, &st) < 0) {
530 if ((ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev)) < 0) {
535 if ((r = autofs_protocol(dev_autofs_fd, ioctl_fd)) < 0)
538 if ((r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300)) < 0)
543 * Unless we close the ioctl fd here, for some weird reason
544 * the direct mount will not receive events from the
547 close_nointr_nofail(ioctl_fd);
550 if ((r = unit_watch_fd(UNIT(a), p[0], EPOLLIN, &a->pipe_watch)) < 0)
554 a->dev_id = st.st_dev;
556 automount_set_state(a, AUTOMOUNT_WAITING);
561 assert_se(close_pipe(p) == 0);
564 close_nointr_nofail(ioctl_fd);
567 repeat_unmout(a->where);
569 log_error("Failed to initialize automounter: %s", strerror(-r));
570 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
573 static void automount_enter_runnning(Automount *a) {
579 assert(UNIT_DEREF(a->mount));
581 dbus_error_init(&error);
583 /* We don't take mount requests anymore if we are supposed to
584 * shut down anyway */
585 if (unit_pending_inactive(UNIT(a))) {
586 log_debug("Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
587 automount_send_ready(a, -EHOSTDOWN);
591 mkdir_p_label(a->where, a->directory_mode);
593 /* Before we do anything, let's see if somebody is playing games with us? */
594 if (lstat(a->where, &st) < 0) {
595 log_warning("%s failed to stat automount point: %m", UNIT(a)->id);
599 if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
600 log_info("%s's automount point already active?", UNIT(a)->id);
601 else if ((r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_DEREF(a->mount), JOB_REPLACE, true, &error, NULL)) < 0) {
602 log_warning("%s failed to queue mount startup job: %s", UNIT(a)->id, bus_error(&error, r));
606 automount_set_state(a, AUTOMOUNT_RUNNING);
610 automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
611 dbus_error_free(&error);
614 static int automount_start(Unit *u) {
615 Automount *a = AUTOMOUNT(u);
619 assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
621 if (path_is_mount_point(a->where, false)) {
622 log_error("Path %s is already a mount point, refusing start for %s", a->where, u->id);
626 if (UNIT_DEREF(a->mount)->load_state != UNIT_LOADED)
629 a->result = AUTOMOUNT_SUCCESS;
630 automount_enter_waiting(a);
634 static int automount_stop(Unit *u) {
635 Automount *a = AUTOMOUNT(u);
639 assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
641 automount_enter_dead(a, AUTOMOUNT_SUCCESS);
645 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
646 Automount *a = AUTOMOUNT(u);
654 unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
655 unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
656 unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
658 SET_FOREACH(p, a->tokens, i)
659 unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
661 if (a->pipe_fd >= 0) {
664 if ((copy = fdset_put_dup(fds, a->pipe_fd)) < 0)
667 unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
673 static int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
674 Automount *a = AUTOMOUNT(u);
680 if (streq(key, "state")) {
681 AutomountState state;
683 if ((state = automount_state_from_string(value)) < 0)
684 log_debug("Failed to parse state value %s", value);
686 a->deserialized_state = state;
687 } else if (streq(key, "result")) {
690 f = automount_result_from_string(value);
692 log_debug("Failed to parse result value %s", value);
693 else if (f != AUTOMOUNT_SUCCESS)
696 } else if (streq(key, "dev-id")) {
699 if (safe_atou(value, &d) < 0)
700 log_debug("Failed to parse dev-id value %s", value);
702 a->dev_id = (unsigned) d;
703 } else if (streq(key, "token")) {
706 if (safe_atou(value, &token) < 0)
707 log_debug("Failed to parse token value %s", value);
710 if (!(a->tokens = set_new(trivial_hash_func, trivial_compare_func)))
713 if ((r = set_put(a->tokens, UINT_TO_PTR(token))) < 0)
716 } else if (streq(key, "pipe-fd")) {
719 if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
720 log_debug("Failed to parse pipe-fd value %s", value);
723 close_nointr_nofail(a->pipe_fd);
725 a->pipe_fd = fdset_remove(fds, fd);
728 log_debug("Unknown serialization key '%s'", key);
733 static UnitActiveState automount_active_state(Unit *u) {
736 return state_translation_table[AUTOMOUNT(u)->state];
739 static const char *automount_sub_state_to_string(Unit *u) {
742 return automount_state_to_string(AUTOMOUNT(u)->state);
745 static bool automount_check_gc(Unit *u) {
746 Automount *a = AUTOMOUNT(u);
750 if (!UNIT_DEREF(a->mount))
753 return UNIT_VTABLE(UNIT_DEREF(a->mount))->check_gc(UNIT_DEREF(a->mount));
756 static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
757 Automount *a = AUTOMOUNT(u);
758 union autofs_v5_packet_union packet;
763 assert(fd == a->pipe_fd);
765 if (events != EPOLLIN) {
766 log_error("Got invalid poll event on pipe.");
770 if ((l = loop_read(a->pipe_fd, &packet, sizeof(packet), true)) != sizeof(packet)) {
771 log_error("Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
775 switch (packet.hdr.type) {
777 case autofs_ptype_missing_direct:
779 if (packet.v5_packet.pid > 0) {
782 get_process_comm(packet.v5_packet.pid, &p);
783 log_debug("Got direct mount request on %s, triggered by %lu (%s)",
784 a->where, (unsigned long) packet.v5_packet.pid, strna(p));
788 log_debug("Got direct mount request on %s", a->where);
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 .object_size = sizeof(Automount),
857 .no_instances = true,
859 .init = automount_init,
860 .load = automount_load,
861 .done = automount_done,
863 .coldplug = automount_coldplug,
865 .dump = automount_dump,
867 .start = automount_start,
868 .stop = automount_stop,
870 .serialize = automount_serialize,
871 .deserialize_item = automount_deserialize_item,
873 .active_state = automount_active_state,
874 .sub_state_to_string = automount_sub_state_to_string,
876 .check_gc = automount_check_gc,
878 .fd_event = automount_fd_event,
880 .reset_failed = automount_reset_failed,
882 .bus_interface = "org.freedesktop.systemd1.Automount",
883 .bus_message_handler = bus_automount_message_handler,
884 .bus_invalidating_properties = bus_automount_invalidating_properties,
886 .shutdown = automount_shutdown,
888 .status_message_formats = {
889 .finished_start_job = {
890 [JOB_DONE] = "Set up automount %s.",
891 [JOB_FAILED] = "Failed to set up automount %s.",
892 [JOB_DEPENDENCY] = "Dependency failed for %s.",
894 .finished_stop_job = {
895 [JOB_DONE] = "Unset automount %s.",
896 [JOB_FAILED] = "Failed to unset automount %s.",