diff --git a/man/standard-conf.xml b/man/standard-conf.xml index 1db859ac2f..a58c76d85f 100644 --- a/man/standard-conf.xml +++ b/man/standard-conf.xml @@ -11,30 +11,31 @@ Configuration Directories and Precedence - Configuration files are read from directories in /etc/, /run/, - /usr/local/lib/, and /usr/lib/, in order of precedence. Each - configuration file in these configuration directories shall be named in the style of - filename.conf. Files in /etc/ override files - with the same name in /run/, /usr/local/lib/, and - /usr/lib/. Files in /run/ override files with the same name under - /usr/. + Configuration files are read from directories in /etc/, + /run/, /usr/local/lib/, and /usr/lib/, in + order of precedence, as listed in the SYNOPSIS section above. Files must have the the + .conf extension. Files in /etc/ override files with the same name + in /run/, /usr/local/lib/, and + /usr/lib/. Files in /run/ override files with the same name + under /usr/. - Packages should install their configuration files in /usr/lib/ (distribution packages) - or /usr/local/lib/ (local installs). Files in /etc/ are - reserved for the local administrator, who may use this logic to override the - configuration files installed by vendor packages. All configuration files - are sorted by their filename in lexicographic order, regardless of which of - the directories they reside in. If multiple files specify the same option, - the entry in the file with the lexicographically latest name will take - precedence. It is recommended to prefix all filenames with a two-digit number - and a dash, to simplify the ordering of the files. + All configuration files are sorted by their filename in lexicographic order, regardless of which of + the directories they reside in. If multiple files specify the same option, the entry in the file with the + lexicographically latest name will take precedence. Thus, the configuration in a certain file may either + be replaced completely (by placing a file with the same name in a directory with higher priority), or + individual settings might be changed (by specifying additional settings in a file with a different name + that is ordered later). - If the administrator wants to disable a configuration file supplied by - the vendor, the recommended way is to place a symlink to - /dev/null in the configuration directory in - /etc/, with the same filename as the vendor - configuration file. If the vendor configuration file is included in - the initrd image, the image has to be regenerated. + Packages should install their configuration files in /usr/lib/ (distribution + packages) or /usr/local/lib/ (local installs). Files in /etc/ + are reserved for the local administrator, who may use this logic to override the configuration files + installed by vendor packages. It is recommended to prefix all filenames with a two-digit number and a + dash, to simplify the ordering of the files. + + If the administrator wants to disable a configuration file supplied by the vendor, the recommended + way is to place a symlink to /dev/null in the configuration directory in + /etc/, with the same filename as the vendor configuration file. If the vendor + configuration file is included in the initrd image, the image has to be regenerated. @@ -48,25 +49,20 @@ can be edited to create local overrides. - When packages need to customize the configuration, they can - install configuration snippets in - /usr/lib/systemd/*.conf.d/ or - /usr/local/lib/systemd/*.conf.d/. Files in - /etc/ are reserved for the local - administrator, who may use this logic to override the - configuration files installed by vendor packages. The main - configuration file is read before any of the configuration - directories, and has the lowest precedence; entries in a file in - any configuration directory override entries in the single - configuration file. Files in the *.conf.d/ - configuration subdirectories are sorted by their filename in lexicographic - order, regardless of which of the subdirectories they reside in. When - multiple files specify the same option, for options which accept just a - single value, the entry in the file with the lexicographically latest name - takes precedence. For options which accept a list of values, entries are - collected as they occur in files sorted lexicographically. It is recommended - to prefix all filenames in those subdirectories with a two-digit number and - a dash, to simplify the ordering of the files. + When packages need to customize the configuration, they can install configuration snippets in + /usr/lib/systemd/*.conf.d/ or /usr/local/lib/systemd/*.conf.d/. + The main configuration file is read before any of the configuration directories, and has the lowest + precedence; entries in a file in any configuration directory override entries in the single configuration + file. Files in the *.conf.d/ configuration subdirectories are sorted by their + filename in lexicographic order, regardless of in which of the subdirectories they reside. When multiple + files specify the same option, for options which accept just a single value, the entry in the file with + the lexicographically latest name takes precedence. For options which accept a list of values, entries + are collected as they occur in files sorted lexicographically. + + Files in /etc/ are reserved for the local administrator, who may use this + logic to override the configuration files installed by vendor packages. It is recommended to prefix all + filenames in those subdirectories with a two-digit number and a dash, to simplify the ordering of the + files. To disable a configuration file supplied by the vendor, the recommended way is to place a symlink to diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c index 56d86d8eba..afef0a222b 100644 --- a/src/sysctl/sysctl.c +++ b/src/sysctl/sysctl.c @@ -11,6 +11,7 @@ #include "conf-files.h" #include "def.h" +#include "errno-util.h" #include "fd-util.h" #include "fileio.h" #include "hashmap.h" @@ -85,13 +86,15 @@ static int apply_all(OrderedHashmap *sysctl_options) { k = sysctl_write(option->key, option->value); if (k < 0) { /* If the sysctl is not available in the kernel or we are running with reduced - * privileges and cannot write it, then log about the issue at LOG_NOTICE level, and - * proceed without failing. (EROFS is treated as a permission problem here, since - * that's how container managers usually protected their sysctls.) In all other cases - * log an error and make the tool fail. */ + * privileges and cannot write it, then log about the issue, and proceed without + * failing. (EROFS is treated as a permission problem here, since that's how + * container managers usually protected their sysctls.) In all other cases log an + * error and make the tool fail. */ - if (IN_SET(k, -EPERM, -EACCES, -EROFS, -ENOENT) || option->ignore_failure) - log_notice_errno(k, "Couldn't write '%s' to '%s', ignoring: %m", option->value, option->key); + if (option->ignore_failure || k == -EROFS || ERRNO_IS_PRIVILEGE(k)) + log_debug_errno(k, "Couldn't write '%s' to '%s', ignoring: %m", option->value, option->key); + else if (k == -ENOENT) + log_info_errno(k, "Couldn't write '%s' to '%s', ignoring: %m", option->value, option->key); else { log_error_errno(k, "Couldn't write '%s' to '%s': %m", option->value, option->key); if (r == 0) @@ -122,7 +125,7 @@ static bool test_prefix(const char *p) { return false; } -static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ignore_enoent) { +static int parse_file(OrderedHashmap **sysctl_options, const char *path, bool ignore_enoent) { _cleanup_fclose_ FILE *f = NULL; unsigned c = 0; int r; @@ -183,7 +186,10 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign if (!test_prefix(p)) continue; - existing = ordered_hashmap_get(sysctl_options, p); + if (ordered_hashmap_ensure_allocated(sysctl_options, &option_hash_ops) < 0) + return log_oom(); + + existing = ordered_hashmap_get(*sysctl_options, p); if (existing) { if (streq(value, existing->value)) { existing->ignore_failure = existing->ignore_failure || ignore_failure; @@ -191,14 +197,14 @@ static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ign } log_debug("Overwriting earlier assignment of %s at '%s:%u'.", p, path, c); - option_free(ordered_hashmap_remove(sysctl_options, p)); + option_free(ordered_hashmap_remove(*sysctl_options, p)); } new_option = option_new(p, value, ignore_failure); if (!new_option) return log_oom(); - k = ordered_hashmap_put(sysctl_options, new_option->key, new_option); + k = ordered_hashmap_put(*sysctl_options, new_option->key, new_option); if (k < 0) return log_error_errno(k, "Failed to add sysctl variable %s to hashmap: %m", p); @@ -320,17 +326,13 @@ static int run(int argc, char *argv[]) { umask(0022); - sysctl_options = ordered_hashmap_new(&option_hash_ops); - if (!sysctl_options) - return log_oom(); - if (argc > optind) { int i; r = 0; for (i = optind; i < argc; i++) { - k = parse_file(sysctl_options, argv[i], false); + k = parse_file(&sysctl_options, argv[i], false); if (k < 0 && r == 0) r = k; } @@ -349,7 +351,7 @@ static int run(int argc, char *argv[]) { } STRV_FOREACH(f, files) { - k = parse_file(sysctl_options, *f, true); + k = parse_file(&sysctl_options, *f, true); if (k < 0 && r == 0) r = k; }