]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
portable: fix marker_matches_images() and propagate errors correctly 42915/head
authorLuca Boccassi <luca.boccassi@gmail.com>
Tue, 7 Jul 2026 10:16:42 +0000 (11:16 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Tue, 7 Jul 2026 17:03:00 +0000 (18:03 +0100)
marker_matches_images() was declared to return bool, but several of its
paths return a negative errno (OOM, parse errors, etc.). A negative int
coerces to true, so every such failure was reported as a "match".

Return int with the tristate semantics the callers already expect.

When detaching by image name instead of the original path, path_pick() may
not resolve a concrete path (e.g. a runtime overlay). Keep comparing the
caller-provided image name, and use the picked path only as an additional
canonical match when it exists.

Follow-up for 907952bbc92dd6656807d9b2eb0d0c94a4c9e865

src/portable/portable.c

index c1abe16985d7a92ddb0739548551d1ecdc914d31..2b398ec07566df942cc9ab5ac586bae8992e1a2a 100644 (file)
@@ -2164,7 +2164,7 @@ int portable_attach(
         return 0;
 }
 
-static bool marker_matches_images(const char *marker, const char *name_or_path, char **extension_image_paths, bool match_all) {
+static int marker_matches_images(const char *marker, const char *name_or_path, char **extension_image_paths, bool match_all) {
         _cleanup_strv_free_ char **root_and_extensions = NULL;
         int r;
 
@@ -2190,7 +2190,7 @@ static bool marker_matches_images(const char *marker, const char *name_or_path,
         /* Ensure the number of images passed matches the number of images listed in the marker */
         while (!isempty(marker))
                 STRV_FOREACH(image_name_or_path, root_and_extensions) {
-                        _cleanup_free_ char *image = NULL, *base_image = NULL, *base_image_name_or_path = NULL;
+                        _cleanup_free_ char *image = NULL, *base_image = NULL, *base_image_name_or_path = NULL, *base_picked_image = NULL;
                         _cleanup_(pick_result_done) PickResult result = PICK_RESULT_NULL;
 
                         r = extract_first_word(&marker, &image, ":", EXTRACT_UNQUOTE|EXTRACT_RETAIN_ESCAPE);
@@ -2211,19 +2211,21 @@ static bool marker_matches_images(const char *marker, const char *name_or_path,
                                       ELEMENTSOF(pick_filter_image_any),
                                       PICK_ARCHITECTURE|PICK_TRIES|PICK_RESOLVE,
                                       &result);
-                        if (r < 0)
+                        if (r < 0 && r != -ENOENT)
                                 return r;
-                        if (!result.path)
-                                return log_debug_errno(
-                                                SYNTHETIC_ERRNO(ENOENT),
-                                                "No matching entry in .v/ directory %s found.",
-                                                *image_name_or_path);
 
-                        r = path_extract_image_name(result.path, &base_image_name_or_path);
+                        r = path_extract_image_name(*image_name_or_path, &base_image_name_or_path);
                         if (r < 0)
-                                return log_debug_errno(r, "Failed to extract image name from %s, ignoring: %m", result.path);
+                                return log_debug_errno(r, "Failed to extract image name from %s, ignoring: %m", *image_name_or_path);
+
+                        if (!streq(base_image, base_image_name_or_path) && result.path) {
+                                r = path_extract_image_name(result.path, &base_picked_image);
+                                if (r < 0)
+                                        return log_debug_errno(r, "Failed to extract image name from %s, ignoring: %m", result.path);
+                        }
 
-                        if (!streq(base_image, base_image_name_or_path)) {
+                        if (!streq(base_image, base_image_name_or_path) &&
+                            !streq_ptr(base_image, base_picked_image)) {
                                 if (match_all)
                                         return false;
                         } else if (!match_all)