diff options
52 files changed, 484 insertions, 300 deletions
diff --git a/man/coredump.conf.xml b/man/coredump.conf.xml index b08d732adb..29ac35142a 100644 --- a/man/coredump.conf.xml +++ b/man/coredump.conf.xml @@ -24,6 +24,8 @@ <refsynopsisdiv> <para><simplelist> <member><filename>/etc/systemd/coredump.conf</filename></member> + <member><filename>/run/systemd/coredump.conf</filename></member> + <member><filename>/usr/lib/systemd/coredump.conf</filename></member> <member><filename>/etc/systemd/coredump.conf.d/*.conf</filename></member> <member><filename>/run/systemd/coredump.conf.d/*.conf</filename></member> <member><filename>/usr/lib/systemd/coredump.conf.d/*.conf</filename></member> diff --git a/man/homed.conf.xml b/man/homed.conf.xml index a6c070cb53..9dfcfb6296 100644 --- a/man/homed.conf.xml +++ b/man/homed.conf.xml @@ -24,6 +24,8 @@ <refsynopsisdiv> <para><simplelist> <member><filename>/etc/systemd/homed.conf</filename></member> + <member><filename>/run/systemd/homed.conf</filename></member> + <member><filename>/usr/lib/systemd/homed.conf</filename></member> <member><filename>/etc/systemd/homed.conf.d/*.conf</filename></member> <member><filename>/run/systemd/homed.conf.d/*.conf</filename></member> <member><filename>/usr/lib/systemd/homed.conf.d/*.conf</filename></member> diff --git a/man/journal-remote.conf.xml b/man/journal-remote.conf.xml index 1cf18c3cd8..44e056ab49 100644 --- a/man/journal-remote.conf.xml +++ b/man/journal-remote.conf.xml @@ -29,6 +29,8 @@ <refsynopsisdiv> <para><simplelist> <member><filename>/etc/systemd/journal-remote.conf</filename></member> + <member><filename>/run/systemd/journal-remote.conf</filename></member> + <member><filename>/usr/lib/systemd/journal-remote.conf</filename></member> <member><filename>/etc/systemd/journal-remote.conf.d/*.conf</filename></member> <member><filename>/run/systemd/journal-remote.conf.d/*.conf</filename></member> <member><filename>/usr/lib/systemd/journal-remote.conf.d/*.conf</filename></member> diff --git a/man/journal-upload.conf.xml b/man/journal-upload.conf.xml index 66ea0dca6c..7d3f22f96b 100644 --- a/man/journal-upload.conf.xml +++ b/man/journal-upload.conf.xml @@ -23,6 +23,8 @@ <refsynopsisdiv> <para><filename>/etc/systemd/journal-upload.conf</filename></para> + <para><filename>/run/systemd/journal-upload.conf</filename></para> + <para><filename>/usr/lib/systemd/journal-upload.conf</filename></para> <para><filename>/etc/systemd/journal-upload.conf.d/*.conf</filename></para> <para><filename>/run/systemd/journal-upload.conf.d/*.conf</filename></para> <para><filename>/usr/lib/systemd/journal-upload.conf.d/*.conf</filename></para> diff --git a/man/kernel-install.xml b/man/kernel-install.xml index 519829579f..168776b4d3 100644 --- a/man/kernel-install.xml +++ b/man/kernel-install.xml @@ -510,8 +510,12 @@ <para><varname>$KERNEL_INSTALL_CONF_ROOT</varname> can be set to override the location of the configuration files read by <command>kernel-install</command>. When set, - <filename>install.conf</filename>, <filename>entry-token</filename>, and other files will be - read from this directory.</para> + <filename>install.conf</filename>, <filename>entry-token</filename>, and other files will be read from + this directory only. Note that this path is relative to the host, and in particular <emphasis>symlinks + in this directory are resolved relative to the host</emphasis>, even if + <option>--root=<replaceable>root</replaceable></option> is used. This means that it is generally + <emphasis>not</emphasis> correct to use this variable to specify a directory underneath + <replaceable>root</replaceable> if symlinks are used there.</para> <para><varname>$KERNEL_INSTALL_PLUGINS</varname> can be set to override the list of plugins executed by <command>kernel-install</command>. The argument is a whitespace-separated list of paths. @@ -639,14 +643,23 @@ </varlistentry> <varlistentry> <term><filename>/etc/kernel/install.conf</filename></term> + <term><filename>/run/kernel/install.conf</filename></term> + <term><filename>/usr/local/lib/kernel/install.conf</filename></term> <term><filename>/usr/lib/kernel/install.conf</filename></term> + <term><filename>/etc/kernel/install.conf.d/*.conf</filename></term> + <term><filename>/run/kernel/install.conf.d/*.conf</filename></term> + <term><filename>/usr/local/lib/kernel/install.conf.d/*.conf</filename></term> + <term><filename>/usr/lib/kernel/install.conf.d/*.conf</filename></term> <listitem> <para>Configuration file with options for <command>kernel-install</command>, as a series of <varname>KEY=</varname><replaceable>VALUE</replaceable> assignments, compatible with shell syntax, following the same rules as described in <citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>. The first of the files that is found will be used. <varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be - used to override the search path; see below for details.</para> + used to override the search path; see below for details. Drop-in files may also be used + to extend the configuration with overrides, see + <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>. + </para> <para>Currently, the following keys are supported: <varname>MACHINE_ID=</varname>, diff --git a/man/logind.conf.xml b/man/logind.conf.xml index d74c9b410f..ec16059065 100644 --- a/man/logind.conf.xml +++ b/man/logind.conf.xml @@ -27,6 +27,8 @@ <refsynopsisdiv> <para><simplelist> <member><filename>/etc/systemd/logind.conf</filename></member> + <member><filename>/run/systemd/logind.conf</filename></member> + <member><filename>/usr/lib/systemd/logind.conf</filename></member> <member><filename>/etc/systemd/logind.conf.d/*.conf</filename></member> <member><filename>/run/systemd/logind.conf.d/*.conf</filename></member> <member><filename>/usr/lib/systemd/logind.conf.d/*.conf</filename></member> diff --git a/man/networkd.conf.xml b/man/networkd.conf.xml index 2ab5cf1d79..f7b3b4711c 100644 --- a/man/networkd.conf.xml +++ b/man/networkd.conf.xml @@ -29,6 +29,8 @@ <refsynopsisdiv> <para><simplelist> <member><filename>/etc/systemd/networkd.conf</filename></member> + <member><filename>/run/systemd/networkd.conf</filename></member> + <member><filename>/usr/lib/systemd/networkd.conf</filename></member> <member><filename>/etc/systemd/networkd.conf.d/*.conf</filename></member> <member><filename>/usr/lib/systemd/networkd.conf.d/*.conf</filename></member> </simplelist></para> diff --git a/man/oomd.conf.xml b/man/oomd.conf.xml index 1c25996498..b099f8f546 100644 --- a/man/oomd.conf.xml +++ b/man/oomd.conf.xml @@ -24,7 +24,10 @@ <refsynopsisdiv> <para><simplelist> <member><filename>/etc/systemd/oomd.conf</filename></member> + <member><filename>/run/systemd/oomd.conf</filename></member> + <member><filename>/usr/lib/systemd/oomd.conf</filename></member> <member><filename>/etc/systemd/oomd.conf.d/*.conf</filename></member> + <member><filename>/run/systemd/oomd.conf.d/*.conf</filename></member> <member><filename>/usr/lib/systemd/oomd.conf.d/*.conf</filename></member> </simplelist></para> </refsynopsisdiv> diff --git a/man/pstore.conf.xml b/man/pstore.conf.xml index 3216a4c27b..d6b6c4b1d7 100644 --- a/man/pstore.conf.xml +++ b/man/pstore.conf.xml @@ -22,10 +22,14 @@ </refnamediv> <refsynopsisdiv> - <para> - <filename>/etc/systemd/pstore.conf</filename> - <filename>/etc/systemd/pstore.conf.d/*</filename> - </para> + <para><simplelist> + <member><filename>/etc/systemd/pstore.conf</filename></member> + <member><filename>/run/systemd/pstore.conf</filename></member> + <member><filename>/usr/lib/systemd/pstore.conf</filename></member> + <member><filename>/etc/systemd/pstore.conf.d/*.conf</filename></member> + <member><filename>/run/systemd/pstore.conf.d/*.conf</filename></member> + <member><filename>/usr/lib/systemd/pstore.conf.d/*.conf</filename></member> + </simplelist></para> </refsynopsisdiv> <refsect1> diff --git a/man/resolved.conf.xml b/man/resolved.conf.xml index 25750c7eb7..95b35537d6 100644 --- a/man/resolved.conf.xml +++ b/man/resolved.conf.xml @@ -27,6 +27,8 @@ <refsynopsisdiv> <para><simplelist> <member><filename>/etc/systemd/resolved.conf</filename></member> + <member><filename>/run/systemd/resolved.conf</filename></member> + <member><filename>/usr/lib/systemd/resolved.conf</filename></member> <member><filename>/etc/systemd/resolved.conf.d/*.conf</filename></member> <member><filename>/run/systemd/resolved.conf.d/*.conf</filename></member> <member><filename>/usr/lib/systemd/resolved.conf.d/*.conf</filename></member> diff --git a/man/standard-conf.xml b/man/standard-conf.xml index c3cebdac5f..f54475f306 100644 --- a/man/standard-conf.xml +++ b/man/standard-conf.xml @@ -50,14 +50,19 @@ <title>Configuration Directories and Precedence</title> <para>The default configuration is set during compilation, so configuration is only needed when it is - necessary to deviate from those defaults. The main configuration file is either in - <filename>/usr/lib/systemd/</filename> or <filename>/etc/systemd/</filename> and contains commented out - entries showing the defaults as a guide to the administrator. Local overrides can be created by creating - drop-ins, as described below. The main configuration file can also be edited for this purpose (or a copy - in <filename>/etc/</filename> if it's shipped in <filename>/usr/</filename>) however using drop-ins for - local configuration is recommended over modifications to the main configuration file.</para> + necessary to deviate from those defaults. The main configuration file is loaded from one of the + listed directories in order of priority, only the first file found is used: + <filename>/etc/systemd/</filename>, + <filename>/run/systemd/</filename>, + <filename>/usr/local/lib/systemd/</filename>, + <filename>/usr/lib/systemd/</filename>. + The vendor version of the file contains commented out entries showing the defaults as a guide to the + administrator. Local overrides can also be created by creating drop-ins, as described below. The main + configuration file can also be edited for this purpose (or a copy in <filename>/etc/</filename> if it's + shipped under <filename>/usr/</filename>), however using drop-ins for local configuration is recommended + over modifications to the main configuration file.</para> - <para>In addition to the "main" configuration file, drop-in configuration snippets are read from + <para>In addition to the main configuration file, drop-in configuration snippets are read from <filename>/usr/lib/systemd/*.conf.d/</filename>, <filename>/usr/local/lib/systemd/*.conf.d/</filename>, and <filename>/etc/systemd/*.conf.d/</filename>. Those drop-ins have higher precedence and override the main configuration file. Files in the <filename>*.conf.d/</filename> configuration subdirectories are diff --git a/man/systemd-sleep.conf.xml b/man/systemd-sleep.conf.xml index 1abec4f34f..411577d519 100644 --- a/man/systemd-sleep.conf.xml +++ b/man/systemd-sleep.conf.xml @@ -24,6 +24,8 @@ <refsynopsisdiv> <para><simplelist> <member><filename>/etc/systemd/sleep.conf</filename></member> + <member><filename>/run/systemd/sleep.conf</filename></member> + <member><filename>/usr/lib/systemd/sleep.conf</filename></member> <member><filename>/etc/systemd/sleep.conf.d/*.conf</filename></member> <member><filename>/run/systemd/sleep.conf.d/*.conf</filename></member> <member><filename>/usr/lib/systemd/sleep.conf.d/*.conf</filename></member> diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index 31b6421399..e6611d04e7 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -28,12 +28,16 @@ <refsynopsisdiv> <para><filename>/etc/systemd/system.conf</filename>, + <filename>/run/systemd/system.conf</filename>, + <filename>/usr/lib/systemd/system.conf</filename>, <filename>/etc/systemd/system.conf.d/*.conf</filename>, <filename>/run/systemd/system.conf.d/*.conf</filename>, <filename>/usr/lib/systemd/system.conf.d/*.conf</filename></para> <para><filename>~/.config/systemd/user.conf</filename>, <filename>/etc/systemd/user.conf</filename>, + <filename>/run/systemd/user.conf</filename>, + <filename>/usr/lib/systemd/user.conf</filename>, <filename>/etc/systemd/user.conf.d/*.conf</filename>, <filename>/run/systemd/user.conf.d/*.conf</filename>, <filename>/usr/lib/systemd/user.conf.d/*.conf</filename></para> @@ -44,9 +48,10 @@ <para>When run as a system instance, <command>systemd</command> interprets the configuration file <filename>system.conf</filename> and the files in <filename>system.conf.d</filename> directories; when - run as a user instance, it interprets the configuration file <filename>user.conf</filename> (either in - the home directory of the user, or if not found, under <filename>/etc/systemd/</filename>) and the files - in <filename>user.conf.d</filename> directories. These configuration files contain a few settings + run as a user instance, it interprets the configuration file <filename>user.conf</filename> (in order of + priority, in the home directory of the user and under <filename>/etc/systemd/</filename>, + <filename>/run/systemd/</filename>, and <filename>/usr/lib/systemd/</filename>) and the files in + <filename>user.conf.d</filename> directories. These configuration files contain a few settings controlling basic manager operations.</para> <para>See diff --git a/man/timesyncd.conf.xml b/man/timesyncd.conf.xml index 498bfa330b..248fd88b77 100644 --- a/man/timesyncd.conf.xml +++ b/man/timesyncd.conf.xml @@ -24,6 +24,8 @@ <refsynopsisdiv> <para><simplelist> <member><filename>/etc/systemd/timesyncd.conf</filename></member> + <member><filename>/run/systemd/timesyncd.conf</filename></member> + <member><filename>/usr/lib/systemd/timesyncd.conf</filename></member> <member><filename>/etc/systemd/timesyncd.conf.d/*.conf</filename></member> <member><filename>/run/systemd/timesyncd.conf.d/*.conf</filename></member> <member><filename>/usr/lib/systemd/timesyncd.conf.d/*.conf</filename></member> diff --git a/src/analyze/analyze-cat-config.c b/src/analyze/analyze-cat-config.c index 073bc94018..b480d4a009 100644 --- a/src/analyze/analyze-cat-config.c +++ b/src/analyze/analyze-cat-config.c @@ -4,7 +4,6 @@ #include "analyze-cat-config.h" #include "conf-files.h" #include "constants.h" -#include "nulstr-util.h" #include "path-util.h" #include "pretty-print.h" #include "strv.h" @@ -23,7 +22,7 @@ int verb_cat_config(int argc, char *argv[], void *userdata) { print_separator(); if (path_is_absolute(*arg)) { - NULSTR_FOREACH(dir, CONF_PATHS_NULSTR("")) { + FOREACH_STRING(dir, CONF_PATHS("")) { t = path_startswith(*arg, dir); if (t) break; diff --git a/src/backlight/backlight.c b/src/backlight/backlight.c index 6a2ad17fbf..6126405994 100644 --- a/src/backlight/backlight.c +++ b/src/backlight/backlight.c @@ -175,7 +175,7 @@ static int validate_device(sd_device *device) { /* Verify whether we should actually care for a specific backlight device. For backlight devices * there might be multiple ways to access the same control: "firmware" (i.e. ACPI), "platform" - * (i.e. via the machine's EC) and "raw" (via the graphics card). In general we should prefer + * (i.e. via the machine's EC), and "raw" (via the graphics card). In general we should prefer * "firmware" (i.e. ACPI) or "platform" access over "raw" access, in order not to confuse the * BIOS/EC, and compatibility with possible low-level hotkey handling of screen brightness. The * kernel will already make sure to expose only one of "firmware" and "platform" for the same @@ -239,8 +239,8 @@ static int validate_device(sd_device *device) { /* If the system has multiple graphics cards, then we cannot associate platform * devices on non-PCI bus (especially WMI bus) with PCI devices. Let's ignore all * backlight devices that do not have the same parent PCI device. */ - log_debug("Found multiple graphics cards on PCI bus. " - "Skipping to associate platform backlight devices on non-PCI bus."); + log_debug("Found multiple graphics cards on PCI bus; " + "skipping deduplication of platform backlight devices not on PCI bus."); r = sd_device_enumerator_add_match_parent(enumerate, parent); if (r < 0) diff --git a/src/basic/conf-files.c b/src/basic/conf-files.c index 9cb66c099b..7fdcc71356 100644 --- a/src/basic/conf-files.c +++ b/src/basic/conf-files.c @@ -369,7 +369,7 @@ int conf_files_list_dropins( assert(dirs); suffix = strjoina("/", dropin_dirname); - r = strv_extend_strv_concat(&dropin_dirs, (char**) dirs, suffix); + r = strv_extend_strv_concat(&dropin_dirs, dirs, suffix); if (r < 0) return r; diff --git a/src/basic/constants.h b/src/basic/constants.h index ef3af88a9d..e70817c51f 100644 --- a/src/basic/constants.h +++ b/src/basic/constants.h @@ -64,18 +64,12 @@ "/usr/local/lib/" n "\0" \ "/usr/lib/" n "\0" -#define CONF_PATHS_USR(n) \ +#define CONF_PATHS(n) \ "/etc/" n, \ "/run/" n, \ "/usr/local/lib/" n, \ "/usr/lib/" n -#define CONF_PATHS(n) \ - CONF_PATHS_USR(n) - -#define CONF_PATHS_USR_STRV(n) \ - STRV_MAKE(CONF_PATHS_USR(n)) - #define CONF_PATHS_STRV(n) \ STRV_MAKE(CONF_PATHS(n)) diff --git a/src/basic/path-lookup.c b/src/basic/path-lookup.c index fbcb1edadc..e7fc4a7f06 100644 --- a/src/basic/path-lookup.c +++ b/src/basic/path-lookup.c @@ -214,7 +214,7 @@ static char** user_dirs( persistent_config) < 0) return NULL; - if (strv_extend_strv_concat(&res, config_dirs, "/systemd/user") < 0) + if (strv_extend_strv_concat(&res, (const char* const*) config_dirs, "/systemd/user") < 0) return NULL; /* global config has lower priority than the user config of the same type */ @@ -232,7 +232,7 @@ static char** user_dirs( data_home) < 0) return NULL; - if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0) + if (strv_extend_strv_concat(&res, (const char* const*) data_dirs, "/systemd/user") < 0) return NULL; if (strv_extend_strv(&res, (char**) user_data_unit_paths, false) < 0) diff --git a/src/basic/strv.c b/src/basic/strv.c index 208108d6c0..d081821a86 100644 --- a/src/basic/strv.c +++ b/src/basic/strv.c @@ -242,21 +242,19 @@ rollback: return -ENOMEM; } -int strv_extend_strv_concat(char ***a, char * const *b, const char *suffix) { +int strv_extend_strv_biconcat(char ***a, const char *prefix, const char* const *b, const char *suffix) { int r; STRV_FOREACH(s, b) { char *v; - v = strjoin(*s, suffix); + v = strjoin(strempty(prefix), *s, suffix); if (!v) return -ENOMEM; - r = strv_push(a, v); - if (r < 0) { - free(v); + r = strv_consume(a, v); + if (r < 0) return r; - } } return 0; diff --git a/src/basic/strv.h b/src/basic/strv.h index 91337b9287..169737d1d8 100644 --- a/src/basic/strv.h +++ b/src/basic/strv.h @@ -43,7 +43,10 @@ int strv_copy_unless_empty(char * const *l, char ***ret); size_t strv_length(char * const *l) _pure_; int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates); -int strv_extend_strv_concat(char ***a, char * const *b, const char *suffix); +int strv_extend_strv_biconcat(char ***a, const char *prefix, const char* const *b, const char *suffix); +static inline int strv_extend_strv_concat(char ***a, const char* const *b, const char *suffix) { + return strv_extend_strv_biconcat(a, NULL, b, suffix); +} int strv_prepend(char ***l, const char *value); /* _with_size() are lower-level functions where the size can be provided externally, diff --git a/src/boot/bootctl-install.c b/src/boot/bootctl-install.c index a0a474537e..b805fa8f7a 100644 --- a/src/boot/bootctl-install.c +++ b/src/boot/bootctl-install.c @@ -81,44 +81,52 @@ static int load_etc_machine_info(void) { return 0; } -static int load_kernel_install_conf_one(const char *dir) { - _cleanup_free_ char *layout = NULL, *p = NULL; +static int load_kernel_install_conf(void) { + _cleanup_free_ char *layout = NULL; + const ConfigTableItem items[] = { + { NULL, "layout", config_parse_string, 0, &layout }, + {} + }; int r; - assert(dir); - - p = path_join(arg_root, dir, "install.conf"); - if (!p) - return log_oom(); - - r = parse_env_file(NULL, p, "layout", &layout); - if (r == -ENOENT) - return 0; + const char *conf_root = getenv("KERNEL_INSTALL_CONF_ROOT"); + + if (conf_root) { + _cleanup_free_ char *conf = NULL; + + conf = path_join(conf_root, "install.conf"); + if (!conf) + return log_oom(); + + r = config_parse_many( + STRV_MAKE_CONST(conf), + STRV_MAKE_CONST(conf_root), + "install.conf.d", + /* root= */ NULL, /* $KERNEL_INSTALL_CONF_ROOT and --root are independent */ + /* sections= */ NULL, + config_item_table_lookup, items, + CONFIG_PARSE_WARN, + /* userdata = */ NULL, + /* ret_stats_by_path= */ NULL, + /* ret_dropin_files= */ NULL); + } else + r = config_parse_standard_file_with_dropins_full( + arg_root, + "kernel/install.conf", + /* sections= */ NULL, + config_item_table_lookup, items, + CONFIG_PARSE_WARN, + /* userdata = */ NULL, + /* ret_stats_by_path= */ NULL, + /* ret_dropin_files= */ NULL); if (r < 0) - return log_error_errno(r, "Failed to parse %s: %m", p); + return r == -ENOENT ? 0 : r; if (!isempty(layout)) { - log_debug("layout=%s is specified in %s.", layout, p); + log_debug("layout=%s is specified in config.", layout); free_and_replace(arg_install_layout, layout); } - return 1; -} - -static int load_kernel_install_conf(void) { - const char *conf_root; - int r; - - conf_root = getenv("KERNEL_INSTALL_CONF_ROOT"); - if (conf_root) - return load_kernel_install_conf_one(conf_root); - - FOREACH_STRING(p, "/etc/kernel", "/usr/lib/kernel") { - r = load_kernel_install_conf_one(p); - if (r != 0) - return r; - } - return 0; } diff --git a/src/core/main.c b/src/core/main.c index fa0dc3191a..07ec98252e 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -736,11 +736,12 @@ static int parse_config_file(void) { }; if (arg_runtime_scope == RUNTIME_SCOPE_SYSTEM) - (void) config_parse_config_file("system.conf", - "Manager\0", - config_item_table_lookup, items, - CONFIG_PARSE_WARN, - NULL); + (void) config_parse_standard_file_with_dropins( + "systemd/system.conf", + "Manager\0", + config_item_table_lookup, items, + CONFIG_PARSE_WARN, + /* userdata= */ NULL); else { _cleanup_strv_free_ char **files = NULL, **dirs = NULL; int r; diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index 51218fc4c8..b87bc52bde 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -178,8 +178,8 @@ static int parse_config(void) { int r; - r = config_parse_config_file( - "coredump.conf", + r = config_parse_standard_file_with_dropins( + "systemd/coredump.conf", "Coredump\0", config_item_table_lookup, items, diff --git a/src/environment-d-generator/environment-d-generator.c b/src/environment-d-generator/environment-d-generator.c index fa2c54af31..236cf38597 100644 --- a/src/environment-d-generator/environment-d-generator.c +++ b/src/environment-d-generator/environment-d-generator.c @@ -17,7 +17,7 @@ static int environment_dirs(char ***ret) { _cleanup_free_ char *c = NULL; int r; - dirs = strv_new(CONF_PATHS_USR("environment.d"), NULL); + dirs = strv_new(CONF_PATHS("environment.d")); if (!dirs) return -ENOMEM; diff --git a/src/home/homed-conf.c b/src/home/homed-conf.c index ffa4bb3bd7..3f74096b64 100644 --- a/src/home/homed-conf.c +++ b/src/home/homed-conf.c @@ -9,9 +9,12 @@ int manager_parse_config_file(Manager *m) { assert(m); - return config_parse_config_file("homed.conf", "Home\0", - config_item_perf_lookup, homed_gperf_lookup, - CONFIG_PARSE_WARN, m); + return config_parse_standard_file_with_dropins( + "systemd/homed.conf", + "Home\0", + config_item_perf_lookup, homed_gperf_lookup, + CONFIG_PARSE_WARN, + m); } DEFINE_CONFIG_PARSE_ENUM(config_parse_default_storage, user_storage, UserStorage, "Failed to parse default storage setting"); diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c index 7431403e4b..74bf6cfcc8 100644 --- a/src/journal-remote/journal-remote-main.c +++ b/src/journal-remote/journal-remote-main.c @@ -746,9 +746,12 @@ static int parse_config(void) { {} }; - return config_parse_config_file("journal-remote.conf", "Remote\0", - config_item_table_lookup, items, - CONFIG_PARSE_WARN, NULL); + return config_parse_standard_file_with_dropins( + "systemd/journal-remote.conf", + "Remote\0", + config_item_table_lookup, items, + CONFIG_PARSE_WARN, + /* userdata= */ NULL); } static int help(void) { diff --git a/src/journal-remote/journal-upload.c b/src/journal-remote/journal-upload.c index 50fa31a133..1198791ed1 100644 --- a/src/journal-remote/journal-upload.c +++ b/src/journal-remote/journal-upload.c @@ -531,9 +531,12 @@ static int parse_config(void) { {} }; - return config_parse_config_file("journal-upload.conf", "Upload\0", - config_item_table_lookup, items, - CONFIG_PARSE_WARN, NULL); + return config_parse_standard_file_with_dropins( + "systemd/journal-upload.conf", + "Upload\0", + config_item_table_lookup, items, + CONFIG_PARSE_WARN, + /* userdata= */ NULL); } static int help(void) { diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index 9e1ca08d23..285aea988a 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -1884,16 +1884,21 @@ static int parse_proc_cmdline_item(const char *key, const char *value, void *dat } static int server_parse_config_file(Server *s) { - const char *conf_file = "journald.conf"; + const char *conf_file; assert(s); if (s->namespace) - conf_file = strjoina("journald@", s->namespace, ".conf"); - - return config_parse_config_file(conf_file, "Journal\0", - config_item_perf_lookup, journald_gperf_lookup, - CONFIG_PARSE_WARN, s); + conf_file = strjoina("systemd/journald@", s->namespace, ".conf"); + else + conf_file = "systemd/journald.conf"; + + return config_parse_standard_file_with_dropins( + conf_file, + "Journal\0", + config_item_perf_lookup, journald_gperf_lookup, + CONFIG_PARSE_WARN, + /* userdata= */ s); } static int server_dispatch_sync(sd_event_source *es, usec_t t, void *userdata) { diff --git a/src/kernel-install/kernel-install.c b/src/kernel-install/kernel-install.c index 4df52c8342..cf1bb5c3af 100644 --- a/src/kernel-install/kernel-install.c +++ b/src/kernel-install/kernel-install.c @@ -431,64 +431,59 @@ static int context_load_environment(Context *c) { return 0; } -static int context_load_install_conf_one(Context *c, const char *path) { - _cleanup_fclose_ FILE *f = NULL; - _cleanup_free_ char - *conf = NULL, *machine_id = NULL, *boot_root = NULL, *layout = NULL, - *initrd_generator = NULL, *uki_generator = NULL; +static int context_load_install_conf(Context *c) { + _cleanup_free_ char *machine_id = NULL, *boot_root = NULL, *layout = NULL, + *initrd_generator = NULL, *uki_generator = NULL; + const ConfigTableItem items[] = { + { NULL, "MACHINE_ID", config_parse_string, 0, &machine_id }, + { NULL, "BOOT_ROOT", config_parse_string, 0, &boot_root }, + { NULL, "layout", config_parse_string, 0, &layout }, + { NULL, "initrd_generator", config_parse_string, 0, &initrd_generator }, + { NULL, "uki_generator", config_parse_string, 0, &uki_generator }, + {} + }; int r; assert(c); - assert(path); - conf = path_join(path, "install.conf"); - if (!conf) - return log_oom(); - - r = chase_and_fopenat_unlocked(c->rfd, conf, CHASE_AT_RESOLVE_IN_ROOT, "re", NULL, &f); - if (r == -ENOENT) - return 0; - if (r < 0) - return log_error_errno(r, "Failed to chase %s: %m", conf); + if (c->conf_root) { + _cleanup_free_ char *conf = NULL; - log_debug("Loading %s…", conf); + conf = path_join(c->conf_root, "install.conf"); + if (!conf) + return log_oom(); - r = parse_env_file(f, conf, - "MACHINE_ID", &machine_id, - "BOOT_ROOT", &boot_root, - "layout", &layout, - "initrd_generator", &initrd_generator, - "uki_generator", &uki_generator); + r = config_parse_many( + STRV_MAKE_CONST(conf), + STRV_MAKE_CONST(c->conf_root), + "install.conf.d", + /* root= */ NULL, /* $KERNEL_INSTALL_CONF_ROOT and --root are independent */ + /* sections= */ NULL, + config_item_table_lookup, items, + CONFIG_PARSE_WARN, + /* userdata = */ NULL, + /* ret_stats_by_path= */ NULL, + /* ret_dropin_files= */ NULL); + } else + r = config_parse_standard_file_with_dropins_full( + arg_root, + "kernel/install.conf", + /* sections= */ NULL, + config_item_table_lookup, items, + CONFIG_PARSE_WARN, + /* userdata = */ NULL, + /* ret_stats_by_path= */ NULL, + /* ret_dropin_files= */ NULL); if (r < 0) - return log_error_errno(r, "Failed to parse '%s': %m", conf); - - (void) context_set_machine_id(c, machine_id, conf); - (void) context_set_boot_root(c, boot_root, conf); - (void) context_set_layout(c, layout, conf); - (void) context_set_initrd_generator(c, initrd_generator, conf); - (void) context_set_uki_generator(c, uki_generator, conf); - - log_debug("Loaded %s.", conf); - return 1; -} - -static int context_load_install_conf(Context *c) { - int r; - - assert(c); + return r == -ENOENT ? 0 : r; - if (c->conf_root) { - r = context_load_install_conf_one(c, c->conf_root); - if (r != 0) - return r; - } - - FOREACH_STRING(p, "/etc/kernel", "/usr/lib/kernel") { - r = context_load_install_conf_one(c, p); - if (r != 0) - return r; - } + (void) context_set_machine_id(c, machine_id, "config"); + (void) context_set_boot_root(c, boot_root, "config"); + (void) context_set_layout(c, layout, "config"); + (void) context_set_initrd_generator(c, initrd_generator, "config"); + (void) context_set_uki_generator(c, uki_generator, "config"); + log_debug("Loaded config."); return 0; } @@ -511,7 +506,7 @@ static int context_load_machine_info(Context *c) { if (r < 0 && r != -ENXIO) log_warning_errno(r, "Failed to read $KERNEL_INSTALL_READ_MACHINE_INFO, assuming yes: %m"); if (r == 0) { - log_debug("Skipping to read /etc/machine-info."); + log_debug("Skipping reading of /etc/machine-info."); return 0; } diff --git a/src/kernel-install/test-kernel-install.sh b/src/kernel-install/test-kernel-install.sh index 338d811957..0e41979878 100755 --- a/src/kernel-install/test-kernel-install.sh +++ b/src/kernel-install/test-kernel-install.sh @@ -125,7 +125,8 @@ grep -qE 'initrd' "$BOOT_ROOT/the-token/1.1.1/initrd" # Install UKI if [ -f "$ukify" ]; then - cat >>"$D/sources/install.conf" <<EOF + mkdir "$D/sources/install.conf.d" + cat >>"$D/sources/install.conf.d/override.conf" <<EOF layout=uki uki_generator=ukify EOF @@ -146,6 +147,8 @@ EOF "$ukify" inspect "$uki" | grep -qE '^.initrd' "$ukify" inspect "$uki" | grep -qE '^.linux' "$ukify" inspect "$uki" | grep -qE '^.dtb' + + rm "$D/sources/install.conf.d/override.conf" fi # Test bootctl diff --git a/src/login/logind-core.c b/src/login/logind-core.c index 40d09cd532..54febdadd7 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -82,9 +82,12 @@ void manager_reset_config(Manager *m) { int manager_parse_config_file(Manager *m) { assert(m); - return config_parse_config_file("logind.conf", "Login\0", - config_item_perf_lookup, logind_gperf_lookup, - CONFIG_PARSE_WARN, m); + return config_parse_standard_file_with_dropins( + "systemd/logind.conf", + "Login\0", + config_item_perf_lookup, logind_gperf_lookup, + CONFIG_PARSE_WARN, + /* userdata= */ m); } int manager_add_device(Manager *m, const char *sysfs, bool master, Device **ret_device) { diff --git a/src/network/networkd-conf.c b/src/network/networkd-conf.c index 063732a3b4..0f7015eb25 100644 --- a/src/network/networkd-conf.c +++ b/src/network/networkd-conf.c @@ -14,14 +14,15 @@ int manager_parse_config_file(Manager *m) { assert(m); - r = config_parse_config_file("networkd.conf", - "Network\0" - "DHCPv4\0" - "DHCPv6\0" - "DHCP\0", - config_item_perf_lookup, networkd_gperf_lookup, - CONFIG_PARSE_WARN, - m); + r = config_parse_standard_file_with_dropins( + "systemd/networkd.conf", + "Network\0" + "DHCPv4\0" + "DHCPv6\0" + "DHCP\0", + config_item_perf_lookup, networkd_gperf_lookup, + CONFIG_PARSE_WARN, + /* userdata= */ m); if (r < 0) return r; diff --git a/src/oom/oomd.c b/src/oom/oomd.c index b43635d6d4..0d8031052e 100644 --- a/src/oom/oomd.c +++ b/src/oom/oomd.c @@ -31,9 +31,12 @@ static int parse_config(void) { {} }; - return config_parse_config_file("oomd.conf", "OOM\0", - config_item_table_lookup, items, - CONFIG_PARSE_WARN, NULL); + return config_parse_standard_file_with_dropins( + "systemd/oomd.conf", + "OOM\0", + config_item_table_lookup, items, + CONFIG_PARSE_WARN, + /* userdata= */ NULL); } static int help(void) { diff --git a/src/partition/repart.c b/src/partition/repart.c index 404e1b40b4..adf1f0e696 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -8010,7 +8010,7 @@ static int run(int argc, char *argv[]) { if (!d) return log_oom(); - r = search_and_access(d, F_OK, NULL, CONF_PATHS_USR_STRV("systemd/repart/definitions"), &dp); + r = search_and_access(d, F_OK, NULL, CONF_PATHS_STRV("systemd/repart/definitions"), &dp); if (r < 0) return log_error_errno(r, "DDI type '%s' is not defined: %m", arg_make_ddi); diff --git a/src/pstore/pstore.c b/src/pstore/pstore.c index 835348f90e..e2dfc4d1a1 100644 --- a/src/pstore/pstore.c +++ b/src/pstore/pstore.c @@ -77,9 +77,12 @@ static int parse_config(void) { {} }; - return config_parse_config_file("pstore.conf", "PStore\0", - config_item_table_lookup, items, - CONFIG_PARSE_WARN, NULL); + return config_parse_standard_file_with_dropins( + "systemd/pstore.conf", + "PStore\0", + config_item_table_lookup, items, + CONFIG_PARSE_WARN, + /* userdata= */ NULL); } /* File list handling - PStoreEntry is the struct and diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c index 182ac20c3f..b648c3e520 100644 --- a/src/resolve/resolved-conf.c +++ b/src/resolve/resolved-conf.c @@ -570,9 +570,12 @@ int manager_parse_config_file(Manager *m) { assert(m); - r = config_parse_config_file("resolved.conf", "Resolve\0", - config_item_perf_lookup, resolved_gperf_lookup, - CONFIG_PARSE_WARN, m); + r = config_parse_standard_file_with_dropins( + "systemd/resolved.conf", + "Resolve\0", + config_item_perf_lookup, resolved_gperf_lookup, + CONFIG_PARSE_WARN, + /* userdata= */ m); if (r < 0) return r; diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c index 40d3675b7e..e2d3b65f88 100644 --- a/src/shared/conf-parser.c +++ b/src/shared/conf-parser.c @@ -8,6 +8,7 @@ #include <sys/types.h> #include "alloc-util.h" +#include "chase.h" #include "conf-files.h" #include "conf-parser.h" #include "constants.h" @@ -480,6 +481,7 @@ int hashmap_put_stats_by_path(Hashmap **stats_by_path, const char *path, const s } static int config_parse_many_files( + const char *root, const char* const* conf_files, char **files, const char *sections, @@ -502,19 +504,16 @@ static int config_parse_many_files( } STRV_FOREACH(fn, files) { - _cleanup_free_ struct stat *st_dropin = NULL; _cleanup_fclose_ FILE *f = NULL; - int fd; - - f = fopen(*fn, "re"); - if (!f) { - if (errno == ENOENT) - continue; + _cleanup_free_ char *fname = NULL; - return -errno; - } + r = chase_and_fopen_unlocked(*fn, root, CHASE_AT_RESOLVE_IN_ROOT, "re", &fname, &f); + if (r == -ENOENT) + continue; + if (r < 0) + return r; - fd = fileno(f); + int fd = fileno(f); r = ordered_hashmap_ensure_put(&dropins, &config_file_hash_ops_fclose, *fn, f); if (r < 0) { @@ -527,7 +526,7 @@ static int config_parse_many_files( /* Get inodes for all drop-ins. Later we'll verify if main config is a symlink to or is * symlinked as one of them. If so, we skip reading main config file directly. */ - st_dropin = new(struct stat, 1); + _cleanup_free_ struct stat *st_dropin = new(struct stat, 1); if (!st_dropin) return -ENOMEM; @@ -543,13 +542,11 @@ static int config_parse_many_files( STRV_FOREACH(fn, conf_files) { _cleanup_fclose_ FILE *f = NULL; - f = fopen(*fn, "re"); - if (!f) { - if (errno == ENOENT) - continue; - - return -errno; - } + r = chase_and_fopen_unlocked(*fn, root, CHASE_AT_RESOLVE_IN_ROOT, "re", NULL, &f); + if (r == -ENOENT) + continue; + if (r < 0) + return r; if (inodes) { if (fstat(fileno(f), &st) < 0) @@ -561,7 +558,7 @@ static int config_parse_many_files( } } - r = config_parse(NULL, *fn, f, sections, lookup, table, flags, userdata, &st); + r = config_parse(/* unit= */ NULL, *fn, f, sections, lookup, table, flags, userdata, &st); if (r < 0) return r; assert(r > 0); @@ -580,7 +577,7 @@ static int config_parse_many_files( const char *path_dropin; FILE *f_dropin; ORDERED_HASHMAP_FOREACH_KEY(f_dropin, path_dropin, dropins) { - r = config_parse(NULL, path_dropin, f_dropin, sections, lookup, table, flags, userdata, &st); + r = config_parse(/* unit= */ NULL, path_dropin, f_dropin, sections, lookup, table, flags, userdata, &st); if (r < 0) return r; assert(r > 0); @@ -598,56 +595,6 @@ static int config_parse_many_files( return 0; } -/* Parse one main config file located in /etc/$pkgdir and its drop-ins, which is what all systemd daemons - * do. */ -int config_parse_config_file_full( - const char *conf_file, - const char *pkgdir, - const char *sections, - ConfigItemLookup lookup, - const void *table, - ConfigParseFlags flags, - void *userdata) { - - _cleanup_strv_free_ char **dropins = NULL, **dropin_dirs = NULL; - char **conf_paths = CONF_PATHS_STRV(""); - int r; - - assert(conf_file); - assert(pkgdir); - - /* build the dropin dir list */ - dropin_dirs = new0(char*, strv_length(conf_paths) + 1); - if (!dropin_dirs) { - if (flags & CONFIG_PARSE_WARN) - return log_oom(); - return -ENOMEM; - } - - size_t i = 0; - STRV_FOREACH(p, conf_paths) { - char *d; - - d = strjoin(*p, pkgdir, "/", conf_file, ".d"); - if (!d) { - if (flags & CONFIG_PARSE_WARN) - return log_oom(); - return -ENOMEM; - } - - dropin_dirs[i++] = d; - } - - r = conf_files_list_strv(&dropins, ".conf", NULL, 0, (const char**) dropin_dirs); - if (r < 0) - return r; - - const char *sysconf_file = strjoina(SYSCONF_DIR, "/", pkgdir, "/", conf_file); - - return config_parse_many_files(STRV_MAKE_CONST(sysconf_file), dropins, - sections, lookup, table, flags, userdata, NULL); -} - /* Parse each config file in the directories specified as strv. */ int config_parse_many( const char* const* conf_files, @@ -667,14 +614,13 @@ int config_parse_many( assert(conf_file_dirs); assert(dropin_dirname); - assert(sections); assert(table); r = conf_files_list_dropins(&files, dropin_dirname, root, conf_file_dirs); if (r < 0) return r; - r = config_parse_many_files(conf_files, files, sections, lookup, table, flags, userdata, ret_stats_by_path); + r = config_parse_many_files(root, conf_files, files, sections, lookup, table, flags, userdata, ret_stats_by_path); if (r < 0) return r; @@ -684,6 +630,50 @@ int config_parse_many( return 0; } +int config_parse_standard_file_with_dropins_full( + const char *root, + const char *main_file, /* A path like "systemd/frobnicator.conf" */ + const char *sections, + ConfigItemLookup lookup, + const void *table, + ConfigParseFlags flags, + void *userdata, + Hashmap **ret_stats_by_path, + char ***ret_dropin_files) { + + const char* const *conf_paths = (const char* const*) CONF_PATHS_STRV(""); + _cleanup_strv_free_ char **configs = NULL; + int r; + + /* Build the list of main config files */ + r = strv_extend_strv_biconcat(&configs, root, conf_paths, main_file); + if (r < 0) { + if (flags & CONFIG_PARSE_WARN) + log_oom(); + return r; + } + + _cleanup_free_ char *dropin_dirname = strjoin(main_file, ".d"); + if (!dropin_dirname) { + if (flags & CONFIG_PARSE_WARN) + log_oom(); + return -ENOMEM; + } + + return config_parse_many( + (const char* const*) configs, + conf_paths, + dropin_dirname, + root, + sections, + lookup, + table, + flags, + userdata, + ret_stats_by_path, + ret_dropin_files); +} + static int dropins_get_stats_by_path( const char* conf_file, const char* const* conf_file_dirs, diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h index 3057356479..254d6cb70b 100644 --- a/src/shared/conf-parser.h +++ b/src/shared/conf-parser.h @@ -93,31 +93,12 @@ int config_parse( void *userdata, struct stat *ret_stat); /* possibly NULL */ -int config_parse_config_file_full( - const char *conf_file, - const char *pkgdir, - const char *sections, /* nulstr */ - ConfigItemLookup lookup, - const void *table, - ConfigParseFlags flags, - void *userdata); - -static inline int config_parse_config_file( - const char *conf_file, - const char *sections, /* nulstr */ - ConfigItemLookup lookup, - const void *table, - ConfigParseFlags flags, - void *userdata) { - return config_parse_config_file_full(conf_file, "systemd", sections, lookup, table, flags, userdata); -} - int config_parse_many( const char* const* conf_files, /* possibly empty */ const char* const* conf_file_dirs, const char *dropin_dirname, const char *root, - const char *sections, /* nulstr */ + const char *sections, /* nulstr */ ConfigItemLookup lookup, const void *table, ConfigParseFlags flags, @@ -125,6 +106,36 @@ int config_parse_many( Hashmap **ret_stats_by_path, /* possibly NULL */ char ***ret_drop_in_files); /* possibly NULL */ +int config_parse_standard_file_with_dropins_full( + const char *root, + const char *main_file, /* A path like "systemd/frobnicator.conf" */ + const char *sections, + ConfigItemLookup lookup, + const void *table, + ConfigParseFlags flags, + void *userdata, + Hashmap **ret_stats_by_path, /* possibly NULL */ + char ***ret_dropin_files); /* possibly NULL */ + +static inline int config_parse_standard_file_with_dropins( + const char *main_file, /* A path like "systemd/frobnicator.conf" */ + const char *sections, /* nulstr */ + ConfigItemLookup lookup, + const void *table, + ConfigParseFlags flags, + void *userdata) { + return config_parse_standard_file_with_dropins_full( + /* root= */ NULL, + main_file, + sections, + lookup, + table, + flags, + userdata, + /* ret_stats_by_path= */ NULL, + /* ret_dropin_files= */ NULL); +} + int config_get_stats_by_path( const char *suffix, const char *root, diff --git a/src/shared/install.c b/src/shared/install.c index e42f77aa28..81f898f28a 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -3253,8 +3253,8 @@ static int split_pattern_into_name_and_instances(const char *pattern, char **out } static int presets_find_config(RuntimeScope scope, const char *root_dir, char ***files) { - static const char* const system_dirs[] = {CONF_PATHS("systemd/system-preset"), NULL}; - static const char* const user_dirs[] = {CONF_PATHS_USR("systemd/user-preset"), NULL}; + static const char* const system_dirs[] = { CONF_PATHS("systemd/system-preset"), NULL }; + static const char* const user_dirs[] = { CONF_PATHS("systemd/user-preset"), NULL }; const char* const* dirs; assert(scope >= 0); diff --git a/src/shared/pretty-print.c b/src/shared/pretty-print.c index b81d1eb40c..c551ed62e3 100644 --- a/src/shared/pretty-print.c +++ b/src/shared/pretty-print.c @@ -308,7 +308,7 @@ void print_separator(void) { fputs("\n\n", stdout); } -static int guess_type(const char **name, char ***prefixes, bool *is_collection, const char **extension) { +static int guess_type(const char **name, char ***ret_prefixes, bool *ret_is_collection, const char **ret_extension) { /* Try to figure out if name is like tmpfiles.d/ or systemd/system-presets/, * i.e. a collection of directories without a main config file. * Incidentally, all those formats don't use sections. So we return a single @@ -316,11 +316,10 @@ static int guess_type(const char **name, char ***prefixes, bool *is_collection, */ _cleanup_free_ char *n = NULL; - bool usr = false, run = false, coll = false; + bool run = false, coll = false; const char *ext = ".conf"; /* This is static so that the array doesn't get deallocated when we exit the function */ static const char* const std_prefixes[] = { CONF_PATHS(""), NULL }; - static const char* const usr_prefixes[] = { CONF_PATHS_USR(""), NULL }; static const char* const run_prefixes[] = { "/run/", NULL }; if (path_equal(*name, "environment.d")) @@ -332,20 +331,13 @@ static int guess_type(const char **name, char ***prefixes, bool *is_collection, if (!n) return log_oom(); - /* All systemd-style config files should support the /usr-/etc-/run split and - * dropins. Let's add a blanket rule that allows us to support them without keeping - * an explicit list. */ - if (path_startswith(n, "systemd") && endswith(n, ".conf")) - usr = true; - delete_trailing_chars(n, "/"); + /* We assume systemd-style config files support the /usr-/run-/etc split and dropins. */ + if (endswith(n, ".d")) coll = true; - if (path_equal(n, "environment")) - usr = true; - if (path_equal(n, "udev/hwdb.d")) ext = ".hwdb"; else if (path_equal(n, "udev/rules.d")) @@ -363,12 +355,9 @@ static int guess_type(const char **name, char ***prefixes, bool *is_collection, ext = ".preset"; } - if (path_equal(n, "systemd/user-preset")) - usr = true; - - *prefixes = (char**) (usr ? usr_prefixes : run ? run_prefixes : std_prefixes); - *is_collection = coll; - *extension = ext; + *ret_prefixes = (char**) (run ? run_prefixes : std_prefixes); + *ret_is_collection = coll; + *ret_extension = ext; return 0; } diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c index 7282111f49..c96f8485dd 100644 --- a/src/shared/sleep-config.c +++ b/src/shared/sleep-config.c @@ -145,9 +145,12 @@ int parse_sleep_config(SleepConfig **ret) { {} }; - (void) config_parse_config_file("sleep.conf", "Sleep\0", - config_item_table_lookup, items, - CONFIG_PARSE_WARN, NULL); + (void) config_parse_standard_file_with_dropins( + "systemd/sleep.conf", + "Sleep\0", + config_item_table_lookup, items, + CONFIG_PARSE_WARN, + /* userdata= */ NULL); /* use default values unless set */ sc->allow[SLEEP_SUSPEND] = allow_suspend != 0; diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 20bb8c3ba5..666dd970e6 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -7643,7 +7643,7 @@ int tpm2_load_pcr_signature(const char *path, JsonVariant **ret) { /* Tries to load a JSON PCR signature file. Takes an absolute path, a simple file name or NULL. In * the latter two cases searches in /etc/, /usr/lib/, /run/, as usual. */ - search = strv_split_nulstr(CONF_PATHS_NULSTR("systemd")); + search = strv_new(CONF_PATHS("systemd")); if (!search) return log_oom_debug(); diff --git a/src/shared/udev-util.c b/src/shared/udev-util.c index 9acdaeff52..0014b7236f 100644 --- a/src/shared/udev-util.c +++ b/src/shared/udev-util.c @@ -28,12 +28,10 @@ int udev_parse_config_full(const ConfigTableItem config_table[]) { assert(config_table); - r = config_parse_config_file_full( - "udev.conf", - "udev", + r = config_parse_standard_file_with_dropins( + "udev/udev.conf", /* sections = */ NULL, - config_item_table_lookup, - config_table, + config_item_table_lookup, config_table, CONFIG_PARSE_WARN, /* userdata = */ NULL); if (r == -ENOENT) diff --git a/src/test/test-conf-parser.c b/src/test/test-conf-parser.c index 0acb4131b5..d0d7419eaa 100644 --- a/src/test/test-conf-parser.c +++ b/src/test/test-conf-parser.c @@ -3,8 +3,10 @@ #include "conf-parser.h" #include "fd-util.h" #include "fs-util.h" +#include "fileio.h" #include "log.h" #include "macro.h" +#include "mkdir.h" #include "string-util.h" #include "strv.h" #include "tests.h" @@ -390,4 +392,102 @@ TEST(config_parse) { test_config_parse_one(i, config_file[i]); } +TEST(config_parse_standard_file_with_dropins_full) { + _cleanup_(rmdir_and_freep) char *root = NULL; + _cleanup_close_ int rfd = -EBADF; + int r; + + assert_se(mkdtemp_malloc(NULL, &root) >= 0); + assert_se(mkdir_p_root(root, "/etc/kernel/install.conf.d", UID_INVALID, GID_INVALID, 0755, NULL)); + assert_se(mkdir_p_root(root, "/run/kernel/install.conf.d", UID_INVALID, GID_INVALID, 0755, NULL)); + assert_se(mkdir_p_root(root, "/usr/lib/kernel/install.conf.d", UID_INVALID, GID_INVALID, 0755, NULL)); + assert_se(mkdir_p_root(root, "/usr/local/lib/kernel/install.conf.d", UID_INVALID, GID_INVALID, 0755, NULL)); + + rfd = open(root, O_CLOEXEC|O_DIRECTORY); + assert_se(rfd >= 0); + + assert_se(write_string_file_at(rfd, "usr/lib/kernel/install.conf", /* this one is ignored */ + "A=!!!", WRITE_STRING_FILE_CREATE) == 0); + assert_se(write_string_file_at(rfd, "usr/local/lib/kernel/install.conf", + "A=aaa", WRITE_STRING_FILE_CREATE) == 0); + assert_se(write_string_file_at(rfd, "usr/local/lib/kernel/install.conf.d/drop1.conf", + "B=bbb", WRITE_STRING_FILE_CREATE) == 0); + assert_se(write_string_file_at(rfd, "usr/local/lib/kernel/install.conf.d/drop2.conf", + "C=c1", WRITE_STRING_FILE_CREATE) == 0); + assert_se(write_string_file_at(rfd, "usr/lib/kernel/install.conf.d/drop2.conf", /* this one is ignored */ + "C=c2", WRITE_STRING_FILE_CREATE) == 0); + assert_se(write_string_file_at(rfd, "run/kernel/install.conf.d/drop3.conf", + "D=ddd", WRITE_STRING_FILE_CREATE) == 0); + assert_se(write_string_file_at(rfd, "etc/kernel/install.conf.d/drop4.conf", + "E=eee", WRITE_STRING_FILE_CREATE) == 0); + + _cleanup_free_ char *A = NULL, *B = NULL, *C = NULL, *D = NULL, *E = NULL, *F = NULL; + _cleanup_strv_free_ char **dropins = NULL; + + const ConfigTableItem items[] = { + { NULL, "A", config_parse_string, 0, &A}, + { NULL, "B", config_parse_string, 0, &B}, + { NULL, "C", config_parse_string, 0, &C}, + { NULL, "D", config_parse_string, 0, &D}, + { NULL, "E", config_parse_string, 0, &E}, + { NULL, "F", config_parse_string, 0, &F}, + {} + }; + + r = config_parse_standard_file_with_dropins_full( + root, "kernel/install.conf", + /* sections= */ NULL, + config_item_table_lookup, items, + CONFIG_PARSE_WARN, + /* userdata= */ NULL, + /* ret_stats_by_path= */ NULL, + /* ret_dropin_files= */ &dropins); + assert_se(r >= 0); + assert_se(streq_ptr(A, "aaa")); + assert_se(streq_ptr(B, "bbb")); + assert_se(streq_ptr(C, "c1")); + assert_se(streq_ptr(D, "ddd")); + assert_se(streq_ptr(E, "eee")); + assert_se(streq_ptr(F, NULL)); + + A = mfree(A); + B = mfree(B); + C = mfree(C); + D = mfree(D); + E = mfree(E); + + assert_se(strv_length(dropins) == 4); + + /* Make sure that we follow symlinks */ + assert_se(mkdir_p_root(root, "/etc/kernel/install2.conf.d", UID_INVALID, GID_INVALID, 0755, NULL)); + assert_se(mkdir_p_root(root, "/run/kernel/install2.conf.d", UID_INVALID, GID_INVALID, 0755, NULL)); + assert_se(mkdir_p_root(root, "/usr/lib/kernel/install2.conf.d", UID_INVALID, GID_INVALID, 0755, NULL)); + assert_se(mkdir_p_root(root, "/usr/local/lib/kernel/install2.conf.d", UID_INVALID, GID_INVALID, 0755, NULL)); + + /* (Those symlinks are only useful relative to <root>. */ + assert_se(symlinkat("/usr/lib/kernel/install.conf", rfd, "usr/lib/kernel/install2.conf") == 0); + assert_se(symlinkat("/usr/local/lib/kernel/install.conf", rfd, "usr/local/lib/kernel/install2.conf") == 0); + assert_se(symlinkat("/usr/local/lib/kernel/install.conf.d/drop1.conf", rfd, "usr/local/lib/kernel/install2.conf.d/drop1.conf") == 0); + assert_se(symlinkat("/usr/local/lib/kernel/install.conf.d/drop2.conf", rfd, "usr/local/lib/kernel/install2.conf.d/drop2.conf") == 0); + assert_se(symlinkat("/usr/lib/kernel/install.conf.d/drop2.conf", rfd, "usr/lib/kernel/install2.conf.d/drop2.conf") == 0); + assert_se(symlinkat("/run/kernel/install.conf.d/drop3.conf", rfd, "run/kernel/install2.conf.d/drop3.conf") == 0); + assert_se(symlinkat("/etc/kernel/install.conf.d/drop4.conf", rfd, "etc/kernel/install2.conf.d/drop4.conf") == 0); + + r = config_parse_standard_file_with_dropins_full( + root, "kernel/install2.conf", + /* sections= */ NULL, + config_item_table_lookup, items, + CONFIG_PARSE_WARN, + /* userdata= */ NULL, + /* ret_stats_by_path= */ NULL, + /* ret_dropin_files= */ NULL); + assert_se(r >= 0); + assert_se(streq_ptr(A, "aaa")); + assert_se(streq_ptr(B, "bbb")); + assert_se(streq_ptr(C, "c1")); + assert_se(streq_ptr(D, "ddd")); + assert_se(streq_ptr(E, "eee")); + assert_se(streq_ptr(F, NULL)); +} + DEFINE_TEST_MAIN(LOG_INFO); diff --git a/src/test/test-strv.c b/src/test/test-strv.c index da8721214a..47ad0eb639 100644 --- a/src/test/test-strv.c +++ b/src/test/test-strv.c @@ -527,6 +527,22 @@ TEST(strv_sort) { assert_se(streq(input_table[4], "durian")); } +TEST(strv_extend_strv_biconcat) { + _cleanup_strv_free_ char **a = NULL, **b = NULL; + + a = strv_new("without", "suffix"); + b = strv_new("with", "suffix"); + assert_se(a); + assert_se(b); + + assert_se(strv_extend_strv_biconcat(&a, "prefix_", (const char* const*) b, "_suffix") >= 0); + + assert_se(streq(a[0], "without")); + assert_se(streq(a[1], "suffix")); + assert_se(streq(a[2], "prefix_with_suffix")); + assert_se(streq(a[3], "prefix_suffix_suffix")); +} + TEST(strv_extend_strv_concat) { _cleanup_strv_free_ char **a = NULL, **b = NULL; @@ -535,7 +551,7 @@ TEST(strv_extend_strv_concat) { assert_se(a); assert_se(b); - assert_se(strv_extend_strv_concat(&a, b, "_suffix") >= 0); + assert_se(strv_extend_strv_concat(&a, (const char* const*) b, "_suffix") >= 0); assert_se(streq(a[0], "without")); assert_se(streq(a[1], "suffix")); diff --git a/src/timesync/timesyncd-conf.c b/src/timesync/timesyncd-conf.c index 9c0b6f7ce1..4b1d4ddbfe 100644 --- a/src/timesync/timesyncd-conf.c +++ b/src/timesync/timesyncd-conf.c @@ -102,9 +102,12 @@ int manager_parse_config_file(Manager *m) { assert(m); - r = config_parse_config_file("timesyncd.conf", "Time\0", - config_item_perf_lookup, timesyncd_gperf_lookup, - CONFIG_PARSE_WARN, m); + r = config_parse_standard_file_with_dropins( + "systemd/timesyncd.conf", + "Time\0", + config_item_perf_lookup, timesyncd_gperf_lookup, + CONFIG_PARSE_WARN, + /* userdata= */ m); if (r < 0) return r; diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index ede5ca8a96..ec6d8dcfa1 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -49,7 +49,6 @@ #include "mkdir-label.h" #include "mount-util.h" #include "mountpoint-util.h" -#include "nulstr-util.h" #include "offline-passwd.h" #include "pager.h" #include "parse-argument.h" @@ -370,7 +369,7 @@ static int user_config_paths(char*** ret) { if (r < 0 && !ERRNO_IS_NOINFO(r)) return r; - r = strv_extend_strv_concat(&res, config_dirs, "/user-tmpfiles.d"); + r = strv_extend_strv_concat(&res, (const char* const*) config_dirs, "/user-tmpfiles.d"); if (r < 0) return r; @@ -382,7 +381,7 @@ static int user_config_paths(char*** ret) { if (r < 0) return r; - r = strv_extend_strv_concat(&res, data_dirs, "/user-tmpfiles.d"); + r = strv_extend_strv_concat(&res, (const char* const*) data_dirs, "/user-tmpfiles.d"); if (r < 0) return r; @@ -4570,7 +4569,7 @@ static int run(int argc, char *argv[]) { break; case RUNTIME_SCOPE_SYSTEM: - config_dirs = strv_split_nulstr(CONF_PATHS_NULSTR("tmpfiles.d")); + config_dirs = strv_new(CONF_PATHS("tmpfiles.d")); if (!config_dirs) return log_oom(); break; diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index bb26f32974..7f16b17467 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -742,7 +742,7 @@ static int link_generate_new_name(Link *link) { device = link->device; if (link->action != SD_DEVICE_ADD) { - log_link_debug(link, "Skipping to apply Name= and NamePolicy= on '%s' uevent.", + log_link_debug(link, "Not applying Name= and NamePolicy= on '%s' uevent.", device_action_to_string(link->action)); goto no_rename; } @@ -822,7 +822,7 @@ static int link_generate_alternative_names(Link *link) { assert(!link->altnames); if (link->action != SD_DEVICE_ADD) { - log_link_debug(link, "Skipping to apply AlternativeNames= and AlternativeNamesPolicy= on '%s' uevent.", + log_link_debug(link, "Not applying AlternativeNames= and AlternativeNamesPolicy= on '%s' uevent.", device_action_to_string(link->action)); return 0; } diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c index fc614443ef..df89679de3 100644 --- a/src/udev/udev-builtin-net_setup_link.c +++ b/src/udev/udev-builtin-net_setup_link.c @@ -26,7 +26,7 @@ static int builtin_net_setup_link(UdevEvent *event, int argc, char **argv, bool return log_device_error_errno(dev, r, "Failed to get action: %m"); if (!IN_SET(action, SD_DEVICE_ADD, SD_DEVICE_BIND, SD_DEVICE_MOVE)) { - log_device_debug(dev, "Skipping to apply .link settings on '%s' uevent.", + log_device_debug(dev, "Not applying .link settings on '%s' uevent.", device_action_to_string(action)); /* Import previously assigned .link file name. */ diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 684ced1315..e408768887 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -33,16 +33,15 @@ static int arg_daemonize = false; static int listen_fds(int *ret_ctrl, int *ret_netlink) { int ctrl_fd = -EBADF, netlink_fd = -EBADF; - int fd, n; assert(ret_ctrl); assert(ret_netlink); - n = sd_listen_fds(true); + int n = sd_listen_fds(true); if (n < 0) return n; - for (fd = SD_LISTEN_FDS_START; fd < n + SD_LISTEN_FDS_START; fd++) { + for (int fd = SD_LISTEN_FDS_START; fd < n + SD_LISTEN_FDS_START; fd++) { if (sd_is_socket(fd, AF_UNIX, SOCK_SEQPACKET, -1) > 0) { if (ctrl_fd >= 0) return -EINVAL; diff --git a/src/xdg-autostart-generator/xdg-autostart-generator.c b/src/xdg-autostart-generator/xdg-autostart-generator.c index 616c017357..71e1a66435 100644 --- a/src/xdg-autostart-generator/xdg-autostart-generator.c +++ b/src/xdg-autostart-generator/xdg-autostart-generator.c @@ -37,7 +37,7 @@ static int enumerate_xdg_autostart(Hashmap *all_services) { r = xdg_user_dirs(&config_dirs, &data_dirs); if (r < 0) return r; - r = strv_extend_strv_concat(&autostart_dirs, config_dirs, "/autostart"); + r = strv_extend_strv_concat(&autostart_dirs, (const char* const*) config_dirs, "/autostart"); if (r < 0) return r; |