chiark / gitweb /
udev: really exclude device-mapper from block device ownership event locking
[elogind.git] / src / core / mount.c
index 90da88382606593d2c38d51c4b42c42b10bc76f3..14ac0a060e5bd8ef33bc67b0157ae7629d3a8b45 100644 (file)
@@ -62,20 +62,6 @@ static const UnitActiveState state_translation_table[_MOUNT_STATE_MAX] = {
 static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
 static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
 
-static char* mount_test_option(const char *haystack, const char *needle) {
-        struct mntent me = { .mnt_opts = (char*) haystack };
-
-        assert(needle);
-
-        /* Like glibc's hasmntopt(), but works on a string, not a
-         * struct mntent */
-
-        if (!haystack)
-                return NULL;
-
-        return hasmntopt(&me, needle);
-}
-
 static bool mount_is_network(MountParameters *p) {
         assert(p);
 
@@ -137,10 +123,6 @@ static void mount_init(Unit *u) {
         m->timeout_usec = u->manager->default_timeout_start_usec;
         m->directory_mode = 0755;
 
-        exec_context_init(&m->exec_context);
-        kill_context_init(&m->kill_context);
-        cgroup_context_init(&m->cgroup_context);
-
         if (unit_has_name(u, "-.mount")) {
                 /* Don't allow start/stop for root directory */
                 u->refuse_manual_start = true;
@@ -181,7 +163,12 @@ static int mount_arm_timer(Mount *m) {
                 return sd_event_source_set_enabled(m->timer_event_source, SD_EVENT_ONESHOT);
         }
 
-        return sd_event_add_monotonic(UNIT(m)->manager->event, now(CLOCK_MONOTONIC) + m->timeout_usec, 0, mount_dispatch_timer, m, &m->timer_event_source);
+        return sd_event_add_time(
+                        UNIT(m)->manager->event,
+                        &m->timer_event_source,
+                        CLOCK_MONOTONIC,
+                        now(CLOCK_MONOTONIC) + m->timeout_usec, 0,
+                        mount_dispatch_timer, m);
 }
 
 static void mount_unwatch_control_pid(Mount *m) {
@@ -215,8 +202,6 @@ static void mount_done(Unit *u) {
         mount_parameters_done(&m->parameters_proc_self_mountinfo);
         mount_parameters_done(&m->parameters_fragment);
 
-        cgroup_context_done(&m->cgroup_context);
-        exec_context_done(&m->exec_context);
         m->exec_runtime = exec_runtime_unref(m->exec_runtime);
         exec_command_done_array(m->exec_command, _MOUNT_EXEC_COMMAND_MAX);
         m->control_command = NULL;
@@ -541,10 +526,6 @@ static int mount_add_extras(Mount *m) {
 
         path_kill_slashes(m->where);
 
-        r = unit_add_exec_dependencies(u, &m->exec_context);
-        if (r < 0)
-                return r;
-
         if (!u->description) {
                 r = unit_set_description(u, m->where);
                 if (r < 0)
@@ -563,24 +544,28 @@ static int mount_add_extras(Mount *m) {
         if (r < 0)
                 return r;
 
-        if (u->default_dependencies) {
-                r = mount_add_default_dependencies(m);
-                if (r < 0)
-                        return r;
-        }
+        r = unit_patch_contexts(u);
+        if (r < 0)
+                return r;
 
-        r = unit_add_default_slice(u);
+        r = unit_add_exec_dependencies(u, &m->exec_context);
         if (r < 0)
                 return r;
 
-        r = mount_fix_timeouts(m);
+        r = unit_add_default_slice(u, &m->cgroup_context);
         if (r < 0)
                 return r;
 
-        r = unit_exec_context_defaults(u, &m->exec_context);
+        r = mount_fix_timeouts(m);
         if (r < 0)
                 return r;
 
+        if (u->default_dependencies) {
+                r = mount_add_default_dependencies(m);
+                if (r < 0)
+                        return r;
+        }
+
         return 0;
 }
 
@@ -786,6 +771,7 @@ static int mount_spawn(Mount *m, ExecCommand *c, pid_t *_pid) {
                        UNIT(m)->manager->confirm_spawn,
                        UNIT(m)->manager->cgroup_supported,
                        UNIT(m)->cgroup_path,
+                       manager_get_runtime_prefix(UNIT(m)->manager),
                        UNIT(m)->id,
                        0,
                        NULL,
@@ -818,6 +804,8 @@ static void mount_enter_dead(Mount *m, MountResult f) {
         exec_runtime_destroy(m->exec_runtime);
         m->exec_runtime = exec_runtime_unref(m->exec_runtime);
 
+        exec_context_destroy_runtime_directory(&m->exec_context, manager_get_runtime_prefix(UNIT(m)->manager));
+
         mount_set_state(m, m->result != MOUNT_SUCCESS ? MOUNT_FAILED : MOUNT_DEAD);
 }
 
@@ -854,8 +842,14 @@ static void mount_enter_signal(Mount *m, MountState state, MountResult f) {
                         goto fail;
 
                 mount_set_state(m, state);
-        } else if (state == MOUNT_REMOUNTING_SIGTERM || state == MOUNT_REMOUNTING_SIGKILL)
+        } else if (state == MOUNT_REMOUNTING_SIGTERM)
+                mount_enter_signal(m, MOUNT_REMOUNTING_SIGKILL, MOUNT_SUCCESS);
+        else if (state == MOUNT_REMOUNTING_SIGKILL)
                 mount_enter_mounted(m, MOUNT_SUCCESS);
+        else if (state == MOUNT_MOUNTING_SIGTERM)
+                mount_enter_signal(m, MOUNT_MOUNTING_SIGKILL, MOUNT_SUCCESS);
+        else if (state == MOUNT_UNMOUNTING_SIGTERM)
+                mount_enter_signal(m, MOUNT_UNMOUNTING_SIGKILL, MOUNT_SUCCESS);
         else
                 mount_enter_dead(m, MOUNT_SUCCESS);
 
@@ -1382,7 +1376,7 @@ static int mount_add_one(
         _cleanup_free_ char *e = NULL, *w = NULL, *o = NULL, *f = NULL;
         bool load_extras = false;
         MountParameters *p;
-        bool delete;
+        bool delete, changed = false;
         Unit *u;
         int r;
 
@@ -1450,6 +1444,7 @@ static int mount_add_one(
                 }
 
                 unit_add_to_load_queue(u);
+                changed = true;
         } else {
                 delete = false;
 
@@ -1468,21 +1463,29 @@ static int mount_add_one(
                         /* Load in the extras later on, after we
                          * finished initialization of the unit */
                         load_extras = true;
+                        changed = true;
                 }
         }
 
-        if (!(w = strdup(what)) ||
-            !(o = strdup(options)) ||
-            !(f = strdup(fstype))) {
+        w = strdup(what);
+        o = strdup(options);
+        f = strdup(fstype);
+        if (!w || !o || !f) {
                 r = -ENOMEM;
                 goto fail;
         }
 
         p = &MOUNT(u)->parameters_proc_self_mountinfo;
+
+        changed = changed ||
+                !streq_ptr(p->options, options) ||
+                !streq_ptr(p->what, what) ||
+                !streq_ptr(p->fstype, fstype);
+
         if (set_flags) {
                 MOUNT(u)->is_mounted = true;
                 MOUNT(u)->just_mounted = !MOUNT(u)->from_proc_self_mountinfo;
-                MOUNT(u)->just_changed = !streq_ptr(p->options, o);
+                MOUNT(u)->just_changed = changed;
         }
 
         MOUNT(u)->from_proc_self_mountinfo = true;
@@ -1505,7 +1508,8 @@ static int mount_add_one(
                         goto fail;
         }
 
-        unit_add_to_dbus_queue(u);
+        if (changed)
+                unit_add_to_dbus_queue(u);
 
         return 0;
 
@@ -1606,7 +1610,7 @@ static int mount_enumerate(Manager *m) {
                 if (!m->proc_self_mountinfo)
                         return -errno;
 
-                r = sd_event_add_io(m->event, fileno(m->proc_self_mountinfo), EPOLLPRI, mount_dispatch_io, m, &m->mount_event_source);
+                r = sd_event_add_io(m->event, &m->mount_event_source, fileno(m->proc_self_mountinfo), EPOLLPRI, mount_dispatch_io, m);
                 if (r < 0)
                         goto fail;
 
@@ -1661,20 +1665,20 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
                 Mount *mount = MOUNT(u);
 
                 if (!mount->is_mounted) {
-                        /* This has just been unmounted. */
 
                         mount->from_proc_self_mountinfo = false;
 
                         switch (mount->state) {
 
                         case MOUNT_MOUNTED:
+                                /* This has just been unmounted by
+                                 * somebody else, follow the state
+                                 * change. */
                                 mount_enter_dead(mount, MOUNT_SUCCESS);
                                 break;
 
                         default:
-                                mount_set_state(mount, mount->state);
                                 break;
-
                         }
 
                 } else if (mount->just_mounted || mount->just_changed) {
@@ -1685,6 +1689,9 @@ static int mount_dispatch_io(sd_event_source *source, int fd, uint32_t revents,
 
                         case MOUNT_DEAD:
                         case MOUNT_FAILED:
+                                /* This has just been mounted by
+                                 * somebody else, follow the state
+                                 * change. */
                                 mount_enter_mounted(mount, MOUNT_SUCCESS);
                                 break;
 
@@ -1812,6 +1819,8 @@ const UnitVTable mount_vtable = {
 
         .get_timeout = mount_get_timeout,
 
+        .can_transient = true,
+
         .enumerate = mount_enumerate,
         .shutdown = mount_shutdown,