[systemd-devel] [PATCH] swap: introduce Discard property
Jan Synacek
jsynacek at redhat.com
Wed Sep 24 05:29:05 PDT 2014
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 | 54 ++++++++++++++++++++++++-----------
src/core/swap.h | 1 +
src/fstab-generator/fstab-generator.c | 10 +++++++
7 files changed, 89 insertions(+), 17 deletions(-)
diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml
index 62a4d08..06d87b7 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 <constant>none</constant>,
+ <constant>once</constant>, <constant>pages</constant>
+ or <constant>all</constant>. Defaults to
+ <constant>none</constant>. (See
+ <citerefentry><refentrytitle>swapon</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ for more information about.)
+ </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 8c9dfde..07ec7a2 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 6f35736..2694315 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 050c5d8..8805411 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 b88a914..568ed41 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -122,6 +122,7 @@ static void swap_init(Unit *u) {
s->exec_context.std_error = u->manager->default_std_error;
s->parameters_proc_swaps.priority = s->parameters_fragment.priority = -1;
+ s->parameters_proc_swaps.discard = s->parameters_fragment.discard = NULL;
s->control_command_id = _SWAP_EXEC_COMMAND_INVALID;
@@ -602,10 +603,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 +737,53 @@ fail:
static void swap_enter_activating(Swap *s) {
int r, priority;
+ char *discard = NULL;
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;
+ }
+
+ 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")) {
+ _cleanup_free_ char *discard_arg = NULL;
+
+ if (streq(discard, "all")) {
+ discard_arg = strdup("--discard");
+ } else if (streq(discard, "once") || streq(discard, "pages")) {
+ r = asprintf(&discard_arg, "--discard=%s", discard);
+ if (r < 0)
+ goto fail;
+ }
+
+ if (discard_arg) {
+ 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 f2ae49b..3482d65 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 2c38ab9..5569325 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",
--
1.9.3
More information about the systemd-devel
mailing list