]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
discover-image: make image_discover() allocate hashmap when necessary
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 11 Jun 2025 13:22:55 +0000 (22:22 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 11 Jun 2025 13:45:08 +0000 (22:45 +0900)
14 files changed:
src/dissect/dissect.c
src/import/importd.c
src/machine/image-dbus.c
src/machine/image.c
src/machine/machined-dbus.c
src/machine/machined-varlink.c
src/portable/portabled-bus.c
src/portable/portabled-image-bus.c
src/portable/portabled-image.c
src/portable/portabled-image.h
src/shared/discover-image.c
src/shared/discover-image.h
src/sysext/sysext.c
src/sysupdate/sysupdated.c

index 7b78a46d2514afb999eb8756b32cd54dcbe36a25..8dd8439ab8cf5edf36e64819d5e2974827e950bb 100644 (file)
@@ -1973,16 +1973,10 @@ static int action_with(DissectedImage *m, LoopDevice *d) {
 
 static int action_discover(void) {
         _cleanup_hashmap_free_ Hashmap *images = NULL;
-        _cleanup_(table_unrefp) Table *t = NULL;
-        Image *img;
         int r;
 
-        images = hashmap_new(&image_hash_ops);
-        if (!images)
-                return log_oom();
-
         for (ImageClass cl = 0; cl < _IMAGE_CLASS_MAX; cl++) {
-                r = image_discover(arg_runtime_scope, cl, NULL, images);
+                r = image_discover(arg_runtime_scope, cl, NULL, &images);
                 if (r < 0)
                         return log_error_errno(r, "Failed to discover images: %m");
         }
@@ -1992,13 +1986,14 @@ static int action_discover(void) {
                 return 0;
         }
 
-        t = table_new("name", "type", "class", "ro", "path", "time", "usage");
+        _cleanup_(table_unrefp) Table *t = table_new("name", "type", "class", "ro", "path", "time", "usage");
         if (!t)
                 return log_oom();
 
         table_set_align_percent(t, table_get_cell(t, 0, 6), 100);
         table_set_ersatz_string(t, TABLE_ERSATZ_DASH);
 
+        Image *img;
         HASHMAP_FOREACH(img, images) {
 
                 if (!arg_all && startswith(img->name, "."))
index a361ea74788870dee82c4d15017a78c2ce219ffe..2b59c965f75f496ac7eaf7624e98298776ff25f4 100644 (file)
@@ -1333,13 +1333,9 @@ static int method_list_images(sd_bus_message *msg, void *userdata, sd_bus_error
              class < 0 ? (c < _IMAGE_CLASS_MAX) : (c == class);
              c++) {
 
-                _cleanup_hashmap_free_ Hashmap *h = NULL;
+                _cleanup_hashmap_free_ Hashmap *images = NULL;
 
-                h = hashmap_new(&image_hash_ops);
-                if (!h)
-                        return -ENOMEM;
-
-                r = image_discover(m->runtime_scope, c, /* root= */ NULL, h);
+                r = image_discover(m->runtime_scope, c, /* root= */ NULL, &images);
                 if (r < 0) {
                         if (class >= 0)
                                 return r;
@@ -1349,7 +1345,7 @@ static int method_list_images(sd_bus_message *msg, void *userdata, sd_bus_error
                 }
 
                 Image *i;
-                HASHMAP_FOREACH(i, h) {
+                HASHMAP_FOREACH(i, images) {
                         r = sd_bus_message_append(
                                         reply,
                                         "(ssssbtttttt)",
index c91cedf12de54929272b40795d380b4c3136abd3..9142157ea4b8033e3c77c36a867544b4259f5e83 100644 (file)
@@ -396,24 +396,20 @@ char* image_bus_path(const char *name) {
 }
 
 static int image_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
-        _cleanup_hashmap_free_ Hashmap *images = NULL;
-        _cleanup_strv_free_ char **l = NULL;
         Manager *m = ASSERT_PTR(userdata);
-        Image *image;
         int r;
 
         assert(bus);
         assert(path);
         assert(nodes);
 
-        images = hashmap_new(&image_hash_ops);
-        if (!images)
-                return -ENOMEM;
-
-        r = image_discover(m->runtime_scope, IMAGE_MACHINE, NULL, images);
+        _cleanup_hashmap_free_ Hashmap *images = NULL;
+        r = image_discover(m->runtime_scope, IMAGE_MACHINE, NULL, &images);
         if (r < 0)
                 return r;
 
+        _cleanup_strv_free_ char **l = NULL;
+        Image *image;
         HASHMAP_FOREACH(image, images) {
                 char *p;
 
index 3e903b3f3f7ca9e81ce579c9919c6bf8596c3628..89e1c68e2592daecc946f75d65f047384b3845b6 100644 (file)
@@ -115,28 +115,23 @@ int image_clean_pool_operation(Manager *manager, ImageCleanPoolMode mode, Operat
         if (r < 0)
                 return log_debug_errno(r, "Failed to fork(): %m");
         if (r == 0) {
-                _cleanup_hashmap_free_ Hashmap *images = NULL;
-                bool success = true;
-                Image *image;
-
                 errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
 
-                images = hashmap_new(&image_hash_ops);
-                if (!images)
-                        report_errno_and_exit(errno_pipe_fd[1], ENOMEM);
-
-                r = image_discover(manager->runtime_scope, IMAGE_MACHINE, /* root = */ NULL, images);
+                _cleanup_hashmap_free_ Hashmap *images = NULL;
+                r = image_discover(manager->runtime_scope, IMAGE_MACHINE, /* root = */ NULL, &images);
                 if (r < 0) {
                         log_debug_errno(r, "Failed to discover images: %m");
                         report_errno_and_exit(errno_pipe_fd[1], r);
                 }
 
+                bool success = true;
                 ssize_t n = loop_write(result_fd, &success, sizeof(success));
                 if (n < 0) {
                         log_debug_errno(n, "Failed to write to tmp file: %m");
                         report_errno_and_exit(errno_pipe_fd[1], n);
                 }
 
+                Image *image;
                 HASHMAP_FOREACH(image, images) {
                         /* We can't remove vendor images (i.e. those in /usr) */
                         if (image_is_vendor(image))
index b13546df095078319538d1426b93993df0508227..222e3934d9ca5dd9b5f5b78e2f6c27ca93583077 100644 (file)
@@ -490,18 +490,13 @@ static int method_get_machine_os_release(sd_bus_message *message, void *userdata
 
 static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_error *error) {
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
-        _cleanup_hashmap_free_ Hashmap *images = NULL;
-        _unused_ Manager *m = ASSERT_PTR(userdata);
-        Image *image;
+        Manager *m = ASSERT_PTR(userdata);
         int r;
 
         assert(message);
 
-        images = hashmap_new(&image_hash_ops);
-        if (!images)
-                return -ENOMEM;
-
-        r = image_discover(m->runtime_scope, IMAGE_MACHINE, NULL, images);
+        _cleanup_hashmap_free_ Hashmap *images = NULL;
+        r = image_discover(m->runtime_scope, IMAGE_MACHINE, NULL, &images);
         if (r < 0)
                 return r;
 
@@ -513,6 +508,7 @@ static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_er
         if (r < 0)
                 return r;
 
+        Image *image;
         HASHMAP_FOREACH(image, images) {
                 _cleanup_free_ char *p = NULL;
 
index b429ceb974c69eb04959442d5b4d34eb5ce7c8bd..f3351724b4164094c47fbf0053167a9dd5eb47f9 100644 (file)
@@ -700,11 +700,8 @@ static int vl_method_list_images(sd_varlink *link, sd_json_variant *parameters,
         if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
                 return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL);
 
-        _cleanup_hashmap_free_ Hashmap *images = hashmap_new(&image_hash_ops);
-        if (!images)
-                return -ENOMEM;
-
-        r = image_discover(m->runtime_scope, IMAGE_MACHINE, /* root = */ NULL, images);
+        _cleanup_hashmap_free_ Hashmap *images = NULL;
+        r = image_discover(m->runtime_scope, IMAGE_MACHINE, /* root = */ NULL, &images);
         if (r < 0)
                 return log_debug_errno(r, "Failed to discover images: %m");
 
index e347db5c0db4763f0ef7c604fee9681b58dd806e..bc62d31c22b26a8b49ae13ddb6ca54ce260ea667 100644 (file)
@@ -141,11 +141,7 @@ static int method_list_images(sd_bus_message *message, void *userdata, sd_bus_er
 
         assert(message);
 
-        images = hashmap_new(&image_hash_ops);
-        if (!images)
-                return -ENOMEM;
-
-        r = manager_image_cache_discover(m, images, error);
+        r = manager_image_cache_discover(m, &images, error);
         if (r < 0)
                 return r;
 
index 8972da0802f05a8e12a40f93950bd2c1ac571013..caad5d4b5753f779e2736394b043886659e9901f 100644 (file)
@@ -1156,11 +1156,7 @@ int bus_image_node_enumerator(sd_bus *bus, const char *path, void *userdata, cha
         assert(path);
         assert(nodes);
 
-        images = hashmap_new(&image_hash_ops);
-        if (!images)
-                return -ENOMEM;
-
-        r = manager_image_cache_discover(m, images, error);
+        r = manager_image_cache_discover(m, &images, error);
         if (r < 0)
                 return r;
 
index 961ca4588a6881f620b230646d7794514d182d55..dd6e405bda34c65aa3e30ea248f1f520b75d8c1e 100644 (file)
@@ -85,8 +85,7 @@ int manager_image_cache_add(Manager *m, Image *image) {
         return 0;
 }
 
-int manager_image_cache_discover(Manager *m, Hashmap *images, sd_bus_error *error) {
-        Image *image;
+int manager_image_cache_discover(Manager *m, Hashmap **ret_images, sd_bus_error *error) {
         int r;
 
         assert(m);
@@ -94,12 +93,17 @@ int manager_image_cache_discover(Manager *m, Hashmap *images, sd_bus_error *erro
         /* A wrapper around image_discover() (for finding images in search path) and portable_discover_attached() (for
          * finding attached images). */
 
-        r = image_discover(m->runtime_scope, IMAGE_PORTABLE, NULL, images);
+        _cleanup_hashmap_free_ Hashmap *images = NULL;
+        r = image_discover(m->runtime_scope, IMAGE_PORTABLE, NULL, &images);
         if (r < 0)
                 return r;
 
+        Image *image;
         HASHMAP_FOREACH(image, images)
                 (void) manager_image_cache_add(m, image);
 
+        if (ret_images)
+                *ret_images = TAKE_PTR(images);
+
         return 0;
 }
index ababa411a88c92edca22615a759342d973d8d9e1..8497a42655dece66f1df6f207df8806165d60645 100644 (file)
@@ -7,4 +7,4 @@ Image *manager_image_cache_get(Manager *m, const char *name_or_path);
 
 int manager_image_cache_add(Manager *m, Image *image);
 
-int manager_image_cache_discover(Manager *m, Hashmap *images, sd_bus_error *error);
+int manager_image_cache_discover(Manager *m, Hashmap **ret_images, sd_bus_error *error);
index 099f5e03f33ee91c4ca3abd7de709b4e03e9cfe3..089d656f40015c325915879c1ade4bf453929b2b 100644 (file)
@@ -887,7 +887,7 @@ int image_discover(
                 RuntimeScope scope,
                 ImageClass class,
                 const char *root,
-                Hashmap *h) {
+                Hashmap **images) {
 
         /* As mentioned above, we follow symlinks on this fstatat(), because we want to permit people to
          * symlink block devices into the search path. (For now, we disable that when operating relative to
@@ -897,7 +897,7 @@ int image_discover(
         assert(scope < _RUNTIME_SCOPE_MAX && scope != RUNTIME_SCOPE_GLOBAL);
         assert(class >= 0);
         assert(class < _IMAGE_CLASS_MAX);
-        assert(h);
+        assert(images);
 
         _cleanup_strv_free_ char **search = NULL;
         r = pick_image_search_path(scope, class, &search);
@@ -1039,7 +1039,7 @@ int image_discover(
                                 continue;
                         }
 
-                        if (hashmap_contains(h, pretty))
+                        if (hashmap_contains(*images, pretty))
                                 continue;
 
                         r = image_make(class, pretty, dirfd(d), resolved, fname, fd, &st, &image);
@@ -1050,7 +1050,7 @@ int image_discover(
 
                         image->discoverable = true;
 
-                        r = hashmap_put(h, image->name, image);
+                        r = hashmap_ensure_put(images, &image_hash_ops, image->name, image);
                         if (r < 0)
                                 return r;
 
@@ -1058,7 +1058,7 @@ int image_discover(
                 }
         }
 
-        if (scope == RUNTIME_SCOPE_SYSTEM && class == IMAGE_MACHINE && !hashmap_contains(h, ".host")) {
+        if (scope == RUNTIME_SCOPE_SYSTEM && class == IMAGE_MACHINE && !hashmap_contains(*images, ".host")) {
                 _cleanup_(image_unrefp) Image *image = NULL;
 
                 r = image_make(IMAGE_MACHINE,
@@ -1074,7 +1074,7 @@ int image_discover(
 
                 image->discoverable = true;
 
-                r = hashmap_put(h, image->name, image);
+                r = hashmap_ensure_put(images, &image_hash_ops, image->name, image);
                 if (r < 0)
                         return r;
 
index 142c001f53af20fc895bb91ea053d53be575b4f0..60f5a4dce13574201c54e6bac8a2822012bdd1fb 100644 (file)
@@ -53,7 +53,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Image*, image_unref);
 int image_find(RuntimeScope scope, ImageClass class, const char *name, const char *root, Image **ret);
 int image_from_path(const char *path, Image **ret);
 int image_find_harder(RuntimeScope scope, ImageClass class, const char *name_or_path, const char *root, Image **ret);
-int image_discover(RuntimeScope scope, ImageClass class, const char *root, Hashmap *map);
+int image_discover(RuntimeScope scope, ImageClass class, const char *root, Hashmap **images);
 
 int image_remove(Image *i);
 int image_rename(Image *i, const char *new_name, RuntimeScope scope);
index a4aea64380c6f6e4794784837f543590907f212a..ffc3ebcf2cb34f1d42e1bd023da672cc4df75e1b 100644 (file)
@@ -2082,20 +2082,14 @@ static int merge(ImageClass image_class,
         return 1;
 }
 
-static int image_discover_and_read_metadata(
-                ImageClass image_class,
-                Hashmap **ret_images) {
+static int image_discover_and_read_metadata(ImageClass image_class, Hashmap **ret_images) {
         _cleanup_hashmap_free_ Hashmap *images = NULL;
         Image *img;
         int r;
 
         assert(ret_images);
 
-        images = hashmap_new(&image_hash_ops);
-        if (!images)
-                return log_oom();
-
-        r = image_discover(RUNTIME_SCOPE_SYSTEM, image_class, arg_root, images);
+        r = image_discover(RUNTIME_SCOPE_SYSTEM, image_class, arg_root, &images);
         if (r < 0)
                 return log_error_errno(r, "Failed to discover images: %m");
 
@@ -2105,7 +2099,8 @@ static int image_discover_and_read_metadata(
                         return log_error_errno(r, "Failed to read metadata for image %s: %m", img->name);
         }
 
-        *ret_images = TAKE_PTR(images);
+        if (ret_images)
+                *ret_images = TAKE_PTR(images);
 
         return 0;
 }
@@ -2338,11 +2333,7 @@ static int verb_list(int argc, char **argv, void *userdata) {
         Image *img;
         int r;
 
-        images = hashmap_new(&image_hash_ops);
-        if (!images)
-                return log_oom();
-
-        r = image_discover(RUNTIME_SCOPE_SYSTEM, arg_image_class, arg_root, images);
+        r = image_discover(RUNTIME_SCOPE_SYSTEM, arg_image_class, arg_root, &images);
         if (r < 0)
                 return log_error_errno(r, "Failed to discover images: %m");
 
@@ -2384,9 +2375,6 @@ static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varl
         MethodListParameters p = {
         };
         _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
-        _cleanup_hashmap_free_ Hashmap *images = NULL;
-        ImageClass image_class = arg_image_class;
-        Image *img;
         int r;
 
         assert(link);
@@ -2395,18 +2383,17 @@ static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varl
         if (r != 0)
                 return r;
 
+        ImageClass image_class = arg_image_class;
         r = parse_image_class_parameter(link, p.class, &image_class, NULL);
         if (r < 0)
                 return r;
 
-        images = hashmap_new(&image_hash_ops);
-        if (!images)
-                return -ENOMEM;
-
-        r = image_discover(RUNTIME_SCOPE_SYSTEM, image_class, arg_root, images);
+        _cleanup_hashmap_free_ Hashmap *images = NULL;
+        r = image_discover(RUNTIME_SCOPE_SYSTEM, image_class, arg_root, &images);
         if (r < 0)
                 return r;
 
+        Image *img;
         HASHMAP_FOREACH(img, images) {
                 if (v) {
                         /* Send previous item with more=true */
index fa04515feec5f1234441f09130880a5a62c47e30..3d65d99389bb240c5a0a7fb4884c033cb900e984 100644 (file)
@@ -1762,11 +1762,7 @@ static int manager_enumerate_image_class(Manager *m, TargetClass class) {
         Image *image;
         int r;
 
-        images = hashmap_new(&image_hash_ops);
-        if (!images)
-                return -ENOMEM;
-
-        r = image_discover(m->runtime_scope, (ImageClass) class, NULL, images);
+        r = image_discover(m->runtime_scope, (ImageClass) class, NULL, &images);
         if (r < 0)
                 return r;