Zbigniew Jędrzejewski-Szmek 62fe94
From 86b23b07c96b185126bfbf217227dad362a20c25 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 62fe94
From: Jan Synacek <jsynacek@redhat.com>
Zbigniew Jędrzejewski-Szmek 62fe94
Date: Wed, 24 Sep 2014 14:29:05 +0200
Zbigniew Jędrzejewski-Szmek 62fe94
Subject: [PATCH] swap: introduce Discard property
Zbigniew Jędrzejewski-Szmek 62fe94
Zbigniew Jędrzejewski-Szmek 62fe94
Process possible "discard" values from /etc/fstab.
Zbigniew Jędrzejewski-Szmek 62fe94
---
Zbigniew Jędrzejewski-Szmek 62fe94
 man/systemd.swap.xml                  | 14 ++++++++++
Zbigniew Jędrzejewski-Szmek 62fe94
 src/core/execute.c                    | 25 ++++++++++++++++++
Zbigniew Jędrzejewski-Szmek 62fe94
 src/core/execute.h                    |  1 +
Zbigniew Jędrzejewski-Szmek 62fe94
 src/core/load-fragment-gperf.gperf.m4 |  1 +
Zbigniew Jędrzejewski-Szmek 62fe94
 src/core/swap.c                       | 49 +++++++++++++++++++++++------------
Zbigniew Jędrzejewski-Szmek 62fe94
 src/core/swap.h                       |  1 +
Zbigniew Jędrzejewski-Szmek 62fe94
 src/fstab-generator/fstab-generator.c | 10 +++++++
Zbigniew Jędrzejewski-Szmek 62fe94
 7 files changed, 84 insertions(+), 17 deletions(-)
Zbigniew Jędrzejewski-Szmek 62fe94
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml
Zbigniew Jędrzejewski-Szmek 62fe94
index 62a4d08b9c..481dc52454 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/man/systemd.swap.xml
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/man/systemd.swap.xml
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -171,6 +171,20 @@
Zbigniew Jędrzejewski-Szmek 62fe94
                         </varlistentry>
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
                         <varlistentry>
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <term><varname>Discard=</varname></term>
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <listitem><para>Enable discards, if the swap
Zbigniew Jędrzejewski-Szmek 62fe94
+                                backing device supports the discard or trim
Zbigniew Jędrzejewski-Szmek 62fe94
+                                operation. Can be one of <literal>none</literal>,
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <literal>once</literal>, <literal>pages</literal>
Zbigniew Jędrzejewski-Szmek 62fe94
+                                or <literal>all</literal>.  Defaults to
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <literal>none</literal>. (See
Zbigniew Jędrzejewski-Szmek 62fe94
+                                <citerefentry><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry>
Zbigniew Jędrzejewski-Szmek 62fe94
+                                for more information.)
Zbigniew Jędrzejewski-Szmek 62fe94
+                                </para></listitem>
Zbigniew Jędrzejewski-Szmek 62fe94
+                        </varlistentry>
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+                        <varlistentry>
Zbigniew Jędrzejewski-Szmek 62fe94
                                 <term><varname>TimeoutSec=</varname></term>
Zbigniew Jędrzejewski-Szmek 62fe94
                                 <listitem><para>Configures the time to
Zbigniew Jędrzejewski-Szmek 62fe94
                                 wait for the swapon command to
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/core/execute.c b/src/core/execute.c
Zbigniew Jędrzejewski-Szmek 62fe94
index 8c9dfde00a..07ec7a28d6 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/core/execute.c
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/core/execute.c
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -2566,6 +2566,31 @@ int exec_command_set(ExecCommand *c, const char *path, ...) {
Zbigniew Jędrzejewski-Szmek 62fe94
         return 0;
Zbigniew Jędrzejewski-Szmek 62fe94
 }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
