]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
conf-parser: parse main config first only if not symlinked to/as drop-in
authorMike Yuan <me@yhndnzj.com>
Thu, 7 Sep 2023 13:38:00 +0000 (21:38 +0800)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 8 Sep 2023 14:25:12 +0000 (16:25 +0200)
Otherwise we'll skip parsing main config directly.

Replaces #27152
Replaces #28956:
chase() is an overkill for determining whether
two files are the same. We only need to check
if the inodes are the same.

src/shared/conf-parser.c

index 63030d4a2d0d6c8de3d6e6039f1d39ec2459ab83..af5aac7b291c966e3fa191477b1a6502e72f8a57 100644 (file)
@@ -487,6 +487,7 @@ static int config_parse_many_files(
                 Hashmap **ret_stats_by_path) {
 
         _cleanup_hashmap_free_ Hashmap *stats_by_path = NULL;
+        _cleanup_set_free_ Set *inodes = NULL;
         struct stat st;
         int r;
 
@@ -496,8 +497,37 @@ static int config_parse_many_files(
                         return -ENOMEM;
         }
 
+        /* Get inodes for all drop-ins. Later we'll verify if main config is a symlink to one of them. If so,
+         * we skip reading main config file directly. */
+        STRV_FOREACH(fn, files) {
+                _cleanup_free_ struct stat *st_dropin = NULL;
+
+                st_dropin = new(struct stat, 1);
+                if (!st_dropin)
+                        return -ENOMEM;
+
+                r = RET_NERRNO(stat(*fn, st_dropin));
+                if (r < 0 && r != -ENOENT)
+                        return r;
+
+                r = set_ensure_consume(&inodes, &inode_hash_ops, TAKE_PTR(st_dropin));
+                if (r < 0)
+                        return r;
+        }
+
         /* First read the first found main config file. */
         STRV_FOREACH(fn, conf_files) {
+                if (inodes) {
+                        r = RET_NERRNO(stat(*fn, &st));
+                        if (r < 0 && r != -ENOENT)
+                                return r;
+
+                        if (set_contains(inodes, &st)) {
+                                log_debug("%s: symlink to drop-in, will be read later.", *fn);
+                                continue;
+                        }
+                }
+
                 r = config_parse(NULL, *fn, NULL, sections, lookup, table, flags, userdata, &st);
                 if (r < 0)
                         return r;