chiark / gitweb /
socket: optionally call accept() for incoming connections and spawn one service insta...
[elogind.git] / mount.c
diff --git a/mount.c b/mount.c
index d52c11d3cabd9d7f15bef62589c85ff18474eb22..597df9e614fe289893a501247da57ad5cc6a3f8d 100644 (file)
--- a/mount.c
+++ b/mount.c
@@ -32,6 +32,7 @@
 #include "log.h"
 #include "strv.h"
 #include "mount-setup.h"
+#include "unit-name.h"
 
 static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
         [MOUNT_DEAD] = UNIT_INACTIVE,
@@ -65,6 +66,16 @@ static const char* const state_string_table[_MOUNT_STATE_MAX] = {
         [MOUNT_MAINTAINANCE] = "maintainance"
 };
 
+static void service_unwatch_control_pid(Mount *m) {
+        assert(m);
+
+        if (m->control_pid <= 0)
+                return;
+
+        unit_unwatch_pid(UNIT(m), m->control_pid);
+        m->control_pid = 0;
+}
+
 static void mount_parameters_done(MountParameters *p) {
         assert(p);
 
@@ -91,10 +102,7 @@ static void mount_done(Unit *u) {
         exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
         m->control_command = NULL;
 
-        if (m->control_pid > 0) {
-                unit_unwatch_pid(u, m->control_pid);
-                m->control_pid = 0;
-        }
+        service_unwatch_control_pid(m);
 
         unit_unwatch_timer(u, &m->timer_watch);
 }
@@ -149,10 +157,10 @@ static int mount_add_node_links(Mount *m) {
         if (!path_startswith(what, "/dev/"))
                 return 0;
 
-        if (!(e = unit_name_escape_path(what+1, ".device")))
+        if (!(e = unit_name_build_escape(what+1, NULL, ".device")))
                 return -ENOMEM;
 
-        r = manager_load_unit(UNIT(m)->meta.manager, e, &device);
+        r = manager_load_unit(UNIT(m)->meta.manager, e, NULL, &device);
         free(e);
 
         if (r < 0)
@@ -237,6 +245,8 @@ static int mount_add_target_links(Mount *m) {
         MountParameters *p;
         Unit *u;
         int r;
+        bool noauto;
+        bool handle;
 
         assert(m);
 
@@ -247,10 +257,10 @@ static int mount_add_target_links(Mount *m) {
         else
                 return 0;
 
-        if (!p->fstype)
-                return 0;
+        noauto = mount_test_option(p->options, MNTOPT_NOAUTO);
+        handle = mount_test_option(p->options, "comment=systemd.mount");
 
-        if (mount_test_option(p->options, MNTOPT_NOAUTO))
+        if (noauto && !handle)
                 return 0;
 
         if (mount_test_option(p->options, "_netdev") ||
@@ -259,11 +269,12 @@ static int mount_add_target_links(Mount *m) {
         else
                 target = SPECIAL_LOCAL_FS_TARGET;
 
-        if ((r = manager_load_unit(UNIT(m)->meta.manager, target, &u)) < 0)
+        if ((r = manager_load_unit(UNIT(m)->meta.manager, target, NULL, &u)) < 0)
                 return r;
 
-        if ((r = unit_add_dependency(u, UNIT_WANTS, UNIT(m))) < 0)
-                return r;
+        if (handle)
+                if ((r = unit_add_dependency(u, UNIT_WANTS, UNIT(m))) < 0)
+                        return r;
 
         return unit_add_dependency(UNIT(m), UNIT_BEFORE, u);
 }
@@ -322,17 +333,12 @@ static void mount_set_state(Mount *m, MountState state) {
             state != MOUNT_REMOUNTING_SIGTERM &&
             state != MOUNT_REMOUNTING_SIGKILL) {
                 unit_unwatch_timer(UNIT(m), &m->timer_watch);
-
-                if (m->control_pid > 0) {
-                        unit_unwatch_pid(UNIT(m), m->control_pid);
-                        m->control_pid = 0;
-                }
-
+                service_unwatch_control_pid(m);
                 m->control_command = NULL;
         }
 
         if (state != old_state)
-                log_debug("%s changed %s → %s", unit_id(UNIT(m)), state_string_table[old_state], state_string_table[state]);
+                log_debug("%s changed %s → %s", UNIT(m)->meta.id, state_string_table[old_state], state_string_table[state]);
 
         unit_notify(UNIT(m), state_translation_table[old_state], state_translation_table[state]);
 }
@@ -361,10 +367,12 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
                 goto fail;
 
         if ((r = exec_spawn(c,
+                            NULL,
                             &m->exec_context,
                             NULL, 0,
                             true,
                             true,
+                            UNIT(m)->meta.manager->confirm_spawn,
                             UNIT(m)->meta.cgroup_bondings,
                             &pid)) < 0)
                 goto fail;
@@ -434,21 +442,28 @@ static void mount_enter_dead(Mount *m, bool success) {
         mount_set_state(m, m->failure ? MOUNT_MAINTAINANCE : MOUNT_DEAD);
 }
 
+static void mount_enter_mounted(Mount *m, bool success) {
+        assert(m);
+
+        if (!success)
+                m->failure = true;
+
+        mount_set_state(m, MOUNT_MOUNTED);
+}
+
 static void mount_enter_signal(Mount *m, MountState state, bool success) {
         int r;
+        bool sent = false;
 
         assert(m);
 
         if (!success)
                 m->failure = true;
 
-        if (m->control_pid > 0) {
-                int sig;
-                bool sent = false;
-
-                sig = (state == MOUNT_MOUNTING_SIGTERM ||
-                       state == MOUNT_UNMOUNTING_SIGTERM ||
-                       state == MOUNT_REMOUNTING_SIGTERM) ? SIGTERM : SIGKILL;
+        if (m->kill_mode != KILL_NONE) {
+                int sig = (state == MOUNT_MOUNTING_SIGTERM ||
+                           state == MOUNT_UNMOUNTING_SIGTERM ||
+                           state == MOUNT_REMOUNTING_SIGTERM) ? SIGTERM : SIGKILL;
 
                 if (m->kill_mode == KILL_CONTROL_GROUP) {
 
@@ -459,32 +474,32 @@ static void mount_enter_signal(Mount *m, MountState state, bool success) {
                                 sent = true;
                 }
 
-                if (!sent)
+                if (!sent && m->control_pid > 0)
                         if (kill(m->kill_mode == KILL_PROCESS ? m->control_pid : -m->control_pid, sig) < 0 && errno != ESRCH) {
                                 r = -errno;
                                 goto fail;
                         }
         }
 
-        mount_set_state(m, state);
+        if (sent) {
+                if ((r = unit_watch_timer(UNIT(m), m->timeout_usec, &m->timer_watch)) < 0)
+                        goto fail;
 
-        if (m->control_pid <= 0)
+                mount_set_state(m, state);
+        } else if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
+                mount_enter_mounted(m, true);
+        else
                 mount_enter_dead(m, true);
 
         return;
 
 fail:
-        log_warning("%s failed to kill processes: %s", unit_id(UNIT(m)), strerror(-r));
-        mount_enter_dead(m, false);
-}
-
-static void mount_enter_mounted(Mount *m, bool success) {
-        assert(m);
-
-        if (!success)
-                m->failure = true;
+        log_warning("%s failed to kill processes: %s", UNIT(m)->meta.id, strerror(-r));
 
-        mount_set_state(m, MOUNT_MOUNTED);
+        if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
+                mount_enter_mounted(m, false);
+        else
+                mount_enter_dead(m, false);
 }
 
 static void mount_enter_unmounting(Mount *m, bool success) {
@@ -505,6 +520,8 @@ static void mount_enter_unmounting(Mount *m, bool success) {
                              NULL)) < 0)
                 goto fail;
 
+        service_unwatch_control_pid(m);
+
         if ((r = mount_spawn(m, c, &m->control_pid)) < 0)
                 goto fail;
 
@@ -513,7 +530,7 @@ static void mount_enter_unmounting(Mount *m, bool success) {
         return;
 
 fail:
-        log_warning("%s failed to run umount exectuable: %s", unit_id(UNIT(m)), strerror(-r));
+        log_warning("%s failed to run umount exectuable: %s", UNIT(m)->meta.id, strerror(-r));
         mount_enter_mounted(m, false);
 }
 
@@ -549,6 +566,8 @@ static void mount_enter_mounting(Mount *m, bool success) {
         if (r < 0)
                 goto fail;
 
+        service_unwatch_control_pid(m);
+
         if ((r = mount_spawn(m, c, &m->control_pid)) < 0)
                 goto fail;
 
@@ -557,7 +576,7 @@ static void mount_enter_mounting(Mount *m, bool success) {
         return;
 
 fail:
-        log_warning("%s failed to run mount exectuable: %s", unit_id(UNIT(m)), strerror(-r));
+        log_warning("%s failed to run mount exectuable: %s", UNIT(m)->meta.id, strerror(-r));
         mount_enter_dead(m, false);
 }
 
@@ -620,6 +639,8 @@ static void mount_enter_remounting(Mount *m, bool success) {
                 goto fail;
         }
 
+        service_unwatch_control_pid(m);
+
         if ((r = mount_spawn(m, c, &m->control_pid)) < 0)
                 goto fail;
 
@@ -704,6 +725,12 @@ static UnitActiveState mount_active_state(Unit *u) {
         return state_translation_table[MOUNT(u)->state];
 }
 
+static const char *mount_sub_state_to_string(Unit *u) {
+        assert(u);
+
+        return state_string_table[MOUNT(u)->state];
+}
+
 static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         Mount *m = MOUNT(u);
         bool success;
@@ -720,7 +747,7 @@ static void mount_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         exec_status_fill(&m->control_command->exec_status, pid, code, status);
         m->control_pid = 0;
 
-        log_debug("%s control process exited, code=%s status=%i", unit_id(u), sigchld_code_to_string(code), status);
+        log_debug("%s control process exited, code=%s status=%i", u->meta.id, sigchld_code_to_string(code), status);
 
         /* Note that mount(8) returning and the kernel sending us a
          * mount table change event might happen out-of-order. If an
@@ -775,39 +802,39 @@ static void mount_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
 
         case MOUNT_MOUNTING:
         case MOUNT_MOUNTING_DONE:
-                log_warning("%s mounting timed out. Stopping.", unit_id(u));
+                log_warning("%s mounting timed out. Stopping.", u->meta.id);
                 mount_enter_signal(m, MOUNT_MOUNTING_SIGTERM, false);
                 break;
 
         case MOUNT_REMOUNTING:
-                log_warning("%s remounting timed out. Stopping.", unit_id(u));
+                log_warning("%s remounting timed out. Stopping.", u->meta.id);
                 mount_enter_signal(m, MOUNT_REMOUNTING_SIGTERM, false);
                 break;
 
         case MOUNT_UNMOUNTING:
-                log_warning("%s unmounting timed out. Stopping.", unit_id(u));
+                log_warning("%s unmounting timed out. Stopping.", u->meta.id);
                 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGTERM, false);
                 break;
 
         case MOUNT_MOUNTING_SIGTERM:
-                log_warning("%s mounting timed out. Killing.", unit_id(u));
+                log_warning("%s mounting timed out. Killing.", u->meta.id);
                 mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, false);
                 break;
 
         case MOUNT_REMOUNTING_SIGTERM:
-                log_warning("%s remounting timed out. Killing.", unit_id(u));
+                log_warning("%s remounting timed out. Killing.", u->meta.id);
                 mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, false);
                 break;
 
         case MOUNT_UNMOUNTING_SIGTERM:
-                log_warning("%s unmounting timed out. Killing.", unit_id(u));
+                log_warning("%s unmounting timed out. Killing.", u->meta.id);
                 mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, false);
                 break;
 
         case MOUNT_MOUNTING_SIGKILL:
         case MOUNT_REMOUNTING_SIGKILL:
         case MOUNT_UNMOUNTING_SIGKILL:
-                log_warning("%s mount process still around after SIGKILL. Ignoring.", unit_id(u));
+                log_warning("%s mount process still around after SIGKILL. Ignoring.", u->meta.id);
 
                 if (m->from_proc_self_mountinfo)
                         mount_enter_mounted(m, false);
@@ -854,7 +881,7 @@ static int mount_add_one(
         if (streq(where, "/"))
                 e = strdup("-.mount");
         else
-                e = unit_name_escape_path(where+1, ".mount");
+                e = unit_name_build_escape(where+1, NULL, ".mount");
 
         if (!e)
                 return -ENOMEM;
@@ -1220,7 +1247,7 @@ int mount_path_is_mounted(Manager *m, const char* path) {
                 char *e, *slash;
                 Unit *u;
 
-                if (!(e = unit_name_escape_path(t+1, ".mount"))) {
+                if (!(e = unit_name_build_escape(t+1, NULL, ".mount"))) {
                         r = -ENOMEM;
                         goto finish;
                 }
@@ -1256,6 +1283,7 @@ const UnitVTable mount_vtable = {
         .suffix = ".mount",
 
         .no_alias = true,
+        .no_instances = true,
 
         .init = mount_init,
         .load = mount_load,
@@ -1270,6 +1298,7 @@ const UnitVTable mount_vtable = {
         .reload = mount_reload,
 
         .active_state = mount_active_state,
+        .sub_state_to_string = mount_sub_state_to_string,
 
         .sigchld_event = mount_sigchld_event,
         .timer_event = mount_timer_event,