From: Zbigniew Jędrzejewski-Szmek Date: Sun, 28 Sep 2014 02:02:04 +0000 (-0400) Subject: fstab-generator: properly deal with discard as non-last option X-Git-Tag: v217~404 X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=4f52d3fe2da7c3449b7fbfaa7c64a83354d3b56c 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 2e1282404..36c9e029e 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 5569325a1..5dafcba3c 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)) {