From: Yu Watanabe Date: Thu, 22 Sep 2022 04:01:15 +0000 (+0900) Subject: core: make exec_directory_add() extends existing symlinks X-Git-Tag: v252-rc2~66^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=564e5c987877f7e481d896c7fd82e8e5a69addc2;p=thirdparty%2Fsystemd.git core: make exec_directory_add() extends existing symlinks Follow-up for 211a3d87fb1fe971dc42a47b4c5cc167def8ab4e. Previously, although ExecDirectoryItem.symlinks is strv, it always contains at most one symlink. --- diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 7035d9fbf8b..57036936f9a 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -3320,7 +3320,7 @@ int bus_exec_context_set_transient_property( _cleanup_free_ char *joined = NULL; STRV_FOREACH(source, l) { - r = exec_directory_add(&d->items, &d->n_items, *source, NULL); + r = exec_directory_add(d, *source, NULL); if (r < 0) return log_oom(); } @@ -3765,21 +3765,8 @@ int bus_exec_context_set_transient_property( if (!UNIT_WRITE_FLAGS_NOOP(flags)) { _cleanup_free_ char *destination_escaped = NULL, *source_escaped = NULL; - ExecDirectoryItem *item = NULL; - - /* Adding new directories is supported from both *DirectorySymlink methods and the - * older ones, so try to find an existing configuration first and create it if it's - * not there yet. */ - for (size_t j = 0; j < directory->n_items; ++j) - if (path_equal(source, directory->items[j].path)) { - item = &directory->items[j]; - break; - } - - if (item) - r = strv_extend(&item->symlinks, destination); - else - r = exec_directory_add(&directory->items, &directory->n_items, source, STRV_MAKE(destination)); + + r = exec_directory_add(directory, source, destination); if (r < 0) return r; diff --git a/src/core/execute.c b/src/core/execute.c index 6a4e1e09547..955e2cf6288 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -7040,33 +7040,54 @@ void exec_directory_done(ExecDirectory *d) { d->mode = 0755; } -int exec_directory_add(ExecDirectoryItem **d, size_t *n, const char *path, char **symlinks) { +static ExecDirectoryItem *exec_directory_find(ExecDirectory *d, const char *path) { + assert(d); + assert(path); + + for (size_t i = 0; i < d->n_items; i++) + if (path_equal(d->items[i].path, path)) + return &d->items[i]; + + return NULL; +} + +int exec_directory_add(ExecDirectory *d, const char *path, const char *symlink) { _cleanup_strv_free_ char **s = NULL; _cleanup_free_ char *p = NULL; + ExecDirectoryItem *existing; + int r; assert(d); - assert(n); assert(path); + existing = exec_directory_find(d, path); + if (existing) { + r = strv_extend(&existing->symlinks, symlink); + if (r < 0) + return r; + + return 0; /* existing item is updated */ + } + p = strdup(path); if (!p) return -ENOMEM; - if (symlinks) { - s = strv_copy(symlinks); + if (symlink) { + s = strv_new(symlink); if (!s) return -ENOMEM; } - if (!GREEDY_REALLOC(*d, *n + 1)) + if (!GREEDY_REALLOC(d->items, d->n_items + 1)) return -ENOMEM; - (*d)[(*n) ++] = (ExecDirectoryItem) { + d->items[d->n_items++] = (ExecDirectoryItem) { .path = TAKE_PTR(p), .symlinks = TAKE_PTR(s), }; - return 0; + return 1; /* new item is added */ } DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(exec_set_credential_hash_ops, char, string_hash_func, string_compare_func, ExecSetCredential, exec_set_credential_free); diff --git a/src/core/execute.h b/src/core/execute.h index 904e7943f32..fc6d36aa00d 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -492,7 +492,7 @@ ExecLoadCredential *exec_load_credential_free(ExecLoadCredential *lc); DEFINE_TRIVIAL_CLEANUP_FUNC(ExecLoadCredential*, exec_load_credential_free); void exec_directory_done(ExecDirectory *d); -int exec_directory_add(ExecDirectoryItem **d, size_t *n, const char *path, char **symlinks); +int exec_directory_add(ExecDirectory *d, const char *path, const char *symlink); extern const struct hash_ops exec_set_credential_hash_ops; extern const struct hash_ops exec_load_credential_hash_ops; diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index a7136c0b2bf..b39cb8cdff8 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -4629,10 +4629,8 @@ int config_parse_exec_directories( /* For State and Runtime directories we support an optional destination parameter, which * will be used to create a symlink to the source. */ - _cleanup_strv_free_ char **symlinks = NULL; + _cleanup_free_ char *dresolved = NULL; if (!isempty(dest)) { - _cleanup_free_ char *dresolved = NULL; - if (streq(lvalue, "ConfigurationDirectory")) { log_syntax(unit, LOG_WARNING, filename, line, 0, "Destination parameter is not supported for ConfigurationDirectory, ignoring: %s", tuple); @@ -4649,13 +4647,9 @@ int config_parse_exec_directories( r = path_simplify_and_warn(dresolved, PATH_CHECK_RELATIVE, unit, filename, line, lvalue); if (r < 0) continue; - - r = strv_consume(&symlinks, TAKE_PTR(dresolved)); - if (r < 0) - return log_oom(); } - r = exec_directory_add(&ed->items, &ed->n_items, sresolved, symlinks); + r = exec_directory_add(ed, sresolved, dresolved); if (r < 0) return log_oom(); }