]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
generator: teach generator_add_symlink() to instantiate specified unit
authorLennart Poettering <lennart@poettering.net>
Sun, 16 Oct 2022 20:39:31 +0000 (22:39 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 17 Jan 2023 08:42:16 +0000 (09:42 +0100)
if we want generators to instantiate a template service, we need to
teach generator_add_symlink() the concept.

Just some preparation for a later commit.

While we are at it, modernize the function around
path_extract_filename() + path_extract_directory()

src/shared/generator.c
src/shared/generator.h

index 6d95aa72f8788533441e2876ae76271445455c26..ec0182d05e7826d3811087eb42248c15ebc948d4 100644 (file)
@@ -59,25 +59,53 @@ int generator_open_unit_file(
         return 0;
 }
 
-int generator_add_symlink(const char *dir, const char *dst, const char *dep_type, const char *src) {
-        _cleanup_free_ char *bn = NULL;
-        const char *from, *to;
+
+int generator_add_symlink_full(
+                const char *dir,
+                const char *dst,
+                const char *dep_type,
+                const char *src,
+                const char *instance) {
+
+        _cleanup_free_ char *dn = NULL, *fn = NULL, *instantiated = NULL, *to = NULL, *from = NULL;
         int r;
 
-        /* Adds a symlink from <dst>.<dep_type>/ to <src> (if src is absolute)
-         * or ../<src> (otherwise). */
+        assert(dir);
+        assert(dst);
+        assert(dep_type);
+        assert(src);
 
-        r = path_extract_filename(src, &bn);
+        /* Adds a symlink from <dst>.<dep_type>/ to <src> (if src is absolute) or ../<src> (otherwise). If
+         * <instance> is specified, then <src> must be a template unit name, and we'll instantiate it. */
+
+        r = path_extract_directory(src, &dn);
+        if (r < 0 && r != -EDESTADDRREQ) /* EDESTADDRREQ → just a file name was passed */
+                return log_error_errno(r, "Failed to extract directory name from '%s': %m", src);
+
+        r = path_extract_filename(src, &fn);
         if (r < 0)
-                return log_error_errno(r, "Failed to extract filename from '%s': %m", src);
+                return log_error_errno(r, "Failed to extract file name from '%s': %m", src);
+        if (r == O_DIRECTORY)
+                return log_error_errno(SYNTHETIC_ERRNO(EISDIR), "Expected path to regular file name, but got '%s', refusing.", src);
 
-        from = path_is_absolute(src) ? src : strjoina("../", src);
-        to = strjoina(dir, "/", dst, ".", dep_type, "/", bn);
+        if (instance) {
+                r = unit_name_replace_instance(fn, instance, &instantiated);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to instantiate '%s' for '%s': %m", fn, instance);
+        }
+
+        from = path_join(dn ?: "..", fn);
+        if (!from)
+                return log_oom();
+
+        to = strjoin(dir, "/", dst, ".", dep_type, "/", instantiated ?: fn);
+        if (!to)
+                return log_oom();
 
         (void) mkdir_parents_label(to, 0755);
-        if (symlink(from, to) < 0)
-                if (errno != EEXIST)
-                        return log_error_errno(errno, "Failed to create symlink \"%s\": %m", to);
+
+        if (symlink(from, to) < 0 && errno != EEXIST)
+                return log_error_errno(errno, "Failed to create symlink \"%s\": %m", to);
 
         return 0;
 }
index 1b4f36ac53c6796713690dad7e122d0c36287355..a4049dbd8fb1c6a51de55928f54413a4355e813b 100644 (file)
@@ -12,7 +12,11 @@ int generator_open_unit_file(
         const char *name,
         FILE **file);
 
-int generator_add_symlink(const char *dir, const char *dst, const char *dep_type, const char *src);
+int generator_add_symlink_full(const char *dir, const char *dst, const char *dep_type, const char *src, const char *instance);
+
+static inline int generator_add_symlink(const char *dir, const char *dst, const char *dep_type, const char *src) {
+        return generator_add_symlink_full(dir, dst, dep_type, src, NULL);
+}
 
 int generator_write_fsck_deps(
         FILE *f,