Parse "timeout=0" as infinity in various generators (#6264)
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 3 Jul 2017 12:29:32 +0000 (08:29 -0400)
committerLennart Poettering <lennart@poettering.net>
Mon, 3 Jul 2017 12:29:32 +0000 (14:29 +0200)
This extends 2d79a0bbb9f651656384a0a86ed814e6306fb5dd to the kernel
command line parsing.

The parsing is changed a bit to only understand "0" as infinity. If units are
specified, parse normally, e.g. "0s" is just 0. This makes it possible to
provide a zero timeout if necessary.

Simple test is added.

Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1462378.

src/basic/time-util.c
src/basic/time-util.h
src/core/load-fragment.c
src/cryptsetup/cryptsetup.c
src/fstab-generator/fstab-generator.c
src/shared/generator.c
src/test/test-time.c

index b0b1811..3b44985 100644 (file)
@@ -1009,6 +1009,16 @@ int parse_sec(const char *t, usec_t *usec) {
         return parse_time(t, usec, USEC_PER_SEC);
 }
 
+int parse_sec_fix_0(const char *t, usec_t *usec) {
+        t += strspn(t, WHITESPACE);
+        if (streq(t, "0")) {
+                *usec = USEC_INFINITY;
+                return 0;
+        }
+
+        return parse_sec(t, usec);
+}
+
 int parse_nsec(const char *t, nsec_t *nsec) {
         static const struct {
                 const char *suffix;
index 414995e..3b7f0e9 100644 (file)
@@ -133,6 +133,7 @@ int timestamp_deserialize(const char *value, usec_t *timestamp);
 int parse_timestamp(const char *t, usec_t *usec);
 
 int parse_sec(const char *t, usec_t *usec);
+int parse_sec_fix_0(const char *t, usec_t *usec);
 int parse_time(const char *t, usec_t *usec, usec_t default_unit);
 int parse_nsec(const char *t, nsec_t *nsec);
 
index 8d7153f..6a6dadd 100644 (file)
@@ -1870,15 +1870,12 @@ int config_parse_sec_fix_0(
          * compatibility with older versions of systemd where 0 instead of infinity was used as indicator to turn off a
          * timeout. */
 
-        r = parse_sec(rvalue, usec);
+        r = parse_sec_fix_0(rvalue, usec);
         if (r < 0) {
                 log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse %s= parameter, ignoring: %s", lvalue, rvalue);
                 return 0;
         }
 
-        if (*usec <= 0)
-                *usec = USEC_INFINITY;
-
         return 0;
 }
 
index 91c6533..3b4c086 100644 (file)
@@ -190,7 +190,7 @@ static int parse_one_option(const char *option) {
                 arg_type = CRYPT_PLAIN;
         else if ((val = startswith(option, "timeout="))) {
 
-                r = parse_sec(val, &arg_timeout);
+                r = parse_sec_fix_0(val, &arg_timeout);
                 if (r < 0) {
                         log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
                         return 0;
index b6c1a87..0bbc6c7 100644 (file)
@@ -176,7 +176,7 @@ static bool mount_in_initrd(struct mntent *me) {
 }
 
 static int write_timeout(FILE *f, const char *where, const char *opts,
-                const char *filter, const char *variable) {
+                         const char *filter, const char *variable) {
         _cleanup_free_ char *timeout = NULL;
         char timespan[FORMAT_TIMESPAN_MAX];
         usec_t u;
@@ -188,7 +188,7 @@ static int write_timeout(FILE *f, const char *where, const char *opts,
         if (r == 0)
                 return 0;
 
-        r = parse_sec(timeout, &u);
+        r = parse_sec_fix_0(timeout, &u);
         if (r < 0) {
                 log_warning("Failed to parse timeout for %s, ignoring: %s", where, timeout);
                 return 0;
index 19ec133..6a78ebb 100644 (file)
@@ -167,12 +167,13 @@ int generator_write_timeouts(
         usec_t u;
         int r;
 
-        r = fstab_filter_options(opts, "comment=systemd.device-timeout\0" "x-systemd.device-timeout\0",
+        r = fstab_filter_options(opts, "comment=systemd.device-timeout\0"
+                                       "x-systemd.device-timeout\0",
                                  NULL, &timeout, filtered);
         if (r <= 0)
                 return r;
 
-        r = parse_sec(timeout, &u);
+        r = parse_sec_fix_0(timeout, &u);
         if (r < 0) {
                 log_warning("Failed to parse timeout for %s, ignoring: %s", where, timeout);
                 return 0;
index 601e835..b7a06c7 100644 (file)
@@ -61,6 +61,19 @@ static void test_parse_sec(void) {
         assert_se(parse_sec(".3 infinity", &u) < 0);
 }
 
+static void test_parse_sec_fix_0(void) {
+        usec_t u;
+
+        assert_se(parse_sec_fix_0("5s", &u) >= 0);
+        assert_se(u == 5 * USEC_PER_SEC);
+        assert_se(parse_sec_fix_0("0s", &u) >= 0);
+        assert_se(u == 0 * USEC_PER_SEC);
+        assert_se(parse_sec_fix_0("0", &u) >= 0);
+        assert_se(u == USEC_INFINITY);
+        assert_se(parse_sec_fix_0(" 0", &u) >= 0);
+        assert_se(u == USEC_INFINITY);
+}
+
 static void test_parse_time(void) {
         usec_t u;
 
@@ -380,6 +393,7 @@ int main(int argc, char *argv[]) {
                  now(clock_boottime_or_monotonic()));
 
         test_parse_sec();
+        test_parse_sec_fix_0();
         test_parse_time();
         test_parse_nsec();
         test_format_timespan(1);