forked from pool/systemd
- Drop 0001-conf-parser-introduce-early-drop-ins.patch
The usage of drop-ins is now the official way for configuring systemd and its various daemons on Factory/ALP. See: https://lists.opensuse.org/archives/list/factory@lists.opensuse.org/thread/KWRBTAVQ6MGHVAHKDZZ6GIRX4RMHKHQ6/ OBS-URL: https://build.opensuse.org/package/show/Base:System/systemd?expand=0&rev=1465
This commit is contained in:
parent
cf83dc34c6
commit
9862047040
@ -1,329 +0,0 @@
|
|||||||
From 503da4e49107f6c20e3fce05506f8b107894a5af Mon Sep 17 00:00:00 2001
|
|
||||||
From: Franck Bui <fbui@suse.com>
|
|
||||||
Date: Fri, 22 Jan 2021 14:57:08 +0100
|
|
||||||
Subject: [PATCH 1/1] conf-parser: introduce 'early' drop-ins
|
|
||||||
MIME-Version: 1.0
|
|
||||||
Content-Type: text/plain; charset=UTF-8
|
|
||||||
Content-Transfer-Encoding: 8bit
|
|
||||||
|
|
||||||
As formerly known as "downstream conf file drop-ins should never override main
|
|
||||||
user conf file".
|
|
||||||
|
|
||||||
Previously all drop-ins, including those shipped by downstream, shipped in
|
|
||||||
/usr, could override user's main configuration file (located in /etc) because
|
|
||||||
the main file was always parsed first.
|
|
||||||
|
|
||||||
This was problematic for downstreams because their customization should never
|
|
||||||
override the users one in general. Therefore the only way to make this logic
|
|
||||||
usable was by teaching users to never use the main conf files and to put all
|
|
||||||
theirs settings in drop-ins with a higher priority than the one downsteam would
|
|
||||||
use. However customizing the defaults through the main conf file is something
|
|
||||||
very well established since a long time hence this is not something
|
|
||||||
conceivable.
|
|
||||||
|
|
||||||
This patch reworks the way we parse configuration files by introducing "early"
|
|
||||||
conf files (idea from Zbigniew Jędrzejewski-Szmek), which always have a
|
|
||||||
priority lower than the main config file and hence other conf file drop-ins
|
|
||||||
too.
|
|
||||||
|
|
||||||
Early conf files can be located in any locations where regular conf snippets
|
|
||||||
can be installed and are sorted between them using the same sorting rules that
|
|
||||||
apply to other conf files. A conf file is considered as an early one if its
|
|
||||||
filename is prefixed with "__" (double underscore).
|
|
||||||
|
|
||||||
Hence for example, drop-in "/usr/lib/systemd/logind.conf.d/__99-foo.conf" will
|
|
||||||
always be parsed before:
|
|
||||||
|
|
||||||
/etc/systemd/logind.conf
|
|
||||||
/etc/systemd/logind.conf.d/00-foo.conf
|
|
||||||
/usr/lib/systemd/logind.conf.d/00-foo.conf
|
|
||||||
|
|
||||||
This change isn't backwards-compatible, but the '__' prefix is something that
|
|
||||||
is unlikely used. Hence the risk should be very low.
|
|
||||||
|
|
||||||
Unfortunately upstream is not seing this problem as a serious one and accept
|
|
||||||
that vendors' configuration files can take precedence over the main
|
|
||||||
configuration files (placed in /etc). See the following links for the
|
|
||||||
related discussions:
|
|
||||||
|
|
||||||
https://github.com/systemd/systemd/issues/2121 (initial issue report)
|
|
||||||
https://github.com/systemd/systemd/pull/17161 (first attempt to solve this issue)
|
|
||||||
https://github.com/systemd/systemd/pull/18347 (introduction of early drop-in)
|
|
||||||
|
|
||||||
Since SUSE heavily relies on drop-ins to customize some of the upstream default
|
|
||||||
settings, there was no other choice than to diverge from upstream in this
|
|
||||||
regard.
|
|
||||||
|
|
||||||
But it should be noted that these early drop-ins are strictly reserved for SUSE
|
|
||||||
own purpose only. IOW users should never use them and early drop-ins should
|
|
||||||
never be created in /etc but only in /usr. We reserve the right to change or
|
|
||||||
drop this feature at any time.
|
|
||||||
|
|
||||||
Fixes: #2121
|
|
||||||
---
|
|
||||||
src/shared/conf-parser.c | 56 ++++++++++++++--
|
|
||||||
src/test/test-conf-parser.c | 125 +++++++++++++++++++++++++++++++++++-
|
|
||||||
2 files changed, 175 insertions(+), 6 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c
|
|
||||||
index ec4b53b2e8..982172dfa0 100644
|
|
||||||
--- a/src/shared/conf-parser.c
|
|
||||||
+++ b/src/shared/conf-parser.c
|
|
||||||
@@ -477,6 +477,7 @@ int hashmap_put_stats_by_path(Hashmap **stats_by_path, const char *path, const s
|
|
||||||
|
|
||||||
static int config_parse_many_files(
|
|
||||||
const char* const* conf_files,
|
|
||||||
+ char **early_files,
|
|
||||||
char **files,
|
|
||||||
const char *sections,
|
|
||||||
ConfigItemLookup lookup,
|
|
||||||
@@ -495,6 +496,20 @@ static int config_parse_many_files(
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ STRV_FOREACH(fn, early_files) {
|
|
||||||
+ r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata, &st);
|
|
||||||
+ if (r < 0)
|
|
||||||
+ return r;
|
|
||||||
+ if (r == 0)
|
|
||||||
+ continue;
|
|
||||||
+
|
|
||||||
+ if (ret_stats_by_path) {
|
|
||||||
+ r = hashmap_put_stats_by_path(&stats_by_path, *fn, &st);
|
|
||||||
+ if (r < 0)
|
|
||||||
+ return r;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
/* First read the first found main config file. */
|
|
||||||
STRV_FOREACH(fn, conf_files) {
|
|
||||||
r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata, &st);
|
|
||||||
@@ -533,6 +548,27 @@ static int config_parse_many_files(
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
+static int config_parse_split_conf_files(char **files, char ***early_files, char ***late_files) {
|
|
||||||
+
|
|
||||||
+ assert(files);
|
|
||||||
+ assert(early_files);
|
|
||||||
+ assert(late_files);
|
|
||||||
+
|
|
||||||
+ STRV_FOREACH(f, files) {
|
|
||||||
+ char ***s, *p;
|
|
||||||
+
|
|
||||||
+ p = strdup(*f);
|
|
||||||
+ if (!p)
|
|
||||||
+ return log_oom();
|
|
||||||
+
|
|
||||||
+ s = startswith(basename(*f), "__") ? early_files : late_files;
|
|
||||||
+ if (strv_push(s, p) < 0)
|
|
||||||
+ return log_oom();
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/* Parse one main config file located in /etc/systemd and its drop-ins, which is what all systemd daemons
|
|
||||||
* do. */
|
|
||||||
int config_parse_config_file(
|
|
||||||
@@ -543,7 +579,8 @@ int config_parse_config_file(
|
|
||||||
ConfigParseFlags flags,
|
|
||||||
void *userdata) {
|
|
||||||
|
|
||||||
- _cleanup_strv_free_ char **dropins = NULL, **dropin_dirs = NULL;
|
|
||||||
+ _cleanup_strv_free_ char **dropins = NULL, **early_dropins = NULL, **dropin_dirs = NULL;
|
|
||||||
+ _cleanup_strv_free_ char **files = NULL;
|
|
||||||
char **conf_paths = CONF_PATHS_STRV("");
|
|
||||||
int r;
|
|
||||||
|
|
||||||
@@ -571,13 +608,17 @@ int config_parse_config_file(
|
|
||||||
dropin_dirs[i++] = d;
|
|
||||||
}
|
|
||||||
|
|
||||||
- r = conf_files_list_strv(&dropins, ".conf", NULL, 0, (const char**) dropin_dirs);
|
|
||||||
+ r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char**) dropin_dirs);
|
|
||||||
+ if (r < 0)
|
|
||||||
+ return r;
|
|
||||||
+
|
|
||||||
+ r = config_parse_split_conf_files(files, &early_dropins, &dropins);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
const char *sysconf_file = strjoina(PKGSYSCONFDIR, "/", conf_file);
|
|
||||||
|
|
||||||
- return config_parse_many_files(STRV_MAKE_CONST(sysconf_file), dropins,
|
|
||||||
+ return config_parse_many_files(STRV_MAKE_CONST(sysconf_file), early_dropins, dropins,
|
|
||||||
sections, lookup, table, flags, userdata, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -595,6 +636,7 @@ int config_parse_many(
|
|
||||||
Hashmap **ret_stats_by_path,
|
|
||||||
char ***ret_dropin_files) {
|
|
||||||
|
|
||||||
+ _cleanup_strv_free_ char **early_dropins = NULL, **dropins = NULL;
|
|
||||||
_cleanup_strv_free_ char **files = NULL;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
@@ -607,12 +649,16 @@ int config_parse_many(
|
|
||||||
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_split_conf_files(files, &early_dropins, &dropins);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
+ r = config_parse_many_files(conf_files, early_dropins, dropins,
|
|
||||||
+ sections, lookup, table, flags, userdata, ret_stats_by_path);
|
|
||||||
+
|
|
||||||
+
|
|
||||||
if (ret_dropin_files)
|
|
||||||
- *ret_dropin_files = TAKE_PTR(files);
|
|
||||||
+ *ret_dropin_files = TAKE_PTR(dropins);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
diff --git a/src/test/test-conf-parser.c b/src/test/test-conf-parser.c
|
|
||||||
index 0acb4131b5..88f8ff11be 100644
|
|
||||||
--- a/src/test/test-conf-parser.c
|
|
||||||
+++ b/src/test/test-conf-parser.c
|
|
||||||
@@ -5,7 +5,10 @@
|
|
||||||
#include "fs-util.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "macro.h"
|
|
||||||
-#include "string-util.h"
|
|
||||||
+#include "mkdir.h"
|
|
||||||
+#include "nulstr-util.h"
|
|
||||||
+#include "path-util.h"
|
|
||||||
+#include "rm-rf.h"
|
|
||||||
#include "strv.h"
|
|
||||||
#include "tests.h"
|
|
||||||
#include "tmpfile-util.h"
|
|
||||||
@@ -390,4 +393,124 @@ TEST(config_parse) {
|
|
||||||
test_config_parse_one(i, config_file[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
+static void setup_conf_files(const char *root, char **conf_files, char ***ret_conf_dirs) {
|
|
||||||
+
|
|
||||||
+ STRV_FOREACH(path, conf_files) {
|
|
||||||
+ _cleanup_free_ char *abspath = NULL;
|
|
||||||
+ _cleanup_fclose_ FILE *f = NULL;
|
|
||||||
+
|
|
||||||
+ abspath = path_join(root, *path);
|
|
||||||
+ assert_se(abspath);
|
|
||||||
+
|
|
||||||
+ (void) mkdir_parents(abspath, 0755);
|
|
||||||
+
|
|
||||||
+ f = fopen(abspath, "w");
|
|
||||||
+ assert_se(f);
|
|
||||||
+ fprintf(f,
|
|
||||||
+ "[Section]\n"
|
|
||||||
+ "Field=%s\n",
|
|
||||||
+ *path);
|
|
||||||
+
|
|
||||||
+ if (ret_conf_dirs) {
|
|
||||||
+ _cleanup_free_ char *d = NULL;
|
|
||||||
+
|
|
||||||
+ assert_se(path_extract_directory(abspath, &d) >= 0);
|
|
||||||
+ assert_se(strv_consume(ret_conf_dirs, TAKE_PTR(d)) == 0);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (ret_conf_dirs) {
|
|
||||||
+ strv_uniq(*ret_conf_dirs);
|
|
||||||
+ strv_sort(*ret_conf_dirs);
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static void test_config_parse_many_one(const char *main, char **dropins, const char *expected) {
|
|
||||||
+
|
|
||||||
+ _cleanup_strv_free_ char **conf_dirs = NULL;
|
|
||||||
+ _cleanup_free_ char *parsed = NULL;
|
|
||||||
+ char *conf_file;
|
|
||||||
+ char *tmp_dir;
|
|
||||||
+ int r;
|
|
||||||
+
|
|
||||||
+ const ConfigTableItem items[] = {
|
|
||||||
+ { "Section", "Field", config_parse_string, 0, &parsed},
|
|
||||||
+ };
|
|
||||||
+
|
|
||||||
+ tmp_dir = strdupa("/tmp/test-conf-parser-XXXXXX");
|
|
||||||
+ assert_se(mkdtemp(tmp_dir));
|
|
||||||
+
|
|
||||||
+ setup_conf_files(tmp_dir, STRV_MAKE(main), NULL);
|
|
||||||
+ setup_conf_files(tmp_dir, dropins, &conf_dirs);
|
|
||||||
+
|
|
||||||
+ conf_file = main ? strjoina(tmp_dir, "/", main) : NULL;
|
|
||||||
+
|
|
||||||
+ /* Since commit bdb2d3c6889408c7, 'conf_file_dirs' can't be NULL anymore. */
|
|
||||||
+
|
|
||||||
+ r = config_parse_many(STRV_MAKE_CONST(conf_file),
|
|
||||||
+ (const char * const*)(conf_dirs ?: STRV_MAKE_EMPTY),
|
|
||||||
+ /* dropin_dirname= */ "",
|
|
||||||
+ /* root= */ NULL,
|
|
||||||
+ "Section\0",
|
|
||||||
+ 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((!!expected == !!parsed));
|
|
||||||
+ assert_se(!expected || streq(expected, parsed));
|
|
||||||
+
|
|
||||||
+ assert_se(rm_rf(tmp_dir, REMOVE_ROOT|REMOVE_PHYSICAL) == 0);
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+TEST(config_parse_many) {
|
|
||||||
+ log_info("== %s ==", __func__);
|
|
||||||
+
|
|
||||||
+ test_config_parse_many_one(/* main= */ NULL,
|
|
||||||
+ /* dropins */ NULL,
|
|
||||||
+ /* expected_name= */ NULL);
|
|
||||||
+
|
|
||||||
+ test_config_parse_many_one("dir/main.conf", NULL, "dir/main.conf");
|
|
||||||
+
|
|
||||||
+ test_config_parse_many_one(NULL,
|
|
||||||
+ STRV_MAKE("dir1/50-foo.conf"),
|
|
||||||
+ "dir1/50-foo.conf");
|
|
||||||
+
|
|
||||||
+ test_config_parse_many_one(NULL,
|
|
||||||
+ STRV_MAKE("dir1/__50-foo.conf"),
|
|
||||||
+ "dir1/__50-foo.conf");
|
|
||||||
+
|
|
||||||
+ test_config_parse_many_one(NULL,
|
|
||||||
+ STRV_MAKE("dir1/10-foo.conf", "dir1/50-bar.conf"),
|
|
||||||
+ "dir1/50-bar.conf");
|
|
||||||
+
|
|
||||||
+ test_config_parse_many_one(NULL,
|
|
||||||
+ STRV_MAKE("dir1/50-foo.conf", "dir2/10-bar.conf"),
|
|
||||||
+ "dir1/50-foo.conf");
|
|
||||||
+
|
|
||||||
+ test_config_parse_many_one(NULL,
|
|
||||||
+ STRV_MAKE("dir1/10-foo.conf", "dir2/10-foo.conf"),
|
|
||||||
+ "dir1/10-foo.conf");
|
|
||||||
+
|
|
||||||
+ /* Early conf files should never override the main one whatever their
|
|
||||||
+ * priority/location. */
|
|
||||||
+ test_config_parse_many_one("dir/10-main.conf",
|
|
||||||
+ STRV_MAKE("dir1/__10-foo.conf", "dir2/__99-foo.conf"),
|
|
||||||
+ "dir/10-main.conf");
|
|
||||||
+
|
|
||||||
+ /* Late conf files always take precendence over the early conf files
|
|
||||||
+ * and the main one. */
|
|
||||||
+ test_config_parse_many_one("dir/50-main.conf",
|
|
||||||
+ STRV_MAKE("dir1/10-foo.conf"),
|
|
||||||
+ "dir1/10-foo.conf");
|
|
||||||
+
|
|
||||||
+ test_config_parse_many_one("dir/10-main.conf",
|
|
||||||
+ STRV_MAKE("dir1/__10-foo.conf", "dir2/__99-foo.conf", "dir2/10-foo.conf"),
|
|
||||||
+ "dir2/10-foo.conf");
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
DEFINE_TEST_MAIN(LOG_INFO);
|
|
||||||
--
|
|
||||||
2.35.3
|
|
||||||
|
|
@ -1,3 +1,13 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Oct 20 08:09:19 UTC 2023 - Franck Bui <fbui@suse.com>
|
||||||
|
|
||||||
|
- Drop 0001-conf-parser-introduce-early-drop-ins.patch
|
||||||
|
|
||||||
|
The usage of drop-ins is now the official way for configuring systemd and its
|
||||||
|
various daemons on Factory/ALP.
|
||||||
|
|
||||||
|
See: https://lists.opensuse.org/archives/list/factory@lists.opensuse.org/thread/KWRBTAVQ6MGHVAHKDZZ6GIRX4RMHKHQ6/
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Thu Oct 19 13:25:01 UTC 2023 - Franck Bui <fbui@suse.com>
|
Thu Oct 19 13:25:01 UTC 2023 - Franck Bui <fbui@suse.com>
|
||||||
|
|
||||||
|
@ -209,7 +209,6 @@ Source212: files.portable
|
|||||||
# only relevant for SUSE distros. Special rewards for those who will manage to
|
# only relevant for SUSE distros. Special rewards for those who will manage to
|
||||||
# get rid of one of them !
|
# get rid of one of them !
|
||||||
#
|
#
|
||||||
Patch2: 0001-conf-parser-introduce-early-drop-ins.patch
|
|
||||||
Patch3: 0009-pid1-handle-console-specificities-weirdness-for-s390.patch
|
Patch3: 0009-pid1-handle-console-specificities-weirdness-for-s390.patch
|
||||||
%if %{with sysvcompat}
|
%if %{with sysvcompat}
|
||||||
Patch4: 0002-rc-local-fix-ordering-startup-for-etc-init.d-boot.lo.patch
|
Patch4: 0002-rc-local-fix-ordering-startup-for-etc-init.d-boot.lo.patch
|
||||||
|
Loading…
Reference in New Issue
Block a user