]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: make exec_directory_add() extends existing symlinks
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 22 Sep 2022 04:01:15 +0000 (13:01 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 3 Oct 2022 00:25:00 +0000 (09:25 +0900)
Follow-up for 211a3d87fb1fe971dc42a47b4c5cc167def8ab4e.

Previously, although ExecDirectoryItem.symlinks is strv, it always
contains at most one symlink.

src/core/dbus-execute.c
src/core/execute.c
src/core/execute.h
src/core/load-fragment.c

index 7035d9fbf8bfd873de811915ac61641e19ad7867..57036936f9a2f441c53633e53897974646dec827 100644 (file)
@@ -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;
 
index 6a4e1e09547444ff9d743324c6b766bb76e75f3b..955e2cf628805960cb930adfde7319b46a726598 100644 (file)
@@ -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);
index 904e7943f32e29c20ca821997c83717333d0de4a..fc6d36aa00d3c594be1bc09af8fd22b68a317a07 100644 (file)
@@ -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;
index a7136c0b2bf119813c2d1e010f0ebbf101741e0f..b39cb8cdff8757d1501f2e9dbf10458d48bad35d 100644 (file)
@@ -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();
         }