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