[systemd-devel] [PATCH] swap: introduce Discard property

Zbigniew Jędrzejewski-Szmek zbyszek at in.waw.pl
Wed Sep 24 05:50:18 PDT 2014


On Wed, Sep 24, 2014 at 02:29:05PM +0200, Jan Synacek wrote:
> Process possible "discard" values from /etc/fstab.
Hm, wouldn't it be enough to simply pass through the options like with
mounts, using the Options= option? This might be less work and be more
flexible.

Zbyszek

> ---
>  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 at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel
> 


More information about the systemd-devel mailing list