chiark / gitweb /
Rearrange Unit to make pahole happy
[elogind.git] / src / core / swap.c
index 9f353af430be489b9624b52d998760125259be4b..b2ca048bcbc0c23c3d476243b1e89e39dc3fb4b7 100644 (file)
@@ -77,7 +77,7 @@ static int swap_set_devnode(Swap *s, const char *devnode) {
 
         assert(s);
 
-        r = hashmap_ensure_allocated(&UNIT(s)->manager->swaps_by_devnode, string_hash_func, string_compare_func);
+        r = hashmap_ensure_allocated(&UNIT(s)->manager->swaps_by_devnode, &string_hash_ops);
         if (r < 0)
                 return r;
 
@@ -152,6 +152,9 @@ static void swap_done(Unit *u) {
         free(s->parameters_fragment.what);
         s->parameters_fragment.what = NULL;
 
+        free(s->parameters_fragment.discard);
+        s->parameters_fragment.discard = NULL;
+
         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
         exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
         s->control_command = NULL;
@@ -210,7 +213,7 @@ static int swap_add_device_links(Swap *s) {
 }
 
 static int swap_add_default_dependencies(Swap *s) {
-        bool nofail = false, noauto = false;
+        bool nofail, noauto;
         int r;
 
         assert(s);
@@ -225,23 +228,25 @@ static int swap_add_default_dependencies(Swap *s) {
         if (r < 0)
                 return r;
 
-        if (s->from_fragment) {
-                SwapParameters *p = &s->parameters_fragment;
+        if (!s->from_fragment)
+                /* The swap unit can either be for an alternative device name, in which
+                 * case we don't need to add the dependency on swap.target because this unit
+                 * is following a different unit which will have this dependency added,
+                 * or it can be derived from /proc/swaps, in which case it was started
+                 * manually, and should not become a dependency of swap.target. */
+                return 0;
 
-                nofail = p->nofail;
-                noauto = p->noauto;
-        }
+        nofail = s->parameters_fragment.nofail;
+        noauto = s->parameters_fragment.noauto;
 
         if (!noauto) {
                 if (nofail)
                         r = unit_add_dependency_by_name_inverse(UNIT(s), UNIT_WANTS, SPECIAL_SWAP_TARGET, NULL, true);
                 else
                         r = unit_add_two_dependencies_by_name_inverse(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SWAP_TARGET, NULL, true);
-                if (r < 0)
-                        return r;
         }
 
-        return 0;
+        return r < 0 ? r : 0;
 }
 
 static int swap_verify(Swap *s) {
@@ -602,10 +607,12 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
                 fprintf(f,
                         "%sPriority: %i\n"
                         "%sNoAuto: %s\n"
-                        "%sNoFail: %s\n",
+                        "%sNoFail: %s\n"
+                        "%sDiscard: %s\n",
                         prefix, p->priority,
                         prefix, yes_no(p->noauto),
-                        prefix, yes_no(p->nofail));
+                        prefix, yes_no(p->nofail),
+                        prefix, p->discard ?: "none");
 
         if (s->control_pid > 0)
                 fprintf(f,
@@ -619,6 +626,11 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
 static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
         pid_t pid;
         int r;
+        ExecParameters exec_params = {
+                .apply_permissions = true,
+                .apply_chroot      = true,
+                .apply_tty_stdin   = true,
+        };
 
         assert(s);
         assert(c);
@@ -634,21 +646,16 @@ static int swap_spawn(Swap *s, ExecCommand *c, pid_t *_pid) {
         if (r < 0)
                 goto fail;
 
+        exec_params.environment = UNIT(s)->manager->environment;
+        exec_params.confirm_spawn = UNIT(s)->manager->confirm_spawn;
+        exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
+        exec_params.cgroup_path = UNIT(s)->cgroup_path;
+        exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
+        exec_params.unit_id = UNIT(s)->id;
+
         r = exec_spawn(c,
-                       NULL,
                        &s->exec_context,
-                       NULL, 0,
-                       UNIT(s)->manager->environment,
-                       true,
-                       true,
-                       true,
-                       UNIT(s)->manager->confirm_spawn,
-                       UNIT(s)->manager->cgroup_supported,
-                       UNIT(s)->cgroup_path,
-                       manager_get_runtime_prefix(UNIT(s)->manager),
-                       UNIT(s)->id,
-                       0,
-                       NULL,
+                       &exec_params,
                        s->exec_runtime,
                        &pid);
         if (r < 0)
@@ -734,36 +741,46 @@ fail:
 
 static void swap_enter_activating(Swap *s) {
         int r, priority;
+        char *discard;
 
         assert(s);
 
         s->control_command_id = SWAP_EXEC_ACTIVATE;
         s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
 
-        if (s->from_fragment)
+        if (s->from_fragment) {
                 priority = s->parameters_fragment.priority;
-        else
+                discard = s->parameters_fragment.discard;
+        } else {
                 priority = -1;
+                discard = NULL;
+        }
+
+        r = exec_command_set(s->control_command, "/sbin/swapon", NULL);
+        if (r < 0)
+                goto fail;
 
         if (priority >= 0) {
                 char p[DECIMAL_STR_MAX(int)];
 
                 sprintf(p, "%i", priority);
+                r = exec_command_append(s->control_command, "-p", p, NULL);
+                if (r < 0)
+                        goto fail;
+        }
 
-                r = exec_command_set(
-                                s->control_command,
-                                "/sbin/swapon",
-                                "-p",
-                                p,
-                                s->what,
-                                NULL);
-        } else
-                r = exec_command_set(
-                                s->control_command,
-                                "/sbin/swapon",
-                                s->what,
-                                NULL);
+        if (discard && !streq(discard, "none")) {
+                const char *discard_arg = "--discard";
+
+                if (!streq(discard, "all"))
+                        discard_arg = strappenda("--discard=", discard);
 
+                r = exec_command_append(s->control_command, discard_arg, NULL);
+                if (r < 0)
+                        goto fail;
+        }
+
+        r = exec_command_append(s->control_command, s->what, NULL);
         if (r < 0)
                 goto fail;
 
@@ -1193,11 +1210,25 @@ static Unit *swap_following(Unit *u) {
 
         assert(s);
 
-        if (streq_ptr(s->what, s->devnode))
+        /* If the user configured the swap through /etc/fstab or
+         * a device unit, follow that. */
+
+        if (s->from_fragment)
                 return NULL;
 
-        /* Make everybody follow the unit that's named after the swap
-         * device in the kernel */
+        LIST_FOREACH_AFTER(same_devnode, other, s)
+                if (other->from_fragment)
+                        return UNIT(other);
+
+        LIST_FOREACH_BEFORE(same_devnode, other, s)
+                if (other->from_fragment)
+                        return UNIT(other);
+
+        /* Otherwise make everybody follow the unit that's named after
+         * the swap device in the kernel */
+
+        if (streq_ptr(s->what, s->devnode))
+                return NULL;
 
         LIST_FOREACH_AFTER(same_devnode, other, s)
                 if (streq_ptr(other->what, other->devnode))
@@ -1210,6 +1241,7 @@ static Unit *swap_following(Unit *u) {
                 first = other;
         }
 
+        /* Fall back to the first on the list */
         return UNIT(first);
 }
 
@@ -1226,7 +1258,7 @@ static int swap_following_set(Unit *u, Set **_set) {
                 return 0;
         }
 
-        set = set_new(NULL, NULL);
+        set = set_new(NULL);
         if (!set)
                 return -ENOMEM;