[systemd-commits] 8 commits - man/systemd.swap.xml src/core src/fstab-generator src/journal src/journal-remote src/network src/shared src/test

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Mon Sep 29 08:14:47 PDT 2014


 man/systemd.swap.xml                  |   14 ++++++
 src/core/cgroup.c                     |    2 
 src/core/dbus-cgroup.c                |   20 ---------
 src/core/dbus-swap.c                  |   24 +++++++++++
 src/core/execute.c                    |   25 ++++++++++++
 src/core/execute.h                    |    1 
 src/core/load-fragment-gperf.gperf.m4 |    1 
 src/core/swap.c                       |   70 ++++++++++++++++++++++++----------
 src/core/swap.h                       |    1 
 src/core/timer.c                      |    2 
 src/fstab-generator/fstab-generator.c |   65 ++++++++++++++++++++++++++-----
 src/journal-remote/journal-remote.c   |   16 +++++++
 src/journal/journalctl.c              |    2 
 src/network/networkd-link.c           |   12 +----
 src/shared/time-util.c                |   21 +++++++---
 src/test/test-time.c                  |    7 +++
 16 files changed, 217 insertions(+), 66 deletions(-)

New commits:
commit b1d6dcf5a5c5aa02843c026dede0638f77798cb4
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Mon Sep 29 07:31:14 2014 -0500

    Do not format USEC_INFINITY as NULL
    
    systemctl would print 'CPUQuotaPerSecUSec=(null)' for no limit. This
    does not look right.
    
    Since USEC_INFINITY is one of the valid values, format_timespan()
    could return NULL, and we should wrap every use of it in strna() or
    similar. But most callers didn't do that, and it seems more robust to
    return a string ("infinity") that makes sense most of the time, even
    if in some places the result will not be grammatically correct.

diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 6c6e4f5..e604c3c 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -111,7 +111,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
                 prefix, yes_no(c->memory_accounting),
                 prefix, c->cpu_shares,
                 prefix, c->startup_cpu_shares,
-                prefix, strna(format_timespan(u, sizeof(u), c->cpu_quota_per_sec_usec, 1)),
+                prefix, format_timespan(u, sizeof(u), c->cpu_quota_per_sec_usec, 1),
                 prefix, c->blockio_weight,
                 prefix, c->startup_blockio_weight,
                 prefix, c->memory_limit,
diff --git a/src/core/timer.c b/src/core/timer.c
index dc0f289..a3713e2 100644
--- a/src/core/timer.c
+++ b/src/core/timer.c
@@ -242,7 +242,7 @@ static void timer_dump(Unit *u, FILE *f, const char *prefix) {
                                 "%s%s: %s\n",
                                 prefix,
                                 timer_base_to_string(v->base),
-                                strna(format_timespan(timespan1, sizeof(timespan1), v->value, 0)));
+                                format_timespan(timespan1, sizeof(timespan1), v->value, 0));
                 }
         }
 }
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 427f695..dcbe38a 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1475,12 +1475,10 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
         case RTM_NEWADDR:
                 if (!address_dropped)
                         log_debug_link(link, "added address: %s/%u (valid for %s)",
-                                       buf, address->prefixlen,
-                                       strna(valid_str));
+                                       buf, address->prefixlen, valid_str);
                 else
                         log_debug_link(link, "updated address: %s/%u (valid for %s)",
-                                       buf, address->prefixlen,
-                                       strna(valid_str));
+                                       buf, address->prefixlen, valid_str);
 
                 LIST_PREPEND(addresses, link->addresses, address);
                 address = NULL;
@@ -1491,15 +1489,13 @@ int link_rtnl_process_address(sd_rtnl *rtnl, sd_rtnl_message *message,
         case RTM_DELADDR:
                 if (address_dropped) {
                         log_debug_link(link, "removed address: %s/%u (valid for %s)",
-                                       buf, address->prefixlen,
-                                       strna(valid_str));
+                                       buf, address->prefixlen, valid_str);
 
                         link_save(link);
                 } else
                         log_warning_link(link,
                                          "removing non-existent address: %s/%u (valid for %s)",
-                                         buf, address->prefixlen,
-                                         strna(valid_str));
+                                         buf, address->prefixlen, valid_str);
 
                 break;
         default:
