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 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel