From 86b23b07c96b185126bfbf217227dad362a20c25 Mon Sep 17 00:00:00 2001 From: Jan Synacek 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 @@ -170,6 +170,20 @@ setting is optional. + + Discard= + + Enable discards, if the swap + backing device supports the discard or trim + operation. Can be one of none, + once, pages + or all. Defaults to + none. (See + swapon8 + for more information.) + + + TimeoutSec= Configures the time 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", -- 2.34.1