Parse "timeout=0" as infinity in various generators (#6264)

This extends 2d79a0bbb9 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.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2017-07-03 08:29:32 -04:00 committed by Lennart Poettering
parent 131d5e148e
commit 0004f698df
7 changed files with 32 additions and 9 deletions

View 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;

View 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);

View 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;
}

View 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;

View 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;

View 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;

View 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);