]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/automount.c
Merge pull request #2495 from heftig/master
[thirdparty/systemd.git] / src / core / automount.c
index 2b84c441b2b9cc9e3848754a6639b25841425920..772ec222ca6d87f20701d919af8f63b7137ca048 100644 (file)
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
 /***
   This file is part of systemd.
 
 ***/
 
 #include <errno.h>
-#include <limits.h>
-#include <sys/mount.h>
-#include <unistd.h>
 #include <fcntl.h>
+#include <limits.h>
+#include <linux/auto_dev-ioctl.h>
+#include <linux/auto_fs4.h>
 #include <sys/epoll.h>
+#include <sys/mount.h>
 #include <sys/stat.h>
-#include <linux/auto_fs4.h>
-#include <linux/auto_dev-ioctl.h>
+#include <unistd.h>
 
-#include "unit.h"
+#include "alloc-util.h"
+#include "async.h"
 #include "automount.h"
-#include "mount.h"
-#include "unit-name.h"
-#include "special.h"
+#include "bus-error.h"
+#include "bus-util.h"
+#include "dbus-automount.h"
+#include "fd-util.h"
+#include "formats-util.h"
+#include "io-util.h"
 #include "label.h"
 #include "mkdir.h"
+#include "mount-util.h"
+#include "mount.h"
+#include "parse-util.h"
 #include "path-util.h"
-#include "dbus-automount.h"
-#include "bus-util.h"
-#include "formats-util.h"
 #include "process-util.h"
