From 5035e4a4f878ee824b72a561195a1f1de44d0f7f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 13 Jul 2025 10:36:08 +0900 Subject: [PATCH 1/3] sysupdate: use conf_files_list_strv_full() to enumerate components With this change, root directory is correctly supported, and symlinked components are also correctly enumerated. --- src/sysupdate/sysupdate.c | 94 ++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 56 deletions(-) diff --git a/src/sysupdate/sysupdate.c b/src/sysupdate/sysupdate.c index 692291fcfe..0b0e4e9fe3 100644 --- a/src/sysupdate/sysupdate.c +++ b/src/sysupdate/sysupdate.c @@ -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) + CLEANUP_ARRAY(directories, n_directories, conf_file_free_many); + + 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"); + + FOREACH_ARRAY(i, directories, n_directories) { + ConfFile *e = *i; + + if (streq(e->name, "sysupdate.d")) { + has_default_component = true; 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; - } - - if (de->d_type != DT_DIR) - continue; - - if (dot_or_dot_dot(de->d_name)) - continue; - - if (streq(de->d_name, "sysupdate.d")) { - has_default_component = true; - continue; - } - - e = startswith(de->d_name, "sysupdate."); - if (!e) - continue; - - a = endswith(e, ".d"); - if (!a) - continue; - - n = strndup(e, a - e); - 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 = 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"); } + + const char *s = startswith(e->name, "sysupdate."); + if (!s) + continue; + + const char *a = endswith(s, ".d"); + if (!a) + continue; + + _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 '%s': %m", n); + if (r == 0) + continue; + + 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(); From 11a1f68217f436e193f7bc7d6b5a9b2a739efb5f Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 13 Jul 2025 10:50:27 +0900 Subject: [PATCH 2/3] sysupdate: use conf_files_list_strv_full() to enumerate features No functional change, just refactoring. --- src/sysupdate/sysupdate.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/sysupdate/sysupdate.c b/src/sysupdate/sysupdate.c index 0b0e4e9fe3..e0d63cade4 100644 --- a/src/sysupdate/sysupdate.c +++ b/src/sysupdate/sysupdate.c @@ -176,7 +176,7 @@ static int read_definitions( } static int context_read_definitions(Context *c, const char* node, bool requires_enabled_transfers) { - _cleanup_strv_free_ char **dirs = NULL, **files = NULL; + _cleanup_strv_free_ char **dirs = NULL; int r; assert(c); @@ -205,22 +205,26 @@ static int context_read_definitions(Context *c, const char* node, bool requires_ if (!dirs) return log_oom(); - r = conf_files_list_strv(&files, - ".feature", - arg_root, - CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, - (const char**) dirs); + ConfFile **files = NULL; + size_t n_files = 0; + + CLEANUP_ARRAY(files, n_files, conf_file_free_many); + + r = conf_files_list_strv_full(".feature", arg_root, + CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, + (const char**) dirs, &files, &n_files); if (r < 0) return log_error_errno(r, "Failed to enumerate sysupdate.d/*.feature definitions: %m"); - STRV_FOREACH(p, files) { + FOREACH_ARRAY(i, files, n_files) { _cleanup_(feature_unrefp) Feature *f = NULL; + ConfFile *e = *i; f = feature_new(); if (!f) return log_oom(); - r = feature_read_definition(f, *p, (const char**) dirs); + r = feature_read_definition(f, e->result, (const char**) dirs); if (r < 0) return r; From ee120e5caa6f549f70127447d670eb613f72c8ee Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 15 Jul 2025 23:38:27 +0900 Subject: [PATCH 3/3] sysupdate: use conf_files_list_strv_full() to enumerate definitions No functional change, just refactoring. --- src/sysupdate/sysupdate.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/sysupdate/sysupdate.c b/src/sysupdate/sysupdate.c index e0d63cade4..e45e230b60 100644 --- a/src/sysupdate/sysupdate.c +++ b/src/sysupdate/sysupdate.c @@ -127,11 +127,12 @@ static int read_definitions( const char *suffix, const char *node) { - _cleanup_strv_free_ char **files = NULL; + ConfFile **files = NULL; Transfer **transfers = NULL, **disabled = NULL; - size_t n_transfers = 0, n_disabled = 0; + size_t n_files = 0, n_transfers = 0, n_disabled = 0; int r; + CLEANUP_ARRAY(files, n_files, conf_file_free_many); CLEANUP_ARRAY(transfers, n_transfers, free_transfers); CLEANUP_ARRAY(disabled, n_disabled, free_transfers); @@ -139,19 +140,20 @@ static int read_definitions( assert(dirs); assert(suffix); - r = conf_files_list_strv(&files, suffix, arg_root, CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, dirs); + r = conf_files_list_strv_full(suffix, arg_root, CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, dirs, &files, &n_files); if (r < 0) return log_error_errno(r, "Failed to enumerate sysupdate.d/*%s definitions: %m", suffix); - STRV_FOREACH(p, files) { + FOREACH_ARRAY(i, files, n_files) { _cleanup_(transfer_freep) Transfer *t = NULL; Transfer **appended; + ConfFile *e = *i; t = transfer_new(c); if (!t) return log_oom(); - r = transfer_read_definition(t, *p, dirs, c->features); + r = transfer_read_definition(t, e->result, dirs, c->features); if (r < 0) return r;