]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
portable: Don't refuse copying out instance of template that exists 40427/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 16 Jan 2026 20:25:10 +0000 (21:25 +0100)
committerDaan De Meyer <daan@amutable.com>
Tue, 3 Feb 2026 14:03:51 +0000 (15:03 +0100)
There's no reason to refuse copying out capsule@abc.service even if
capsule@.service already exists on the host, so let's optionally not
search for templates if we can't find an instance when looking up
units and use it in portabled.

src/portable/portable.c
src/shared/install.c
src/shared/install.h
src/ssh-generator/ssh-generator.c

index b65fa7467eeeb68c016798552d485bd109be388c..2b709f22f5f55d25583adfa0859ce484de423898 100644 (file)
@@ -2047,7 +2047,7 @@ int portable_attach(
 
         if (!FLAGS_SET(flags, PORTABLE_REATTACH) && !FLAGS_SET(flags, PORTABLE_FORCE_ATTACH))
                 HASHMAP_FOREACH(item, unit_files) {
-                        r = unit_file_exists(scope, &paths, item->name);
+                        r = unit_file_exists_full(scope, &paths, SEARCH_IGNORE_TEMPLATE, item->name, /* ret_path= */ NULL);
                         if (r < 0)
                                 return sd_bus_error_set_errnof(error, r, "Failed to determine whether unit '%s' exists on the host: %m", item->name);
                         if (r > 0)
index 4c68821562c74450f76bd5293bebf5388ce654df..d3e5a1fb5ae6674e4dbbf8ffe9abeae49b383b2f 100644 (file)
 
 #define UNIT_FILE_FOLLOW_SYMLINK_MAX 64
 
-typedef enum SearchFlags {
-        SEARCH_LOAD                   = 1 << 0,
-        SEARCH_FOLLOW_CONFIG_SYMLINKS = 1 << 1,
-        SEARCH_DROPIN                 = 1 << 2,
-} SearchFlags;
-
 typedef struct {
         RuntimeScope scope;
         OrderedHashmap *will_process;
@@ -1563,7 +1557,7 @@ static int unit_file_search(
 
         assert(info->name);
 
-        if (unit_name_is_valid(info->name, UNIT_NAME_INSTANCE)) {
+        if (!FLAGS_SET(flags, SEARCH_IGNORE_TEMPLATE) && unit_name_is_valid(info->name, UNIT_NAME_INSTANCE)) {
                 r = unit_name_template(info->name, &template);
                 if (r < 0)
                         return r;
@@ -3242,7 +3236,7 @@ int unit_file_get_state(
 int unit_file_exists_full(
                 RuntimeScope scope,
                 const LookupPaths *lp,
-                bool follow,
+                SearchFlags flags,
                 const char *name,
                 char **ret_path) {
 
@@ -3262,7 +3256,7 @@ int unit_file_exists_full(
                         &c,
                         lp,
                         name,
-                        follow ? SEARCH_FOLLOW_CONFIG_SYMLINKS : 0,
+                        flags,
                         ret_path ? &info : NULL,
                         /* changes= */ NULL,
                         /* n_changes= */ NULL);
index 98d5a41d3e5101ac58452c73d3badab74e0fb988..ad5803e32168e3d1095bfda42c0333a0b0829752 100644 (file)
@@ -39,6 +39,13 @@ typedef enum UnitFileFlags {
         _UNIT_FILE_FLAGS_MASK_PUBLIC = UNIT_FILE_RUNTIME|UNIT_FILE_PORTABLE|UNIT_FILE_FORCE,
 } UnitFileFlags;
 
+typedef enum SearchFlags {
+        SEARCH_LOAD                   = 1 << 0,
+        SEARCH_FOLLOW_CONFIG_SYMLINKS = 1 << 1,
+        SEARCH_DROPIN                 = 1 << 2,
+        SEARCH_IGNORE_TEMPLATE        = 1 << 3, /* Don't look up the template if the instance does not exist. */
+} SearchFlags;
+
 /* type can be either one of the INSTALL_CHANGE_SYMLINK, INSTALL_CHANGE_UNLINK, … listed above, or a negative
  * errno value.
  *
@@ -184,12 +191,12 @@ int unit_file_get_state(RuntimeScope scope, const char *root_dir, const char *fi
 int unit_file_exists_full(
                 RuntimeScope scope,
                 const LookupPaths *lp,
-                bool follow,
+                SearchFlags flags,
                 const char *name,
                 char **ret_path);
 
 static inline int unit_file_exists(RuntimeScope scope, const LookupPaths *lp, const char *name) {
-        return unit_file_exists_full(scope, lp, false, name, NULL);
+        return unit_file_exists_full(scope, lp, 0, name, NULL);
 }
 
 int unit_file_get_list(RuntimeScope scope, const char *root_dir, char * const *states, char * const *patterns, Hashmap **ret);
index e596d369338b6ea564aa4f9e8c12e088ecfcc2ec..3923710b5cca07cecae53bfe8a58b0fbbcb767a8 100644 (file)
@@ -474,7 +474,7 @@ static int run(const char *dest, const char *dest_early, const char *dest_late)
 
         _cleanup_free_ char *found_sshd_template_unit = NULL;
         r = unit_file_exists_full(RUNTIME_SCOPE_SYSTEM, &lp,
-                                  /* follow = */ true,
+                                  SEARCH_FOLLOW_CONFIG_SYMLINKS,
                                   "sshd@.service",
                                   &found_sshd_template_unit);
         if (r < 0)