+int exec_command_append(ExecCommand *c, const char *path, ...) {
Zbigniew Jędrzejewski-Szmek 62fe94
+        va_list ap;
Zbigniew Jędrzejewski-Szmek 62fe94
+        char **l;
Zbigniew Jędrzejewski-Szmek 62fe94
+        int r;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        assert(c);
Zbigniew Jędrzejewski-Szmek 62fe94
+        assert(path);
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        va_start(ap, path);
Zbigniew Jędrzejewski-Szmek 62fe94
+        l = strv_new_ap(path, ap);
Zbigniew Jędrzejewski-Szmek 62fe94
+        va_end(ap);
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (!l)
Zbigniew Jędrzejewski-Szmek 62fe94
+                return -ENOMEM;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        r = strv_extend_strv(&c->argv, l);
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (r < 0) {
Zbigniew Jędrzejewski-Szmek 62fe94
+                strv_free(l);
Zbigniew Jędrzejewski-Szmek 62fe94
+                return r;
Zbigniew Jędrzejewski-Szmek 62fe94
+        }
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        return 0;
Zbigniew Jędrzejewski-Szmek 62fe94
+}
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
 static int exec_runtime_allocate(ExecRuntime **rt) {
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         if (*rt)
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/core/execute.h b/src/core/execute.h
Zbigniew Jędrzejewski-Szmek 62fe94
index 6f35736eda..2694315155 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/core/execute.h
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/core/execute.h
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -233,6 +233,7 @@ void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix);
Zbigniew Jędrzejewski-Szmek 62fe94
 void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix);
Zbigniew Jędrzejewski-Szmek 62fe94
 void exec_command_append_list(ExecCommand **l, ExecCommand *e);
Zbigniew Jędrzejewski-Szmek 62fe94
 int exec_command_set(ExecCommand *c, const char *path, ...);
Zbigniew Jędrzejewski-Szmek 62fe94
+int exec_command_append(ExecCommand *c, const char *path, ...);
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
 void exec_context_init(ExecContext *c);
Zbigniew Jędrzejewski-Szmek 62fe94
 void exec_context_done(ExecContext *c);
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
Zbigniew Jędrzejewski-Szmek 62fe94
index 050c5d819f..8805411f28 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/core/load-fragment-gperf.gperf.m4
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/core/load-fragment-gperf.gperf.m4
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -297,6 +297,7 @@ Automount.DirectoryMode,         config_parse_mode,                  0,
Zbigniew Jędrzejewski-Szmek 62fe94
 m4_dnl
Zbigniew Jędrzejewski-Szmek 62fe94
 Swap.What,                       config_parse_path,                  0,                             offsetof(Swap, parameters_fragment.what)
Zbigniew Jędrzejewski-Szmek 62fe94
 Swap.Priority,                   config_parse_int,                   0,                             offsetof(Swap, parameters_fragment.priority)
Zbigniew Jędrzejewski-Szmek 62fe94
+Swap.Discard,                    config_parse_string,                0,                             offsetof(Swap, parameters_fragment.discard)
Zbigniew Jędrzejewski-Szmek 62fe94
 Swap.TimeoutSec,                 config_parse_sec,                   0,                             offsetof(Swap, timeout_usec)
Zbigniew Jędrzejewski-Szmek 62fe94
 EXEC_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
