]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sysupdate: use conf_files_list_strv_full() to enumerate components
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 13 Jul 2025 01:36:08 +0000 (10:36 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 17 Sep 2025 13:04:06 +0000 (22:04 +0900)
With this change, root directory is correctly supported, and symlinked
components are also correctly enumerated.

src/sysupdate/sysupdate.c

index 692291fcfee622d36388cc24359f46eef49a5444..0b0e4e9fe3601858a8a71b4d6f008c269657075b 100644 (file)
@@ -1542,8 +1542,6 @@ static int verb_components(int argc, char **argv, void *userdata) {
         _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL;
         _cleanup_(umount_and_rmdir_and_freep) char *mounted_dir = NULL;
         _cleanup_set_free_ Set *names = NULL;
-        _cleanup_free_ char **z = NULL; /* We use simple free() rather than strv_free() here, since set_free() will free the strings for us */
-        char **l = CONF_PATHS_STRV("");
         bool has_default_component = false;
         int r;
 
@@ -1553,65 +1551,49 @@ static int verb_components(int argc, char **argv, void *userdata) {
         if (r < 0)
                 return r;
 
-        STRV_FOREACH(i, l) {
-                _cleanup_closedir_ DIR *d = NULL;
-                _cleanup_free_ char *p = NULL;
+        ConfFile **directories = NULL;
+        size_t n_directories = 0;
 
-                r = chase_and_opendir(*i, arg_root, CHASE_PREFIX_ROOT, &p, &d);
-                if (r == -ENOENT)
-                        continue;
-                if (r < 0)
-                        return log_error_errno(r, "Failed to open directory '%s': %m", *i);
-
-                for (;;) {
-                        _cleanup_free_ char *n = NULL;
-                        struct dirent *de;
-                        const char *e, *a;
-
-                        de = readdir_ensure_type(d);
-                        if (!de) {
-                                if (errno != 0)
-                                        return log_error_errno(errno, "Failed to enumerate directory '%s': %m", p);
-
-                                break;
-                        }
+        CLEANUP_ARRAY(directories, n_directories, conf_file_free_many);
 
-                        if (de->d_type != DT_DIR)
-                                continue;
+        r = conf_files_list_strv_full(".d", arg_root, CONF_FILES_DIRECTORY, (const char * const *) CONF_PATHS_STRV(""), &directories, &n_directories);
+        if (r < 0)
+                return log_error_errno(r, "Failed to enumerate directories: %m");
 
-                        if (dot_or_dot_dot(de->d_name))
-                                continue;
+        FOREACH_ARRAY(i, directories, n_directories) {
+                ConfFile *e = *i;
 
-                        if (streq(de->d_name, "sysupdate.d")) {
-                                has_default_component = true;
-                                continue;
-                        }
+                if (streq(e->name, "sysupdate.d")) {
+                        has_default_component = true;
+                        continue;
+                }
 
-                        e = startswith(de->d_name, "sysupdate.");
-                        if (!e)
-                                continue;
+                const char *s = startswith(e->name, "sysupdate.");
+                if (!s)
+                        continue;
 
-                        a = endswith(e, ".d");
-                        if (!a)
-                                continue;
+                const char *a = endswith(s, ".d");
+                if (!a)
+                        continue;
 
-                        n = strndup(e, a - e);
-                        if (!n)
-                                return log_oom();
+                _cleanup_free_ char *n = strndup(s, a - s);
+                if (!n)
+                        return log_oom();
 
-                        r = component_name_valid(n);
-                        if (r < 0)
-                                return log_error_errno(r, "Unable to validate component name: %m");
-                        if (r == 0)
-                                continue;
+                r = component_name_valid(n);
+                if (r < 0)
+                        return log_error_errno(r, "Unable to validate component name '%s': %m", n);
+                if (r == 0)
+                        continue;
 
-                        r = set_ensure_consume(&names, &string_hash_ops_free, TAKE_PTR(n));
-                        if (r < 0 && r != -EEXIST)
-                                return log_error_errno(r, "Failed to add component to set: %m");
-                }
+                r = set_ensure_put(&names, &string_hash_ops_free, n);
+                if (r < 0 && r != -EEXIST)
+                        return log_error_errno(r, "Failed to add component '%s' to set: %m", n);
+                TAKE_PTR(n);
         }
 
-        z = set_get_strv(names);
+        /* We use simple free() rather than strv_free() here, since set_free() will free the strings for us */
+        _cleanup_free_ char **z = set_get_strv(names);
         if (!z)
                 return log_oom();