From 5024f01fec5e6c8fd05ca5451176878084e3f18f Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 17 Sep 2014 09:06:49 +0200 Subject: [PATCH] sysctl: make --prefix allow all kinds of sysctl paths Currently, we save arguments passed as --prefix directly and compare them later to absolute sysctl file-system paths. That is, you are required to specify arguments to --prefix with leading /proc/sys/. This is kinda uselesss. Furthermore, we replace dots by slashes in the name, which makes it impossible to match on specific sysfs paths that have dots in their name (like netdev names). The intention of this argument is clear, but it never worked as expected. This patch modifies --prefix to accept any kind of sysctl paths. It supports paths prefixed with /proc/sys for compatibility (but drops the erroneous dot->slash conversion), but instead applies normalize_sysctl() which turns any name or path into a proper path. It then appends /proc/sys/ so we can properly use it in matches. Thanks to Jan Synacek for catching this! Conflicts: src/sysctl/sysctl.c (cherry picked from commit 0e1f579227b08832437a7ac2227c7e4007a89d23) Resolves: #1138591 --- src/sysctl/sysctl.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c index a9d4d53..d6f48dd 100644 --- a/src/sysctl/sysctl.c +++ b/src/sysctl/sysctl.c @@ -51,9 +51,23 @@ static const char conf_file_dirs[] = static char *normalize_sysctl(char *s) { char *n; - for (n = s; *n; n++) + n = strpbrk(s, "/."); + /* If the first separator is a slash, the path is + * assumed to be normalized and slashes remain slashes + * and dots remains dots. */ + if (!n || *n == '/') + return s; + + /* Otherwise, dots become slashes and slashes become + * dots. Fun. */ + while (n) { if (*n == '.') *n = '/'; + else + *n = '.'; + + n = strpbrk(n + 1, "/."); + } return s; } @@ -205,7 +219,7 @@ static int help(void) { printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n" "Applies kernel sysctl settings.\n\n" " -h --help Show this help\n" - " --prefix=PATH Only apply rules that apply to paths with the specified prefix\n", + " --prefix=PATH Only apply rules with the specified prefix\n", program_invocation_short_name); return 0; @@ -238,18 +252,22 @@ static int parse_argv(int argc, char *argv[]) { case ARG_PREFIX: { char *p; - char **l; - for (p = optarg; *p; p++) - if (*p == '.') - *p = '/'; - - l = strv_append(arg_prefixes, optarg); - if (!l) + /* We used to require people to specify absolute paths + * in /proc/sys in the past. This is kinda useless, but + * we need to keep compatibility. We now support any + * sysctl name available. */ + normalize_sysctl(optarg); + if (startswith(optarg, "/proc/sys")) + p = strdup(optarg); + else + p = strappend("/proc/sys/", optarg); + + if (!p) return log_oom(); - strv_free(arg_prefixes); - arg_prefixes = l; + if (strv_push(&arg_prefixes, p) < 0) + return log_oom(); break; }