Zbigniew Jędrzejewski-Szmek 62fe94
 CGROUP_CONTEXT_CONFIG_ITEMS(Swap)m4_dnl
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/core/swap.c b/src/core/swap.c
Zbigniew Jędrzejewski-Szmek 62fe94
index b88a914f72..2e12824049 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/core/swap.c
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/core/swap.c
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -152,6 +152,9 @@ static void swap_done(Unit *u) {
Zbigniew Jędrzejewski-Szmek 62fe94
         free(s->parameters_fragment.what);
Zbigniew Jędrzejewski-Szmek 62fe94
         s->parameters_fragment.what = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
+        free(s->parameters_fragment.discard);
Zbigniew Jędrzejewski-Szmek 62fe94
+        s->parameters_fragment.discard = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
         s->exec_runtime = exec_runtime_unref(s->exec_runtime);
Zbigniew Jędrzejewski-Szmek 62fe94
         exec_command_done_array(s->exec_command, _SWAP_EXEC_COMMAND_MAX);
Zbigniew Jędrzejewski-Szmek 62fe94
         s->control_command = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -602,10 +605,12 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
Zbigniew Jędrzejewski-Szmek 62fe94
                 fprintf(f,
Zbigniew Jędrzejewski-Szmek 62fe94
                         "%sPriority: %i\n"
Zbigniew Jędrzejewski-Szmek 62fe94
                         "%sNoAuto: %s\n"
Zbigniew Jędrzejewski-Szmek 62fe94
-                        "%sNoFail: %s\n",
Zbigniew Jędrzejewski-Szmek 62fe94
+                        "%sNoFail: %s\n"
Zbigniew Jędrzejewski-Szmek 62fe94
+                        "%sDiscard: %s\n",
Zbigniew Jędrzejewski-Szmek 62fe94
                         prefix, p->priority,
Zbigniew Jędrzejewski-Szmek 62fe94
                         prefix, yes_no(p->noauto),
Zbigniew Jędrzejewski-Szmek 62fe94
-                        prefix, yes_no(p->nofail));
Zbigniew Jędrzejewski-Szmek 62fe94
+                        prefix, yes_no(p->nofail),
Zbigniew Jędrzejewski-Szmek 62fe94
+                        prefix, p->discard);
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         if (s->control_pid > 0)
Zbigniew Jędrzejewski-Szmek 62fe94
                 fprintf(f,
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -734,36 +739,46 @@ fail:
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
 static void swap_enter_activating(Swap *s) {
Zbigniew Jędrzejewski-Szmek 62fe94
         int r, priority;
Zbigniew Jędrzejewski-Szmek 62fe94
+        char *discard;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         assert(s);
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         s->control_command_id = SWAP_EXEC_ACTIVATE;
Zbigniew Jędrzejewski-Szmek 62fe94
         s->control_command = s->exec_command + SWAP_EXEC_ACTIVATE;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-        if (s->from_fragment)
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (s->from_fragment) {
Zbigniew Jędrzejewski-Szmek 62fe94
                 priority = s->parameters_fragment.priority;
Zbigniew Jędrzejewski-Szmek 62fe94
-        else
Zbigniew Jędrzejewski-Szmek 62fe94
+                discard = s->parameters_fragment.discard;
Zbigniew Jędrzejewski-Szmek 62fe94
+        } else {
Zbigniew Jędrzejewski-Szmek 62fe94
                 priority = -1;
Zbigniew Jędrzejewski-Szmek 62fe94
+                discard = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
+        }
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        r = exec_command_set(s->control_command, "/sbin/swapon", NULL);
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
+                goto fail;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         if (priority >= 0) {
Zbigniew Jędrzejewski-Szmek 62fe94
                 char p[DECIMAL_STR_MAX(int)];
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
                 sprintf(p, "%i", priority);
Zbigniew Jędrzejewski-Szmek 62fe94
+                r = exec_command_append(s->control_command, "-p", p, NULL);
Zbigniew Jędrzejewski-Szmek 62fe94
+                if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
+                        goto fail;
Zbigniew Jędrzejewski-Szmek 62fe94
+        }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-                r = exec_command_set(
Zbigniew Jędrzejewski-Szmek 62fe94
-                                s->control_command,
Zbigniew Jędrzejewski-Szmek 62fe94
-                                "/sbin/swapon",
Zbigniew Jędrzejewski-Szmek 62fe94
-                                "-p",
Zbigniew Jędrzejewski-Szmek 62fe94
-                                p,
Zbigniew Jędrzejewski-Szmek 62fe94
-                                s->what,
Zbigniew Jędrzejewski-Szmek 62fe94
-                                NULL);
Zbigniew Jędrzejewski-Szmek 62fe94
-        } else
Zbigniew Jędrzejewski-Szmek 62fe94
-                r = exec_command_set(
Zbigniew Jędrzejewski-Szmek 62fe94
-                                s->control_command,
Zbigniew Jędrzejewski-Szmek 62fe94
-                                "/sbin/swapon",
Zbigniew Jędrzejewski-Szmek 62fe94
-                                s->what,
Zbigniew Jędrzejewski-Szmek 62fe94
-                                NULL);
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (discard && !streq(discard, "none")) {
Zbigniew Jędrzejewski-Szmek 62fe94
+                const char *discard_arg = "--discard";
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+                if (!streq(discard, "all"))
Zbigniew Jędrzejewski-Szmek 62fe94
+                        discard_arg = strappenda("--discard=", discard);
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+                r = exec_command_append(s->control_command, discard_arg, NULL);
Zbigniew Jędrzejewski-Szmek 62fe94
+                if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
+                        goto fail;
Zbigniew Jędrzejewski-Szmek 62fe94
+        }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
+        r = exec_command_append(s->control_command, s->what, NULL);
Zbigniew Jędrzejewski-Szmek 62fe94
         if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
                 goto fail;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/core/swap.h b/src/core/swap.h
Zbigniew Jędrzejewski-Szmek 62fe94
index f2ae49b1de..3482d651ec 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/core/swap.h
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/core/swap.h
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -63,6 +63,7 @@ typedef enum SwapResult {
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
 typedef struct SwapParameters {
Zbigniew Jędrzejewski-Szmek 62fe94
         char *what;
Zbigniew Jędrzejewski-Szmek 62fe94
+        char *discard;
Zbigniew Jędrzejewski-Szmek 62fe94
         int priority;
Zbigniew Jędrzejewski-Szmek 62fe94
         bool noauto:1;
Zbigniew Jędrzejewski-Szmek 62fe94
         bool nofail:1;
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
Zbigniew Jędrzejewski-Szmek 62fe94
index 2c38ab977c..5569325a16 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/fstab-generator/fstab-generator.c
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/fstab-generator/fstab-generator.c
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -73,6 +73,8 @@ static int mount_find_pri(struct mntent *me, int *ret) {
Zbigniew Jędrzejewski-Szmek 62fe94
 static int add_swap(const char *what, struct mntent *me) {
Zbigniew Jędrzejewski-Szmek 62fe94
         _cleanup_free_ char *name = NULL, *unit = NULL, *lnk = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
         _cleanup_fclose_ FILE *f = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
+        char *discard = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
         bool noauto;
Zbigniew Jędrzejewski-Szmek 62fe94
         int r, pri = -1;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -118,6 +120,14 @@ static int add_swap(const char *what, struct mntent *me) {
Zbigniew Jędrzejewski-Szmek 62fe94
                 "What=%s\n",
Zbigniew Jędrzejewski-Szmek 62fe94
                 what);
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
+        discard = mount_test_option(me->mnt_opts, "discard");
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (discard) {
Zbigniew Jędrzejewski-Szmek 62fe94
+                discard = strpbrk(discard, "=");
Zbigniew Jędrzejewski-Szmek 62fe94
+                fprintf(f,
Zbigniew Jędrzejewski-Szmek 62fe94
+                        "Discard=%s\n",
Zbigniew Jędrzejewski-Szmek 62fe94
+                        discard ? discard+1 : "all");
Zbigniew Jędrzejewski-Szmek 62fe94
+        }
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
         if (pri >= 0)
Zbigniew Jędrzejewski-Szmek 62fe94
                 fprintf(f,
Zbigniew Jędrzejewski-Szmek 62fe94
                         "Priority=%i\n",