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