automount.c revision d5099efc47d4e6ac60816b5381a5f607ab03f06e
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen This file is part of systemd.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Copyright 2010 Lennart Poettering
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is free software; you can redistribute it and/or modify it
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen under the terms of the GNU Lesser General Public License as published by
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen the Free Software Foundation; either version 2.1 of the License, or
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen (at your option) any later version.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen systemd is distributed in the hope that it will be useful, but
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen WITHOUT ANY WARRANTY; without even the implied warranty of
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Lesser General Public License for more details.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen You should have received a copy of the GNU Lesser General Public License
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen#include <linux/auto_dev-ioctl.h>
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [AUTOMOUNT_DEAD] = UNIT_INACTIVE,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [AUTOMOUNT_WAITING] = UNIT_ACTIVE,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [AUTOMOUNT_RUNNING] = UNIT_ACTIVE,
d5d8429a12c4b1ef0dcd226c0904f00f4fa4898aLennart Poetteringstatic int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void automount_init(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(u->load_state == UNIT_STUB);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(a)->ignore_on_isolate = true;
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmekstatic void repeat_unmount(const char *path) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* If there are multiple mounts on a mount point, this
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * removes them all */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (umount2(path, MNT_DETACH) >= 0)
260ad50f5b4a9795032e3119c64f838a2d03370dThomas Hindoe Paaboel Andersen log_error("Failed to unmount: %m");
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmekstatic void unmount_autofs(Automount *a) {
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek automount_send_ready(a, -EHOSTDOWN);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek a->pipe_event_source = sd_event_source_unref(a->pipe_event_source);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek a->pipe_fd = safe_close(a->pipe_fd);
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek /* If we reload/reexecute things we keep the mount point
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek (UNIT(a)->manager->exit_code != MANAGER_RELOAD &&
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmek UNIT(a)->manager->exit_code != MANAGER_REEXECUTE))
8fba1c8d4e3d05d2af2848b6570bdc09e725d06eZbigniew Jędrzejewski-Szmekstatic void automount_done(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int automount_add_mount_links(Automount *a) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *parent = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = path_get_parent(a->where, &parent);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return unit_require_mounts_for(UNIT(a), parent);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int automount_add_default_dependencies(Automount *a) {
b7e7184634d573fb73143210962acce205f37f61Michael Biebl if (UNIT(a)->manager->running_as != SYSTEMD_SYSTEM)
b7e7184634d573fb73143210962acce205f37f61Michael Biebl r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
b7e7184634d573fb73143210962acce205f37f61Michael Biebl log_error_unit(UNIT(a)->id, "Cannot have an automount unit for the root directory. Refusing.");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen e = unit_name_from_path(a->where, ".automount");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen b = unit_has_name(UNIT(a), e);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error_unit(UNIT(a)->id, "%s's Where setting doesn't match unit name. Refusing.", UNIT(a)->id);
77354c7e6f096a447245a8781c1eaa4acbe67089Martin Pitt /* Load a .automount file */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_load_fragment_and_dropin_optional(u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (u->load_state == UNIT_LOADED) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen a->where = unit_name_to_path(u->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_load_related_unit(u, ".mount", &x);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, x, true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = automount_add_mount_links(a);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (UNIT(a)->default_dependencies) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = automount_add_default_dependencies(a);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void automount_set_state(Automount *a, AutomountState state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (state != AUTOMOUNT_WAITING &&
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s changed %s -> %s",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen automount_state_to_string(old_state),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen automount_state_to_string(state));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_notify(UNIT(a), state_translation_table[old_state], state_translation_table[state], true);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int automount_coldplug(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(a->state == AUTOMOUNT_DEAD);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (a->deserialized_state != a->state) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = open_dev_autofs(u->manager);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (a->deserialized_state == AUTOMOUNT_WAITING ||
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen a->deserialized_state == AUTOMOUNT_RUNNING) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen automount_set_state(a, a->deserialized_state);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void automount_dump(Unit *u, FILE *f, const char *prefix) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sAutomount State: %s\n"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%sDirectoryMode: %04o\n",
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering prefix, automount_state_to_string(a->state),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen prefix, automount_result_to_string(a->result),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void automount_enter_dead(Automount *a, AutomountResult f) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen automount_set_state(a, a->result != AUTOMOUNT_SUCCESS ? AUTOMOUNT_FAILED : AUTOMOUNT_DEAD);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int open_dev_autofs(Manager *m) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen struct autofs_dev_ioctl param;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen label_fix("/dev/autofs", false, false);
4e4885553447f6f4c014bfa3e5b5837a76a0e612Lennart Poettering m->dev_autofs_fd = open("/dev/autofs", O_CLOEXEC|O_RDONLY);
3315f085178f46155fda345d9526c09083b45946Lennart Poettering log_error("Failed to open /dev/autofs: %m");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (ioctl(m->dev_autofs_fd, AUTOFS_DEV_IOCTL_VERSION, ¶m) < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug("Autofs kernel version %i.%i", param.ver_major, param.ver_minor);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int open_ioctl_fd(int dev_autofs_fd, const char *where, dev_t devid) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen struct autofs_dev_ioctl *param;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen l = sizeof(struct autofs_dev_ioctl) + strlen(where) + 1;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen init_autofs_dev_ioctl(param);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen param->openmount.devid = devid;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_OPENMOUNT, param) < 0)
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek fd_cloexec(param->ioctlfd, true);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmekstatic int autofs_protocol(int dev_autofs_fd, int ioctl_fd) {
e987f2a809c6bab7e7bae4ca8f598ea5bafd5225Zbigniew JÄ™drzejewski-Szmek if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOVER, ¶m) < 0)
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek major = param.protover.version;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew JÄ™drzejewski-Szmek if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_PROTOSUBVER, ¶m) < 0)
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek minor = param.protosubver.sub_version;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_debug("Autofs protocol version %i.%i", major, minor);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmekstatic int autofs_set_timeout(int dev_autofs_fd, int ioctl_fd, time_t sec) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew JÄ™drzejewski-Szmek if (ioctl(dev_autofs_fd, AUTOFS_DEV_IOCTL_TIMEOUT, ¶m) < 0)
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmekstatic int autofs_send_ready(int dev_autofs_fd, int ioctl_fd, uint32_t token, int status) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew JÄ™drzejewski-Szmek if (ioctl(dev_autofs_fd, status ? AUTOFS_DEV_IOCTL_FAIL : AUTOFS_DEV_IOCTL_READY, ¶m) < 0)
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmekint automount_send_ready(Automount *a, int status) {
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek _cleanup_close_ int ioctl_fd = -1;
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek ioctl_fd = open_ioctl_fd(UNIT(a)->manager->dev_autofs_fd, a->where, a->dev_id);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_debug_unit(UNIT(a)->id, "Sending failure: %s", strerror(-status));
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmek log_debug_unit(UNIT(a)->id, "Sending success.");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Autofs thankfully does not hand out 0 as a token */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen while ((token = PTR_TO_UINT(set_steal_first(a->tokens)))) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Autofs fun fact II:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * if you pass a positive status code here, the kernel will
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * freeze! Yay! */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen k = autofs_send_ready(UNIT(a)->manager->dev_autofs_fd,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void automount_enter_waiting(Automount *a) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_close_ int ioctl_fd = -1;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen dev_autofs_fd = open_dev_autofs(UNIT(a)->manager);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* We knowingly ignore the results of this call */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen mkdir_p_label(a->where, 0555);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen warn_if_dir_nonempty(a->meta.id, a->where);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (pipe2(p, O_NONBLOCK|O_CLOEXEC) < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen snprintf(options, sizeof(options), "fd=%i,pgrp=%u,minproto=5,maxproto=5,direct", p[1], (unsigned) getpgrp());
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen snprintf(name, sizeof(name), "systemd-%u", (unsigned) getpid());
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (mount(name, a->where, "autofs", 0, options) < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (stat(a->where, &st) < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen ioctl_fd = open_ioctl_fd(dev_autofs_fd, a->where, st.st_dev);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = autofs_protocol(dev_autofs_fd, ioctl_fd);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = autofs_set_timeout(dev_autofs_fd, ioctl_fd, 300);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Autofs fun fact:
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * Unless we close the ioctl fd here, for some weird reason
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * the direct mount will not receive events from the
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen automount_set_state(a, AUTOMOUNT_WAITING);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Failed to initialize automounter: %s", strerror(-r));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void automount_enter_runnning(Automount *a) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* We don't take mount requests anymore if we are supposed to
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen * shut down anyway */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (unit_stop_pending(UNIT(a))) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Suppressing automount request on %s since unit stop is scheduled.", UNIT(a)->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen automount_send_ready(a, -EHOSTDOWN);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen mkdir_p_label(a->where, a->directory_mode);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen /* Before we do anything, let's see if somebody is playing games with us? */
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (lstat(a->where, &st) < 0) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_warning_unit(UNIT(a)->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s failed to stat automount point: %m", UNIT(a)->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s's automount point already active?", UNIT(a)->id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen JOB_REPLACE, true, &error, NULL);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_warning_unit(UNIT(a)->id,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "%s failed to queue mount startup job: %s",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen UNIT(a)->id, bus_error_message(&error, r));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen automount_set_state(a, AUTOMOUNT_RUNNING);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
1e2fee5f757c0bb3a6fea216b1e10ee7b3c0e12eZbigniew Jędrzejewski-Szmekstatic int automount_start(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (path_is_mount_point(a->where, false)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen "Path %s is already a mount point, refusing start for %s",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen a->result = AUTOMOUNT_SUCCESS;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int automount_stop(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen assert(a->state == AUTOMOUNT_WAITING || a->state == AUTOMOUNT_RUNNING);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen automount_enter_dead(a, AUTOMOUNT_SUCCESS);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_serialize_item(u, f, "state", automount_state_to_string(a->state));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_serialize_item(u, f, "result", automount_result_to_string(a->result));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_serialize_item_format(u, f, "dev-id", "%u", (unsigned) a->dev_id);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_serialize_item_format(u, f, "token", "%u", PTR_TO_UINT(p));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen copy = fdset_put_dup(fds, a->pipe_fd);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int automount_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen state = automount_state_from_string(value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Failed to parse state value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen a->deserialized_state = state;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "result")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen f = automount_result_from_string(value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Failed to parse result value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen else if (f != AUTOMOUNT_SUCCESS)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "dev-id")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (safe_atou(value, &d) < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Failed to parse dev-id value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen a->dev_id = (unsigned) d;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "token")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (safe_atou(value, &token) < 0)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Failed to parse token value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (!(a->tokens = set_new(NULL)))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen r = set_put(a->tokens, UINT_TO_PTR(token));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen } else if (streq(key, "pipe-fd")) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen if (safe_atoi(value, &fd) < 0 || fd < 0 || !fdset_contains(fds, fd))
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Failed to parse pipe-fd value %s", value);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen a->pipe_fd = fdset_remove(fds, fd);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_debug_unit(u->id, "Unknown serialization key '%s'", key);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic UnitActiveState automount_active_state(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return state_translation_table[AUTOMOUNT(u)->state];
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic const char *automount_sub_state_to_string(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return automount_state_to_string(AUTOMOUNT(u)->state);
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmekstatic bool automount_check_gc(Unit *u) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen return UNIT_VTABLE(UNIT_TRIGGER(u))->check_gc(UNIT_TRIGGER(u));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen Automount *a = AUTOMOUNT(userdata);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error_unit(UNIT(a)->id, "Got invalid poll event on pipe.");
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering l = loop_read(a->pipe_fd, &packet, sizeof(packet), true);
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering if (l != sizeof(packet)) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error_unit(UNIT(a)->id, "Invalid read from pipe: %s", l < 0 ? strerror(-l) : "short read");
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen _cleanup_free_ char *p = NULL;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen get_process_comm(packet.v5_packet.pid, &p);
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering "Got automount request for %s, triggered by "PID_FMT" (%s)",
a986501b9059b72e8deced262554fbdd1ab9da17Lennart Poettering a->where, packet.v5_packet.pid, strna(p));
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering log_debug_unit(UNIT(a)->id, "Got direct mount request on %s", a->where);
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering r = set_ensure_allocated(&a->tokens, NULL);
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek log_error_unit(UNIT(a)->id, "Failed to allocate token set.");
f4f01ec146d91cb6943828851d98eee6a1ad4dd9Martin Pitt r = set_put(a->tokens, UINT_TO_PTR(packet.v5_packet.wait_queue_token));
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen log_error_unit(UNIT(a)->id, "Failed to remember token: %s", strerror(-r));
805e5dda0a01c99d231824e1a9c4a208418bf342Lennart Poettering log_error_unit(UNIT(a)->id, "Received unknown automount request %i", packet.hdr.type);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmekstatic void automount_shutdown(Manager *m) {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen m->dev_autofs_fd = safe_close(m->dev_autofs_fd);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic void automount_reset_failed(Unit *u) {
a8ffe6fbcbfdba39aef8dce8b298b3e0cb377c0eZbigniew Jędrzejewski-Szmek if (a->state == AUTOMOUNT_FAILED)
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen automount_set_state(a, AUTOMOUNT_DEAD);
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen a->result = AUTOMOUNT_SUCCESS;
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersenstatic const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [AUTOMOUNT_WAITING] = "waiting",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [AUTOMOUNT_RUNNING] = "running",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [AUTOMOUNT_FAILED] = "failed"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel AndersenDEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
56f64d95763a799ba4475daf44d8e9f72a1bd474Michal Schmidtstatic const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [AUTOMOUNT_SUCCESS] = "success",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel AndersenDEFINE_STRING_TABLE_LOOKUP(automount_result, AutomountResult);
7a03974a6f4510dcb1850515a80c2063c767a80fThomas Hindoe Paaboel Andersenconst UnitVTable automount_vtable = {
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .object_size = sizeof(Automount),
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .coldplug = automount_coldplug,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .serialize = automount_serialize,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .deserialize_item = automount_deserialize_item,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .active_state = automount_active_state,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .sub_state_to_string = automount_sub_state_to_string,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .check_gc = automount_check_gc,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .reset_failed = automount_reset_failed,
8c84621c25c563c7428f3d355136fc542389aab8Thomas Hindoe Paaboel Andersen .bus_interface = "org.freedesktop.systemd1.Automount",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen .shutdown = automount_shutdown,
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [JOB_DONE] = "Set up automount %s.",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [JOB_FAILED] = "Failed to set up automount %s.",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [JOB_DEPENDENCY] = "Dependency failed for %s.",
95ed3294c632f5606327149f10cef1eb34422862Thomas Hindoe Paaboel Andersen [JOB_DONE] = "Unset automount %s.",
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt [JOB_FAILED] = "Failed to unset automount %s.",