automount.c revision 7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster This file is part of systemd.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Copyright 2010 Lennart Poettering
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster systemd is free software; you can redistribute it and/or modify it
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster under the terms of the GNU Lesser General Public License as published by
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster the Free Software Foundation; either version 2.1 of the License, or
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster (at your option) any later version.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster systemd is distributed in the hope that it will be useful, but
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster WITHOUT ANY WARRANTY; without even the implied warranty of
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster Lesser General Public License for more details.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster You should have received a copy of the GNU Lesser General Public License
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster along with systemd; If not, see <http://www.gnu.org/licenses/>.
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic inline void expire_data_free(struct expire_data *data) {
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan FosterDEFINE_TRIVIAL_CLEANUP_FUNC(struct expire_data*, expire_data_free);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* If there are multiple mounts on a mount point, this
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster * removes them all */
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster log_error_errno(errno, "Failed to unmount: %m");
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Fosterstatic int automount_send_ready(Automount *a, Set *tokens, int status);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster automount_send_ready(a, a->tokens, -EHOSTDOWN);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster automount_send_ready(a, a->expire_tokens, -EHOSTDOWN);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster a->pipe_event_source = sd_event_source_unref(a->pipe_event_source);
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster /* If we reload/reexecute things we keep the mount point
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster (UNIT(a)->manager->exit_code != MANAGER_RELOAD &&
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster UNIT(a)->manager->exit_code != MANAGER_REEXECUTE))
a688bcbb4bcff5398fdd29b86f83450257dc0df4Allan Foster a->expire_event_source = sd_event_source_unref(a->expire_event_source);
assert(a);
assert(a);
r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true);
assert(a);
return -EINVAL;
return -ENOMEM;
return -EINVAL;
assert(u);
Unit *x;
if (!a->where) {
if (!a->where)
return -ENOMEM;
r = automount_add_mount_links(a);
return automount_verify(a);
assert(a);
unmount_autofs(a);
assert(a);
r = sd_event_add_io(u->manager->event, &a->pipe_event_source, a->pipe_fd, EPOLLIN, automount_dispatch_io, u);
assert(a);
fprintf(f,
assert(a);
if (f != AUTOMOUNT_SUCCESS)
a->result = f;
assert(m);
if (m->dev_autofs_fd >= 0)
return m->dev_autofs_fd;
if (m->dev_autofs_fd < 0)
return -errno;
return m->dev_autofs_fd;
size_t l;
return -errno;
return -EIO;
return -errno;
return -errno;
return -errno;
if (status) {
return -errno;
unsigned token;
assert(a);
if (ioctl_fd < 0)
return ioctl_fd;
if (status)
status);
assert(a);
switch (state) {
case MOUNT_MOUNTED:
case MOUNT_REMOUNTING:
case MOUNT_DEAD:
case MOUNT_UNMOUNTING:
case MOUNT_MOUNTING_SIGTERM:
case MOUNT_MOUNTING_SIGKILL:
case MOUNT_REMOUNTING_SIGTERM:
case MOUNT_REMOUNTING_SIGKILL:
case MOUNT_UNMOUNTING_SIGTERM:
case MOUNT_UNMOUNTING_SIGKILL:
case MOUNT_FAILED:
switch (state) {
case MOUNT_DEAD:
case MOUNT_MOUNTING:
case MOUNT_MOUNTING_DONE:
case MOUNT_MOUNTING_SIGTERM:
case MOUNT_MOUNTING_SIGKILL:
case MOUNT_REMOUNTING_SIGTERM:
case MOUNT_REMOUNTING_SIGKILL:
case MOUNT_UNMOUNTING_SIGTERM:
case MOUNT_UNMOUNTING_SIGKILL:
case MOUNT_FAILED:
bool mounted = false;
int r, dev_autofs_fd;
assert(a);
if (a->tokens)
if (dev_autofs_fd < 0) {
r = dev_autofs_fd;
goto fail;
r = -errno;
goto fail;
r = -errno;
goto fail;
mounted = true;
r = -errno;
goto fail;
if (ioctl_fd < 0) {
r = ioctl_fd;
goto fail;
goto fail;
goto fail;
r = sd_event_add_io(UNIT(a)->manager->event, &a->pipe_event_source, p[0], EPOLLIN, automount_dispatch_io, a);
goto fail;
a->pipe_fd = p[0];
fail:
safe_close_pair(p);
if (mounted)
static void *expire_thread(void *p) {
return NULL;
assert(a);
if (!data)
return log_oom();
return automount_start_expire(a);
assert(a);
if (a->expire_event_source) {
r = sd_event_add_time(
&a->expire_event_source,
assert(a);
goto fail;
goto fail;
r = automount_start_expire(a);
fail:
assert(a);
return -EEXIST;
return -ENOENT;
assert(a);
Iterator i;
assert(a);
assert(f);
if (a->pipe_fd >= 0) {
int copy;
if (copy < 0)
return copy;
assert(a);
if (state < 0)
else if (f != AUTOMOUNT_SUCCESS)
a->result = f;
a->dev_id = (unsigned) d;
unsigned token;
log_oom();
unsigned token;
log_oom();
int fd;
assert(u);
assert(u);
assert(u);
if (!UNIT_TRIGGER(u))
assert(a);
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
goto fail;
r = manager_add_job(UNIT(a)->manager, JOB_STOP, UNIT_TRIGGER(UNIT(a)), JOB_REPLACE, true, &error, NULL);
goto fail;
fail:
assert(m);
assert(a);
assert(m);
if (supported < 0)
return supported;
.sections =
.no_alias = true,
.no_instances = true,
.finished_start_job = {
.finished_stop_job = {