-#include "async.h"
+#include "special.h"
+#include "stdio-util.h"
+#include "string-table.h"
+#include "string-util.h"
+#include "unit-name.h"
+#include "unit.h"
 
 static const UnitActiveState state_translation_table[_AUTOMOUNT_STATE_MAX] = {
         [AUTOMOUNT_DEAD] = UNIT_INACTIVE,
@@ -80,26 +87,11 @@ static void automount_init(Unit *u) {
         UNIT(a)->ignore_on_isolate = true;
 }
 
-static void repeat_unmount(const char *path) {
-        assert(path);
-
-        for (;;) {
-                /* If there are multiple mounts on a mount point, this
-                 * removes them all */
-
-                if (umount2(path, MNT_DETACH) >= 0)
-                        continue;
-
-                if (errno != EINVAL)
-                        log_error_errno(errno, "Failed to unmount: %m");
-
-                break;
-        }
-}
-
 static int automount_send_ready(Automount *a, Set *tokens, int status);
 
 static void unmount_autofs(Automount *a) {
+        int r;
+
         assert(a);
 
         if (a->pipe_fd < 0)
@@ -115,8 +107,11 @@ static void unmount_autofs(Automount *a) {
          * around */
         if (a->where &&
             (UNIT(a)->manager->exit_code != MANAGER_RELOAD &&
-             UNIT(a)->manager->exit_code != MANAGER_REEXECUTE))
-                repeat_unmount(a->where);
+             UNIT(a)->manager->exit_code != MANAGER_REEXECUTE)) {
+                r = repeat_unmount(a->where, MNT_DETACH);
+                if (r < 0)
+                        log_error_errno(r, "Failed to unmount: %m");
+        }
 }
 
 static void automount_done(Unit *u) {
@@ -126,26 +121,22 @@ static void automount_done(Unit *u) {
 
         unmount_autofs(a);
 
-        free(a->where);
-        a->where = NULL;
+        a->where = mfree(a->where);
 
-        set_free(a->tokens);
-        a->tokens = NULL;
-        set_free(a->expire_tokens);
-        a->expire_tokens = NULL;
+        a->tokens = set_free(a->tokens);
+        a->expire_tokens = set_free(a->expire_tokens);
 
         a->expire_event_source = sd_event_source_unref(a->expire_event_source);
 }
 
 static int automount_add_mount_links(Automount *a) {
         _cleanup_free_ char *parent = NULL;
-        int r;
 
         assert(a);
 
-        r = path_get_parent(a->where, &parent);
-        if (r < 0)
-                return r;
+        parent = dirname_malloc(a->where);
+        if (!parent)
+                return -ENOMEM;
 
         return unit_require_mounts_for(UNIT(a), parent);
 }
@@ -155,6 +146,9 @@ static int automount_add_default_dependencies(Automount *a) {
 
         assert(a);
 
+        if (!UNIT(a)->default_dependencies)
+                return 0;
+
         if (UNIT(a)->manager->running_as != MANAGER_SYSTEM)
                 return 0;
 
@@ -226,11 +220,9 @@ static int automount_load(Unit *u) {
                 if (r < 0)
                         return r;
 
-                if (UNIT(a)->default_dependencies) {
-                        r = automount_add_default_dependencies(a);
-                        if (r < 0)
-                                return r;
-                }
+                r = automount_add_default_dependencies(a);
+                if (r < 0)
+                        return r;
         }
 
         return automount_verify(a);
@@ -610,12 +602,16 @@ static void automount_enter_waiting(Automount *a) {
         return;
 
 fail:
+        log_unit_error_errno(UNIT(a), r, "Failed to initialize automounter: %m");
+
         safe_close_pair(p);
 
-        if (mounted)
-                repeat_unmount(a->where);
+        if (mounted) {
+                r = repeat_unmount(a->where, MNT_DETACH);
+                if (r < 0)
+                        log_error_errno(r, "Failed to unmount, ignoring: %m");
+        }
 
-        log_unit_error_errno(UNIT(a), r, "Failed to initialize automounter: %m");
         automount_enter_dead(a, AUTOMOUNT_FAILURE_RESOURCES);
 }
 
@@ -704,7 +700,7 @@ static int automount_start_expire(Automount *a) {
 }
 
 static void automount_enter_runnning(Automount *a) {
-        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         struct stat st;
         int r;
 
@@ -730,8 +726,7 @@ static void automount_enter_runnning(Automount *a) {
         if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id)
                 log_unit_info(UNIT(a), "Automount point already active?");
         else {
-                r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)),
-                                    JOB_REPLACE, true, &error, NULL);
+                r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)), JOB_REPLACE, &error, NULL);
                 if (r < 0) {
                         log_unit_warning(UNIT(a), "Failed to queue mount startup job: %s", bus_error_message(&error, r));
                         goto fail;
@@ -776,8 +771,9 @@ static int automount_stop(Unit *u) {
 
 static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
         Automount *a = AUTOMOUNT(u);
-        void *p;
         Iterator i;
+        void *p;
+        int r;
 
         assert(a);
         assert(f);
@@ -792,15 +788,9 @@ static int automount_serialize(Unit *u, FILE *f, FDSet *fds) {
         SET_FOREACH(p, a->expire_tokens, i)
                 unit_serialize_item_format(u, f, "expire-token", "%u", PTR_TO_UINT(p));
 
-        if (a->pipe_fd >= 0) {
-                int copy;
-
-                copy = fdset_put_dup(fds, a->pipe_fd);
-                if (copy < 0)
-                        return copy;
-
-                unit_serialize_item_format(u, f, "pipe-fd", "%i", copy);
-        }
+        r = unit_serialize_item_fd(u, f, fds, "pipe-fd", a->pipe_fd);
+        if (r < 0)
+                return r;
 
         return 0;
 }
@@ -905,7 +895,7 @@ static bool automount_check_gc(Unit *u) {
 }
 
 static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, void *userdata) {
-        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         union autofs_v5_packet_union packet;
         Automount *a = AUTOMOUNT(userdata);
         struct stat st;
@@ -981,7 +971,7 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo
                         break;
                 }
 
-                r = manager_add_job(UNIT(a)->manager, JOB_STOP, UNIT_TRIGGER(UNIT(a)), JOB_REPLACE, true, &error, NULL);
+                r = manager_add_job(UNIT(a)->manager, JOB_STOP, UNIT_TRIGGER(UNIT(a)), JOB_REPLACE, &error, NULL);
                 if (r < 0) {
                         log_unit_warning(UNIT(a), "Failed to queue umount startup job: %s", bus_error_message(&error, r));
                         goto fail;
@@ -1026,15 +1016,6 @@ static bool automount_supported(void) {
         return supported;
 }
 
-static const char* const automount_state_table[_AUTOMOUNT_STATE_MAX] = {
-        [AUTOMOUNT_DEAD] = "dead",
-        [AUTOMOUNT_WAITING] = "waiting",
-        [AUTOMOUNT_RUNNING] = "running",
-        [AUTOMOUNT_FAILED] = "failed"
-};
-
-DEFINE_STRING_TABLE_LOOKUP(automount_state, AutomountState);
-
 static const char* const automount_result_table[_AUTOMOUNT_RESULT_MAX] = {
         [AUTOMOUNT_SUCCESS] = "success",
         [AUTOMOUNT_FAILURE_RESOURCES] = "resources"
@@ -1074,7 +1055,6 @@ const UnitVTable automount_vtable = {
 
         .reset_failed = automount_reset_failed,
 
-        .bus_interface = "org.freedesktop.systemd1.Automount",
         .bus_vtable = bus_automount_vtable,
 
         .shutdown = automount_shutdown,