diff --git a/src/shared/time-util.c b/src/shared/time-util.c
index 2dc01e6..066ef97 100644
--- a/src/shared/time-util.c
+++ b/src/shared/time-util.c
@@ -279,11 +279,8 @@ char *format_timespan(char *buf, size_t l, usec_t t, usec_t accuracy) {
         assert(buf);
         assert(l > 0);
 
-        if (t == USEC_INFINITY)
-                return NULL;
-
-        if (t <= 0) {
-                snprintf(p, l, "0");
+        if (t == USEC_INFINITY || t <= 0) {
+                strncpy(p, t == USEC_INFINITY ? "infinity" : "0", l);
                 p[l-1] = 0;
                 return p;
         }
@@ -628,7 +625,7 @@ int parse_sec(const char *t, usec_t *usec) {
                 { "", USEC_PER_SEC }, /* default is sec */
         };
 
-        const char *p;
+        const char *p, *s;
         usec_t r = 0;
         bool something = false;
 
@@ -636,6 +633,18 @@ int parse_sec(const char *t, usec_t *usec) {
         assert(usec);
 
         p = t;
+
+        p += strspn(p, WHITESPACE);
+        s = startswith(p, "infinity");
+        if (s) {
+                s += strspn(s, WHITESPACE);
+                if (*s != 0)
+                        return -EINVAL;
+
+                *usec = USEC_INFINITY;
+                return 0;
+        }
+
         for (;;) {
                 long long l, z = 0;
                 char *e;
diff --git a/src/test/test-time.c b/src/test/test-time.c
index 87e7ae7..8cfc4cc 100644
--- a/src/test/test-time.c
+++ b/src/test/test-time.c
@@ -43,12 +43,18 @@ static void test_parse_sec(void) {
         assert_se(u == 2500 * USEC_PER_MSEC);
         assert_se(parse_sec(".7", &u) >= 0);
         assert_se(u == 700 * USEC_PER_MSEC);
+        assert_se(parse_sec("infinity", &u) >= 0);
+        assert_se(u == USEC_INFINITY);
+        assert_se(parse_sec(" infinity ", &u) >= 0);
+        assert_se(u == USEC_INFINITY);
 
         assert_se(parse_sec(" xyz ", &u) < 0);
         assert_se(parse_sec("", &u) < 0);
         assert_se(parse_sec(" . ", &u) < 0);
         assert_se(parse_sec(" 5. ", &u) < 0);
         assert_se(parse_sec(".s ", &u) < 0);
+        assert_se(parse_sec(" infinity .7", &u) < 0);
+        assert_se(parse_sec(".3 infinity", &u) < 0);
 }
 
 static void test_parse_nsec(void) {
@@ -125,6 +131,7 @@ static void test_format_timespan(usec_t accuracy) {
         test_format_timespan_one(986087, accuracy);
         test_format_timespan_one(500 * USEC_PER_MSEC, accuracy);
         test_format_timespan_one(9*USEC_PER_YEAR/5 - 23, accuracy);
+        test_format_timespan_one(USEC_INFINITY, accuracy);
 }
 
 static void test_timezone_is_valid(void) {

commit ee26bcc0387f6eda83878eb85a08c01ee0d82c44
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Sun Sep 28 23:42:33 2014 -0400

    core/dbus: simplify handling of CPUQuotaPerSecUSec
    
    No functional change intended.

diff --git a/src/core/dbus-cgroup.c b/src/core/dbus-cgroup.c
index eb7c2b9..900566c 100644
--- a/src/core/dbus-cgroup.c
+++ b/src/core/dbus-cgroup.c
@@ -133,24 +133,6 @@ static int property_get_device_allow(
         return sd_bus_message_close_container(reply);
 }
 
-static int property_get_cpu_quota_per_sec_usec(
-                sd_bus *bus,
-                const char *path,
-                const char *interface,
-                const char *property,
-                sd_bus_message *reply,
-                void *userdata,
-                sd_bus_error *error) {
-
-        CGroupContext *c = userdata;
-
-        assert(bus);
-        assert(reply);
-        assert(c);
-
-        return sd_bus_message_append(reply, "t", c->cpu_quota_per_sec_usec);
-}
-
 static int property_get_ulong_as_u64(
                 sd_bus *bus,
                 const char *path,
@@ -174,7 +156,7 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
         SD_BUS_PROPERTY("CPUAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, cpu_accounting), 0),
         SD_BUS_PROPERTY("CPUShares", "t", property_get_ulong_as_u64, offsetof(CGroupContext, cpu_shares), 0),
         SD_BUS_PROPERTY("StartupCPUShares", "t", property_get_ulong_as_u64, offsetof(CGroupContext, startup_cpu_shares), 0),
-        SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", property_get_cpu_quota_per_sec_usec, 0, 0),
+        SD_BUS_PROPERTY("CPUQuotaPerSecUSec", "t", bus_property_get_usec, offsetof(CGroupContext, cpu_quota_per_sec_usec), 0),
         SD_BUS_PROPERTY("BlockIOAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, blockio_accounting), 0),
         SD_BUS_PROPERTY("BlockIOWeight", "t", property_get_ulong_as_u64, offsetof(CGroupContext, blockio_weight), 0),
         SD_BUS_PROPERTY("StartupBlockIOWeight", "t", property_get_ulong_as_u64, offsetof(CGroupContext, startup_blockio_weight), 0),

commit 4afbccded23f5144e39a7f7b243393799186ba39
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Sun Sep 28 22:13:07 2014 -0400

    core/swap: advertise Discard over dbus

diff --git a/src/core/dbus-swap.c b/src/core/dbus-swap.c
index 93eae53..c854716 100644
--- a/src/core/dbus-swap.c
+++ b/src/core/dbus-swap.c
@@ -55,12 +55,36 @@ static int property_get_priority(
         return sd_bus_message_append(reply, "i", p);
 }
 
+static int property_get_discard(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        Swap *s = SWAP(userdata);
+        const char *p;
+
+        assert(bus);
+        assert(reply);
+        assert(s);
+
+        if (s->from_fragment)
+                p = s->parameters_fragment.discard ?: "none";
+        else
+                p = "none";
+        return sd_bus_message_append(reply, "s", p);
+}
+
 static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, swap_result, SwapResult);
 
 const sd_bus_vtable bus_swap_vtable[] = {
         SD_BUS_VTABLE_START(0),
         SD_BUS_PROPERTY("What", "s", NULL, offsetof(Swap, what), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Priority", "i", property_get_priority, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("Discard", "s", property_get_discard, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("TimeoutUSec", "t", bus_property_get_usec, offsetof(Swap, timeout_usec), SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ControlPID", "u", bus_property_get_pid, offsetof(Swap, control_pid), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Swap, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),

commit cdc8982030271785d650af410230397bbb5a4be9
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Sun Sep 28 10:37:52 2014 -0400

    core/swap: follow the configured unit by default
    
    Phenomenon: parameters configured in /etc/fstab for swap units are
    ignored. E.g. pri= settings have no effect when systemd starts swap
    units. What is even more confusing, .swap units for the name used in
    /etc/fstab initially show proper values for Priority=, but after
    starting them, they are re-initalized from /proc/swaps and show the -1
    value from /proc/swaps.
    
    Change swap units to follow the original configured unit. This way
    proper settings are used when starting the swap.

diff --git a/src/core/swap.c b/src/core/swap.c
index 36c9e02..ef90d0e 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -1208,11 +1208,25 @@ static Unit *swap_following(Unit *u) {
 
         assert(s);
 
-        if (streq_ptr(s->what, s->devnode))
+        /* If the user configured the swap through /etc/fstab or
+         * a device unit, follow that. */
+
+        if (s->from_fragment)
                 return NULL;
 
-        /* Make everybody follow the unit that's named after the swap
-         * device in the kernel */
+        LIST_FOREACH_AFTER(same_devnode, other, s)
+                if (other->from_fragment)
+                        return UNIT(other);
+
+        LIST_FOREACH_BEFORE(same_devnode, other, s)
+                if (other->from_fragment)
+                        return UNIT(other);
+
+        /* Otherwise make everybody follow the unit that's named after
+         * the swap device in the kernel */
+
+        if (streq_ptr(s->what, s->devnode))
+                return NULL;
 
         LIST_FOREACH_AFTER(same_devnode, other, s)
                 if (streq_ptr(other->what, other->devnode))
@@ -1225,6 +1239,7 @@ static Unit *swap_following(Unit *u) {
                 first = other;
         }
 
+        /* Fall back to the first on the list */
         return UNIT(first);
 }
 

commit 4f52d3fe2da7c3449b7fbfaa7c64a83354d3b56c
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Sat Sep 27 22:02:04 2014 -0400

    fstab-generator: properly deal with discard as non-last option
    
    Previous code would only return correct results when discard
    was the last option.
    
    While at it, avoid incorrect behaviour for (invalid) 'pri' option
    not followed by '=...', and also do not return -1 as the error code.

diff --git a/src/core/swap.c b/src/core/swap.c
index 2e12824..36c9e02 100644
--- a/src/core/swap.c
+++ b/src/core/swap.c
@@ -610,7 +610,7 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) {
                         prefix, p->priority,
                         prefix, yes_no(p->noauto),
                         prefix, yes_no(p->nofail),
-                        prefix, p->discard);
+                        prefix, p->discard ?: "none");
 
         if (s->control_pid > 0)
                 fprintf(f,
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 5569325..5dafcba 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -46,34 +46,70 @@ static int arg_root_rw = -1;
 
 
 static int mount_find_pri(struct mntent *me, int *ret) {
-        char *end, *pri;
+        char *end, *opt;
         unsigned long r;
 
         assert(me);
         assert(ret);
 
-        pri = hasmntopt(me, "pri");
-        if (!pri)
+        opt = hasmntopt(me, "pri");
+        if (!opt)
                 return 0;
 
-        pri += 4;
+        opt += strlen("pri");
+
+        if (*opt != '=')
+                return -EINVAL;
 
         errno = 0;
-        r = strtoul(pri, &end, 10);
+        r = strtoul(opt + 1, &end, 10);
         if (errno > 0)
                 return -errno;
 
-        if (end == pri || (*end != ',' && *end != 0))
+        if (end == opt + 1 || (*end != ',' && *end != 0))
                 return -EINVAL;
 
         *ret = (int) r;
         return 1;
 }
 
+static int mount_find_discard(struct mntent *me, char **ret) {
+        char *opt, *ans;
+        size_t len;
+
+        assert(me);
+        assert(ret);
+
+        opt = hasmntopt(me, "discard");
+        if (!opt)
+                return 0;
+
+        opt += strlen("discard");
+
+        if (*opt == ',' || *opt == '\0')
+                ans = strdup("all");
+        else {
+                if (*opt != '=')
+                        return -EINVAL;
+
+                len = strcspn(opt + 1, ",");
+                if (len == 0)
+                        return -EINVAL;
+
+                ans = strndup(opt + 1, len);
+        }
+
+        if (!ans)
+                return -ENOMEM;
+
+        *ret = ans;
+        return 1;
+}
+
 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;
+        _cleanup_free_ char *discard = NULL;
 
         bool noauto;
         int r, pri = -1;
@@ -89,7 +125,13 @@ static int add_swap(const char *what, struct mntent *me) {
         r = mount_find_pri(me, &pri);
         if (r < 0) {
                 log_error("Failed to parse priority");
-                return pri;
+                return r;
+        }
+
+        r = mount_find_discard(me, &discard);
+        if (r < 0) {
+                log_error("Failed to parse discard");
+                return r;
         }
 
         noauto = !!hasmntopt(me, "noauto");
@@ -120,18 +162,11 @@ 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",
-                        pri);
+                fprintf(f, "Priority=%i\n", pri);
+
+        if (discard)
+                fprintf(f, "Discard=%s\n", discard);
 
         fflush(f);
         if (ferror(f)) {

commit 86b23b07c96b185126bfbf217227dad362a20c25
Author: Jan Synacek <jsynacek at redhat.com>
Date:   Wed Sep 24 14:29:05 2014 +0200

    swap: introduce Discard property
    
    Process possible "discard" values from /etc/fstab.

diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml
index 62a4d08..481dc52 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 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..2e12824 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 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",

commit 70f1b2ddc6b94d3fa5539eb8503887b465f7fcc7
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Sat Sep 27 20:00:00 2014 -0400

    journal-remote: fix handling of non-blocking sources
    
    In the conversion to sd-event loop, handling of normal files got
    broken. We do not want to perform non-blocking reads on them, but
    simply do read() in a loop. Install a statically-enabled "source"
    to do that.

diff --git a/src/journal-remote/journal-remote.c b/src/journal-remote/journal-remote.c
index ad87783..c97cfe6 100644
--- a/src/journal-remote/journal-remote.c
+++ b/src/journal-remote/journal-remote.c
@@ -295,6 +295,8 @@ static int dispatch_raw_source_event(sd_event_source *event,
                                      int fd,
                                      uint32_t revents,
                                      void *userdata);
+static int dispatch_blocking_source_event(sd_event_source *event,
+                                          void *userdata);
 static int dispatch_raw_connection_event(sd_event_source *event,
                                          int fd,
                                          uint32_t revents,
@@ -378,6 +380,13 @@ static int add_source(RemoteServer *s, int fd, char* name, bool own_name) {
         r = sd_event_add_io(s->events, &source->event,
                             fd, EPOLLIN|EPOLLRDHUP|EPOLLPRI,
                             dispatch_raw_source_event, s);
+        if (r == -EPERM) {
+                log_debug("Falling back to sd_event_add_defer for fd:%d (%s)", fd, name);
+                r = sd_event_add_defer(s->events, &source->event,
+                                       dispatch_blocking_source_event, source);
+                if (r == 0)
+                        sd_event_source_set_enabled(source->event, SD_EVENT_ON);
+        }
         if (r < 0) {
                 log_error("Failed to register event source for fd:%d: %s",
                           fd, strerror(-r));
@@ -1029,6 +1038,13 @@ static int dispatch_raw_source_event(sd_event_source *event,
                 return 1;
 }
 
+static int dispatch_blocking_source_event(sd_event_source *event,
+                                          void *userdata) {
+        RemoteSource *source = userdata;
+
+        return dispatch_raw_source_event(event, source->fd, EPOLLIN, server);
+}
+
 static int accept_connection(const char* type, int fd,
                              SocketAddress *addr, char **hostname) {
         int fd2, r;

commit 4bed248505da4da94d82078fe60326a374970e97
Author: Zbigniew Jędrzejewski-Szmek <zbyszek at in.waw.pl>
Date:   Fri Sep 26 10:49:55 2014 -0400

    journalctl: do not output --reboot-- markers when running non-interactively
    
    They are not legal in the export format.

diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
index 47206d3..89a922c 100644
--- a/src/journal/journalctl.c
+++ b/src/journal/journalctl.c
@@ -1939,7 +1939,7 @@ int main(int argc, char *argv[]) {
                                         goto finish;
                         }
 
-                        if (!arg_merge) {
+                        if (!arg_merge && !arg_quiet) {
                                 sd_id128_t boot_id;
 
                                 r = sd_journal_get_monotonic_usec(j, NULL, &boot_id);



More information about the systemd-commits mailing list