diff options
Diffstat (limited to '0051-refactor-remote-ro-code.patch')
-rw-r--r-- | 0051-refactor-remote-ro-code.patch | 2089 |
1 files changed, 2089 insertions, 0 deletions
diff --git a/0051-refactor-remote-ro-code.patch b/0051-refactor-remote-ro-code.patch new file mode 100644 index 0000000..c9269cb --- /dev/null +++ b/0051-refactor-remote-ro-code.patch @@ -0,0 +1,2089 @@ +From d4816441dc5ad67cc8cbab565e5ddc0eaf838611 Mon Sep 17 00:00:00 2001 +From: "Neil.wrz" <wangrunze13@huawei.com> +Date: Mon, 6 Mar 2023 17:43:17 -0800 +Subject: [PATCH 51/53] refactor remote ro code + +Signed-off-by: Neil.wrz <wangrunze13@huawei.com> +--- + CI/make-and-install.sh | 2 +- + .../oci/storage/image_store/CMakeLists.txt | 3 - + .../oci/storage/image_store/image_store.c | 37 +-- + .../oci/storage/image_store/image_store.h | 13 +- + .../oci/storage/layer_store/CMakeLists.txt | 3 - + .../graphdriver/overlay2/CMakeLists.txt | 3 - + .../graphdriver/overlay2/driver_overlay2.h | 8 - + .../oci/storage/layer_store/layer_store.c | 230 +++++++++--------- + .../oci/storage/layer_store/layer_store.h | 9 +- + .../image_remote_impl.c | 61 +++-- + .../layer_remote_impl.c | 71 +++--- + .../overlay_remote_impl.c | 103 +++++--- + .../remote_layer_support/remote_support.c | 141 ++++++----- + .../remote_layer_support/remote_support.h | 62 +++-- + .../ro_symlink_maintain.c | 124 +--------- + .../ro_symlink_maintain.h | 19 +- + .../modules/image/oci/storage/storage.c | 4 +- + src/utils/cutils/map/rb_tree.c | 1 + + test/image/oci/registry/CMakeLists.txt | 2 + + test/image/oci/storage/CMakeLists.txt | 3 + + test/image/oci/storage/images/CMakeLists.txt | 2 + + test/image/oci/storage/layers/CMakeLists.txt | 4 + + .../remote_layer_support/CMakeLists.txt | 44 ++++ + .../remote_layer_support/remote_layer_ut.cc | 93 +++++++ + test/image/oci/storage/rootfs/CMakeLists.txt | 2 + + test/mocks/remote_store_mock.cc | 68 ++++++ + test/mocks/remote_store_mock.h | 40 +++ + 27 files changed, 683 insertions(+), 469 deletions(-) + rename src/daemon/modules/image/oci/storage/{image_store => remote_layer_support}/image_remote_impl.c (71%) + rename src/daemon/modules/image/oci/storage/{layer_store => remote_layer_support}/layer_remote_impl.c (76%) + rename src/daemon/modules/image/oci/storage/{layer_store/graphdriver/overlay2 => remote_layer_support}/overlay_remote_impl.c (72%) + create mode 100644 test/image/oci/storage/remote_layer_support/CMakeLists.txt + create mode 100644 test/image/oci/storage/remote_layer_support/remote_layer_ut.cc + create mode 100644 test/mocks/remote_store_mock.cc + create mode 100644 test/mocks/remote_store_mock.h + +diff --git a/CI/make-and-install.sh b/CI/make-and-install.sh +index faeaf005..fa9c2250 100755 +--- a/CI/make-and-install.sh ++++ b/CI/make-and-install.sh +@@ -103,7 +103,7 @@ rm -rf build + mkdir build + cd build + if [[ ${enable_gcov} -ne 0 ]]; then +- cmake -DLIB_INSTALL_DIR=${builddir}/lib -DCMAKE_INSTALL_PREFIX=${builddir} -DCMAKE_INSTALL_SYSCONFDIR=${builddir}/etc -DCMAKE_BUILD_TYPE=Debug -DGCOV=ON -DENABLE_EMBEDDED=ON -DENABLE_COVERAGE=ON -DENABLE_UT=ON -DENABLE_METRICS=ON .. ++ cmake -DLIB_INSTALL_DIR=${builddir}/lib -DCMAKE_INSTALL_PREFIX=${builddir} -DCMAKE_INSTALL_SYSCONFDIR=${builddir}/etc -DCMAKE_BUILD_TYPE=Debug -DGCOV=ON -DENABLE_EMBEDDED=ON -DENABLE_COVERAGE=ON -DENABLE_UT=ON -DENABLE_METRICS=ON -DENABLE_REMOTE_LAYER_STORE=ON .. + else + cmake -DLIB_INSTALL_DIR=${builddir}/lib -DCMAKE_INSTALL_PREFIX=${builddir} -DCMAKE_INSTALL_SYSCONFDIR=${builddir}/etc -DENABLE_EMBEDDED=ON -DENABLE_METRICS=ON -DENABLE_REMOTE_LAYER_STORE=ON .. + fi +diff --git a/src/daemon/modules/image/oci/storage/image_store/CMakeLists.txt b/src/daemon/modules/image/oci/storage/image_store/CMakeLists.txt +index 7d4fb77c..ecf21caa 100644 +--- a/src/daemon/modules/image/oci/storage/image_store/CMakeLists.txt ++++ b/src/daemon/modules/image/oci/storage/image_store/CMakeLists.txt +@@ -1,8 +1,5 @@ + # get current directory sources files + aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} local_image_store_srcs) +-IF (NOT ENABLE_REMOTE_LAYER_STORE) +-list(REMOVE_ITEM local_image_store_srcs "${CMAKE_CURRENT_SOURCE_DIR}/image_remote_impl.c") +-ENDIF() + + set(IMAGE_STORE_SRCS + ${local_image_store_srcs} +diff --git a/src/daemon/modules/image/oci/storage/image_store/image_store.c b/src/daemon/modules/image/oci/storage/image_store/image_store.c +index 84187ded..9a32b247 100644 +--- a/src/daemon/modules/image/oci/storage/image_store/image_store.c ++++ b/src/daemon/modules/image/oci/storage/image_store/image_store.c +@@ -132,7 +132,7 @@ static void free_image_store(image_store_t *store) + (void)map_free(store->bydigest); + store->bydigest = NULL; + +- linked_list_for_each_safe(item, &(store->images_list), next) { ++ linked_list_for_each_safe (item, &(store->images_list), next) { + linked_list_del(item); + image_ref_dec((image_t *)item->elem); + free(item); +@@ -164,7 +164,7 @@ static void image_store_digest_field_kvfree(void *key, void *value) + + free(key); + if (val != NULL) { +- linked_list_for_each_safe(item, &(val->images_list), next) { ++ linked_list_for_each_safe (item, &(val->images_list), next) { + linked_list_del(item); + free(item); + item = NULL; +@@ -500,7 +500,7 @@ static void digest_image_slice_without_value(digest_image_t *digest_filter_image + return; + } + +- linked_list_for_each_safe(item, &(digest_filter_images->images_list), next) { ++ linked_list_for_each_safe (item, &(digest_filter_images->images_list), next) { + tmp = (image_t *)item->elem; + if (strcmp(tmp->simage->id, img->simage->id) == 0) { + linked_list_del(item); +@@ -581,7 +581,7 @@ static int remove_image_from_memory(const char *id) + goto out; + } + +- linked_list_for_each_safe(item, &(g_image_store->images_list), next) { ++ linked_list_for_each_safe (item, &(g_image_store->images_list), next) { + image_t *tmp = (image_t *)item->elem; + if (strcmp(tmp->simage->id, id) != 0) { + continue; +@@ -680,7 +680,7 @@ static void free_digest_image(digest_image_t *ptr) + return; + } + +- linked_list_for_each_safe(item, &(ptr->images_list), next) { ++ linked_list_for_each_safe (item, &(ptr->images_list), next) { + linked_list_del(item); + free(item); + item = NULL; +@@ -2678,7 +2678,7 @@ int image_store_get_all_images(imagetool_images_list *images_list) + goto unlock; + } + +- linked_list_for_each_safe(item, &(g_image_store->images_list), next) { ++ linked_list_for_each_safe (item, &(g_image_store->images_list), next) { + imagetool_image_summary *imginfo = NULL; + image_t *img = (image_t *)item->elem; + imginfo = get_image_summary(img); +@@ -3099,7 +3099,7 @@ out: + return ret; + } + +-int validate_manifest_schema_version_1(const char *path, bool *valid) ++int image_store_validate_manifest_schema_version_1(const char *path, bool *valid) + { + int ret = 0; + int nret; +@@ -3506,7 +3506,7 @@ static int get_images_from_json() + continue; + } + +- if (validate_manifest_schema_version_1(image_path, &valid_v1_image) != 0) { ++ if (image_store_validate_manifest_schema_version_1(image_path, &valid_v1_image) != 0) { + ERROR("Failed to validate manifest schema version 1 format"); + continue; + } +@@ -3543,7 +3543,7 @@ static void image_store_check_all_images() + return; + } + +- linked_list_for_each_safe(item, &(g_image_store->images_list), next) { ++ linked_list_for_each_safe (item, &(g_image_store->images_list), next) { + image_t *img = (image_t *)item->elem; + if (img->spec == NULL) { + ERROR("Failed to check spec info of image: %s, try to delete", img->simage->id); +@@ -3657,18 +3657,23 @@ out: + } + + #ifdef ENABLE_REMOTE_LAYER_STORE +-int append_image_by_directory_with_lock(const char *id) ++int remote_append_image_by_directory_with_lock(const char *id) + { + int ret = 0; + int nret = 0; + char image_path[PATH_MAX] = { 0x00 }; + ++ if (id == NULL) { ++ ERROR("can't add NULL remote image"); ++ return -1; ++ } ++ + if (!image_store_lock(EXCLUSIVE)) { + ERROR("Failed to lock remote image store when handle: %s", id); + return -1; + } + +- if (map_search(g_image_store->byid, (void *)id) != NULL ) { ++ if (map_search(g_image_store->byid, (void *)id) != NULL) { + DEBUG("remote image already exist, not added: %s", id); + goto out; + } +@@ -3687,10 +3692,15 @@ out: + return ret; + } + +-int remove_image_from_memory_with_lock(const char *id) ++int remote_remove_image_from_memory_with_lock(const char *id) + { + int ret = 0; + ++ if (id == NULL) { ++ ERROR("can't remove NULL remote image"); ++ return -1; ++ } ++ + if (!image_store_lock(EXCLUSIVE)) { + ERROR("Failed to lock remote image store when handle: %s", id); + return -1; +@@ -3709,9 +3719,8 @@ out: + return ret; + } + +-char *get_top_layer_from_json(const char *img_id) ++char *remote_image_get_top_layer_from_json(const char *img_id) + { +- + char *ret = NULL; + int nret = 0; + char image_path[PATH_MAX] = { 0x00 }; +diff --git a/src/daemon/modules/image/oci/storage/image_store/image_store.h b/src/daemon/modules/image/oci/storage/image_store/image_store.h +index c3cb50e3..5164cc73 100644 +--- a/src/daemon/modules/image/oci/storage/image_store/image_store.h ++++ b/src/daemon/modules/image/oci/storage/image_store/image_store.h +@@ -28,9 +28,6 @@ + #include "isula_libutils/imagetool_image.h" + #include "isula_libutils/imagetool_images_list.h" + #include "isula_libutils/imagetool_image_summary.h" +-#ifdef ENABLE_REMOTE_LAYER_STORE +-#include "remote_support.h" +-#endif + + struct storage_module_init_options; + +@@ -112,11 +109,11 @@ void image_store_free(); + imagetool_image_summary *image_store_get_image_summary(const char *id); + + #ifdef ENABLE_REMOTE_LAYER_STORE +-remote_support *image_store_impl_remote_support(); +-int validate_manifest_schema_version_1(const char *path, bool *valid); +-int append_image_by_directory_with_lock(const char *image_dir); +-int remove_image_from_memory_with_lock(const char *id); +-char *get_top_layer_from_json(const char *img_id); /* return top layer id */ ++int image_store_validate_manifest_schema_version_1(const char *path, bool *valid); ++int remote_append_image_by_directory_with_lock(const char *image_dir); ++int remote_remove_image_from_memory_with_lock(const char *id); ++// return top layer id ++char *remote_image_get_top_layer_from_json(const char *img_id); + #endif + + #ifdef __cplusplus +diff --git a/src/daemon/modules/image/oci/storage/layer_store/CMakeLists.txt b/src/daemon/modules/image/oci/storage/layer_store/CMakeLists.txt +index e04b4ad7..c218a7c0 100644 +--- a/src/daemon/modules/image/oci/storage/layer_store/CMakeLists.txt ++++ b/src/daemon/modules/image/oci/storage/layer_store/CMakeLists.txt +@@ -1,8 +1,5 @@ + # get current directory sources files + aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} local_layer_store_srcs) +-IF (NOT ENABLE_REMOTE_LAYER_STORE) +-list(REMOVE_ITEM local_layer_store_srcs "${CMAKE_CURRENT_SOURCE_DIR}/layer_remote_impl.c") +-ENDIF() + add_subdirectory(graphdriver) + + set(LAYER_STORE_SRCS +diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/CMakeLists.txt b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/CMakeLists.txt +index dd4e82aa..ceed16b7 100644 +--- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/CMakeLists.txt ++++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/CMakeLists.txt +@@ -1,8 +1,5 @@ + # get current directory sources files + aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} local_overlay2_srcs) +-IF (NOT ENABLE_REMOTE_LAYER_STORE) +-list(REMOVE_ITEM local_overlay2_srcs "${CMAKE_CURRENT_SOURCE_DIR}/overlay_remote_impl.c") +-ENDIF() + + set(OVERLAY2_SRCS + ${local_overlay2_srcs} +diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.h b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.h +index 5c1d93fb..e14271b1 100644 +--- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.h ++++ b/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.h +@@ -22,9 +22,6 @@ + #include <stdint.h> + + #include "driver.h" +-#ifdef ENABLE_REMOTE_LAYER_STORE +-#include "remote_support.h" +-#endif + + struct driver_create_opts; + struct driver_mount_opts; +@@ -71,11 +68,6 @@ int overlay2_repair_lowers(const char *id, const char *parent, const struct grap + + int overlay2_get_layer_fs_info(const char *id, const struct graphdriver *driver, imagetool_fs_info *fs_info); + +-#ifdef ENABLE_REMOTE_LAYER_STORE +-remote_support *overlay_driver_impl_remote_support(void); +-bool overlay_remote_layer_valid(const char *layer_id); +-#endif +- + #ifdef __cplusplus + } + #endif +diff --git a/src/daemon/modules/image/oci/storage/layer_store/layer_store.c b/src/daemon/modules/image/oci/storage/layer_store/layer_store.c +index 4edd0cad..79339757 100644 +--- a/src/daemon/modules/image/oci/storage/layer_store/layer_store.c ++++ b/src/daemon/modules/image/oci/storage/layer_store/layer_store.c +@@ -1789,119 +1789,6 @@ out: + return ret; + } + +-static layer_t *load_one_layer_from_json(const char *id) +-{ +- int nret = 0; +- char *mount_point_path = NULL; +- char tmpdir[PATH_MAX] = { 0 }; +- char *rpath = NULL; +- layer_t *l = NULL; +- bool layer_valid = false; +- +- nret = snprintf(tmpdir, PATH_MAX, "%s/%s", g_root_dir, id); +- if (nret < 0 || nret >= PATH_MAX) { +- ERROR("Sprintf: %s failed", id); +- goto free_out; +- } +- +- mount_point_path = mountpoint_json_path(id); +- if (mount_point_path == NULL) { +- ERROR("Out of Memory"); +- goto free_out; +- } +- +- rpath = layer_json_path(id); +- if (rpath == NULL) { +- ERROR("%s is invalid layer", id); +- goto free_out; +- } +- +- l = load_layer(rpath, mount_point_path); +- if (l == NULL) { +- ERROR("load layer: %s failed, remove it", id); +- goto free_out; +- } +- +- if (do_validate_image_layer(tmpdir, l) != 0) { +- ERROR("%s is invalid image layer", id); +- goto free_out; +- } +- +- if (do_validate_rootfs_layer(l) != 0) { +- ERROR("%s is invalid rootfs layer", id); +- goto free_out; +- } +- +- layer_valid = true; +- +-free_out: +- free(rpath); +- free(mount_point_path); +- if (!layer_valid) { +- free_layer_t(l); +- l = NULL; +- } +- // always return true; +- // if load layer failed, just remove it +- return l; +-} +- +-int load_one_layer(const char *id) +-{ +- int ret = 0; +- layer_t *tl = NULL; +- int i = 0; +- +- if (!layer_store_lock(true)) { +- return -1; +- } +- +- if (map_search(g_metadata.by_id, (void *)id) != NULL) { +- DEBUG("remote layer already exist, not added: %s", id); +- goto unlock_out; +- } +- +- tl = load_one_layer_from_json(id); +- if (tl == NULL) { +- ret = -1; +- goto unlock_out; +- } +- +- if (!map_insert(g_metadata.by_id, (void *)tl->slayer->id, (void *)tl)) { +- ERROR("Insert id: %s for layer failed", tl->slayer->id); +- ret = -1; +- goto unlock_out; +- } +- +- for (; i < tl->slayer->names_len; i++) { +- // this should be done by master isulad +- // if (remove_name(tl->slayer->names[i])) { +- // should_save = true; +- // } +- if (!map_insert(g_metadata.by_name, (void *)tl->slayer->names[i], (void *)tl)) { +- ret = -1; +- ERROR("Insert name: %s for layer failed", tl->slayer->names[i]); +- goto unlock_out; +- } +- } +- ret = insert_digest_into_map(g_metadata.by_compress_digest, tl->slayer->compressed_diff_digest, tl->slayer->id); +- if (ret != 0) { +- ERROR("update layer: %s compress failed", tl->slayer->id); +- goto unlock_out; +- } +- +- ret = insert_digest_into_map(g_metadata.by_uncompress_digest, tl->slayer->diff_digest, tl->slayer->id); +- if (ret != 0) { +- ERROR("update layer: %s uncompress failed", tl->slayer->id); +- goto unlock_out; +- } +- +- ret = 0; +-unlock_out: +- layer_store_unlock(); +- return ret; +-} +- + static bool load_layer_json_cb(const char *path_name, const struct dirent *sub_dir, void *context) + { + #define LAYER_NAME_LEN 64 +@@ -2483,7 +2370,7 @@ container_inspect_graph_driver *layer_store_get_metadata_by_layer_id(const char + } + + #ifdef ENABLE_REMOTE_LAYER_STORE +-int remove_memory_stores_with_lock(const char *id) ++int remote_layer_remove_memory_stores_with_lock(const char *id) + { + int ret = 0; + +@@ -2496,6 +2383,11 @@ int remove_memory_stores_with_lock(const char *id) + goto unlock_out; + } + ++ if (map_search(g_metadata.by_id, (void *)id) == NULL) { ++ DEBUG("remote layer already removed, don't delete: %s", id); ++ goto unlock_out; ++ } ++ + ret = remove_memory_stores(id); + + unlock_out: +@@ -2503,4 +2395,114 @@ unlock_out: + + return ret; + } ++ ++static layer_t *load_one_layer_from_json(const char *id) ++{ ++ int nret = 0; ++ char *mount_point_path = NULL; ++ char tmpdir[PATH_MAX] = { 0 }; ++ char *rpath = NULL; ++ layer_t *l = NULL; ++ bool layer_valid = false; ++ ++ nret = snprintf(tmpdir, PATH_MAX, "%s/%s", g_root_dir, id); ++ if (nret < 0 || nret >= PATH_MAX) { ++ ERROR("Sprintf: %s failed", id); ++ goto free_out; ++ } ++ ++ mount_point_path = mountpoint_json_path(id); ++ if (mount_point_path == NULL) { ++ ERROR("Out of Memory"); ++ goto free_out; ++ } ++ ++ rpath = layer_json_path(id); ++ if (rpath == NULL) { ++ ERROR("%s is invalid layer", id); ++ goto free_out; ++ } ++ ++ l = load_layer(rpath, mount_point_path); ++ if (l == NULL) { ++ ERROR("load layer: %s failed, remove it", id); ++ goto free_out; ++ } ++ ++ if (do_validate_image_layer(tmpdir, l) != 0) { ++ ERROR("%s is invalid image layer", id); ++ goto free_out; ++ } ++ ++ if (do_validate_rootfs_layer(l) != 0) { ++ ERROR("%s is invalid rootfs layer", id); ++ goto free_out; ++ } ++ ++ layer_valid = true; ++ ++free_out: ++ free(rpath); ++ free(mount_point_path); ++ if (!layer_valid) { ++ free_layer_t(l); ++ l = NULL; ++ } ++ // always return true; ++ // if load layer failed, just remove it ++ return l; ++} ++ ++int remote_load_one_layer(const char *id) ++{ ++ int ret = 0; ++ layer_t *tl = NULL; ++ int i = 0; ++ ++ if (!layer_store_lock(true)) { ++ return -1; ++ } ++ ++ if (map_search(g_metadata.by_id, (void *)id) != NULL) { ++ DEBUG("remote layer already exist, not added: %s", id); ++ goto unlock_out; ++ } ++ ++ tl = load_one_layer_from_json(id); ++ if (tl == NULL) { ++ ret = -1; ++ goto unlock_out; ++ } ++ ++ if (!map_insert(g_metadata.by_id, (void *)tl->slayer->id, (void *)tl)) { ++ ERROR("Insert id: %s for layer failed", tl->slayer->id); ++ ret = -1; ++ goto unlock_out; ++ } ++ ++ for (; i < tl->slayer->names_len; i++) { ++ // this should be done by master isulad ++ if (!map_insert(g_metadata.by_name, (void *)tl->slayer->names[i], (void *)tl)) { ++ ret = -1; ++ ERROR("Insert name: %s for layer failed", tl->slayer->names[i]); ++ goto unlock_out; ++ } ++ } ++ ret = insert_digest_into_map(g_metadata.by_compress_digest, tl->slayer->compressed_diff_digest, tl->slayer->id); ++ if (ret != 0) { ++ ERROR("update layer: %s compress failed", tl->slayer->id); ++ goto unlock_out; ++ } ++ ++ ret = insert_digest_into_map(g_metadata.by_uncompress_digest, tl->slayer->diff_digest, tl->slayer->id); ++ if (ret != 0) { ++ ERROR("update layer: %s uncompress failed", tl->slayer->id); ++ goto unlock_out; ++ } ++ ++ ret = 0; ++unlock_out: ++ layer_store_unlock(); ++ return ret; ++} + #endif +diff --git a/src/daemon/modules/image/oci/storage/layer_store/layer_store.h b/src/daemon/modules/image/oci/storage/layer_store/layer_store.h +index 44bd297e..4677e5ee 100644 +--- a/src/daemon/modules/image/oci/storage/layer_store/layer_store.h ++++ b/src/daemon/modules/image/oci/storage/layer_store/layer_store.h +@@ -24,9 +24,6 @@ + #include "storage.h" + #include "io_wrapper.h" + #include "map.h" +-#ifdef ENABLE_REMOTE_LAYER_STORE +-#include "remote_support.h" +-#endif + + struct io_read_wrapper; + struct layer_list; +@@ -84,10 +81,8 @@ int layer_store_check(const char *id); + container_inspect_graph_driver *layer_store_get_metadata_by_layer_id(const char *id); + + #ifdef ENABLE_REMOTE_LAYER_STORE +-remote_support *layer_store_impl_remote_support(); +-bool layer_remote_layer_valid(const char *layer_id); +-int load_one_layer(const char *id); +-int remove_memory_stores_with_lock(const char *id); ++int remote_load_one_layer(const char *id); ++int remote_layer_remove_memory_stores_with_lock(const char *id); + #endif + + #ifdef __cplusplus +diff --git a/src/daemon/modules/image/oci/storage/image_store/image_remote_impl.c b/src/daemon/modules/image/oci/storage/remote_layer_support/image_remote_impl.c +similarity index 71% +rename from src/daemon/modules/image/oci/storage/image_store/image_remote_impl.c +rename to src/daemon/modules/image/oci/storage/remote_layer_support/image_remote_impl.c +index 20da8116..a822ea81 100644 +--- a/src/daemon/modules/image/oci/storage/image_store/image_remote_impl.c ++++ b/src/daemon/modules/image/oci/storage/remote_layer_support/image_remote_impl.c +@@ -13,27 +13,23 @@ + * Description: provide remote image store functions + ******************************************************************************/ + #define _GNU_SOURCE +-#include "image_store.h" ++#include "remote_support.h" + + #include <isula_libutils/log.h> + #include <stdio.h> + +-#include "remote_support.h" + #include "ro_symlink_maintain.h" + #include "map.h" + #include "utils_file.h" + #include "utils.h" + #include "layer_store.h" ++#include "image_store.h" + #include "utils_array.h" + +-struct remote_image_data { +- const char *image_home; +-}; +- + static map_t *image_byid_old = NULL; + static map_t *image_byid_new = NULL; + +-static void *remote_support_create(const char *remote_home, const char *remote_ro) ++struct remote_image_data *remote_image_create(const char *remote_home, const char *remote_ro) + { + struct remote_image_data *data = util_common_calloc_s(sizeof(struct remote_image_data)); + if (data == NULL) { +@@ -46,7 +42,7 @@ static void *remote_support_create(const char *remote_home, const char *remote_r + return data; + } + +-static void remote_support_destroy(void *data) ++void remote_image_destroy(struct remote_image_data *data) + { + if (data == NULL) { + return; +@@ -59,7 +55,7 @@ static void remote_support_destroy(void *data) + return; + } + +-static int remote_support_scan(void *data) ++static int remote_dir_scan(void *data) + { + int ret = 0; + int nret; +@@ -79,7 +75,7 @@ static int remote_support_scan(void *data) + image_dirs_num = util_array_len((const char **)image_dirs); + + for (i = 0; i < image_dirs_num; i++) { +- bool valid_v1_image = false; ++ bool is_v1_image = false; + + if (util_reg_match(id_patten, image_dirs[i]) != 0) { + DEBUG("Image's json is placed inside image's data directory, so skip any other file or directory: %s", +@@ -93,12 +89,14 @@ static int remote_support_scan(void *data) + continue; + } + +- if (validate_manifest_schema_version_1(image_path, &valid_v1_image) != 0) { ++ if (image_store_validate_manifest_schema_version_1(image_path, &is_v1_image) != 0) { + ERROR("Failed to validate manifest schema version 1 format"); + continue; + } + +- if (!valid_v1_image) { ++ // for refresh, we don't care v1 image, cause image should be handled by master isulad ++ // when master isulad pull images ++ if (!is_v1_image) { + map_insert(image_byid_new, util_strdup_s(image_dirs[i]), (void *)&exist); + } + } +@@ -108,12 +106,13 @@ out: + return ret; + } + +-static int remote_support_add(void *data) ++static int remote_image_add(void *data) + { + char **array_added = NULL; + char **array_deleted = NULL; + char *top_layer = NULL; + map_t *tmp_map = NULL; ++ bool exist = true; + int i = 0; + int ret = 0; + +@@ -121,26 +120,28 @@ static int remote_support_add(void *data) + return -1; + } + +- array_added = added_layers(image_byid_old, image_byid_new); +- array_deleted = deleted_layers(image_byid_old, image_byid_new); ++ array_added = remote_added_layers(image_byid_old, image_byid_new); ++ array_deleted = remote_deleted_layers(image_byid_old, image_byid_new); + + for (i = 0; i < util_array_len((const char **)array_added); i++) { +- top_layer = get_top_layer_from_json(array_added[i]); +- if (top_layer != NULL && !layer_remote_layer_valid(top_layer)) { +- ERROR("ERROR not find valid under layer, remoet image:%s not added", array_added[i]); ++ top_layer = remote_image_get_top_layer_from_json(array_added[i]); ++ if (top_layer != NULL && !remote_layer_layer_valid(top_layer)) { ++ WARN("Current not find valid under layer, remoet image:%s not added", array_added[i]); + map_remove(image_byid_new, (void *)array_added[i]); + continue; + } + +- if (append_image_by_directory_with_lock(array_added[i]) != 0) { ++ if (remote_append_image_by_directory_with_lock(array_added[i]) != 0) { + ERROR("Failed to load image into memrory: %s", array_added[i]); ++ map_remove(image_byid_new, (void *)array_added[i]); + ret = -1; + } + } + + for (i = 0; i < util_array_len((const char **)array_deleted); i++) { +- if (remove_image_from_memory_with_lock(array_deleted[i]) != 0) { ++ if (remote_remove_image_from_memory_with_lock(array_deleted[i]) != 0) { + ERROR("Failed to remove remote memory store"); ++ map_insert(image_byid_new, array_deleted[i], (void *)&exist); + ret = -1; + } + } +@@ -148,7 +149,7 @@ static int remote_support_add(void *data) + tmp_map = image_byid_old; + image_byid_old = image_byid_new; + image_byid_new = tmp_map; +- empty_map(image_byid_new); ++ map_clear(image_byid_new); + + util_free_array(array_added); + util_free_array(array_deleted); +@@ -157,17 +158,13 @@ static int remote_support_add(void *data) + return ret; + } + +-remote_support *image_store_impl_remote_support(void) +-{ +- remote_support *rs = util_common_calloc_s(sizeof(remote_support)); +- if (rs == NULL) { +- return NULL; ++void remote_image_refresh(struct remote_image_data *data) { ++ if (remote_dir_scan(data) != 0) { ++ ERROR("remote overlay failed to scan dir, skip refresh"); ++ return; + } + +- rs->create = remote_support_create; +- rs->destroy = remote_support_destroy; +- rs->scan_remote_dir = remote_support_scan; +- rs->load_item = remote_support_add; +- +- return rs; ++ if (remote_image_add(data) != 0) { ++ ERROR("refresh overlay failed"); ++ } + } +diff --git a/src/daemon/modules/image/oci/storage/layer_store/layer_remote_impl.c b/src/daemon/modules/image/oci/storage/remote_layer_support/layer_remote_impl.c +similarity index 76% +rename from src/daemon/modules/image/oci/storage/layer_store/layer_remote_impl.c +rename to src/daemon/modules/image/oci/storage/remote_layer_support/layer_remote_impl.c +index d676458c..3e3afff6 100644 +--- a/src/daemon/modules/image/oci/storage/layer_store/layer_remote_impl.c ++++ b/src/daemon/modules/image/oci/storage/remote_layer_support/layer_remote_impl.c +@@ -13,7 +13,7 @@ + * Description: remote layer store implementation + ******************************************************************************/ + #define _GNU_SOURCE +-#include "layer_store.h" ++#include "remote_support.h" + + #include <pthread.h> + #include <isula_libutils/log.h> +@@ -21,20 +21,15 @@ + + #include "map.h" + #include "utils.h" +-#include "remote_support.h" + #include "ro_symlink_maintain.h" ++#include "layer_store.h" + #include "path.h" + #include "driver_overlay2.h" + +-struct remote_layer_data { +- const char *layer_home; +- const char *layer_ro; +-}; +- + static map_t *layer_byid_old = NULL; + static map_t *layer_byid_new = NULL; + +-static void *remote_support_create(const char *layer_home, const char *layer_ro) ++struct remote_layer_data *remote_layer_create(const char *layer_home, const char *layer_ro) + { + struct remote_layer_data *data = util_common_calloc_s(sizeof(struct remote_layer_data)); + if (data == NULL) { +@@ -49,7 +44,7 @@ static void *remote_support_create(const char *layer_home, const char *layer_ro) + return data; + }; + +-static void remote_support_destroy(void *data) ++void remote_layer_destroy(struct remote_layer_data *data) + { + if (data == NULL) { + return; +@@ -72,10 +67,9 @@ static bool layer_walk_dir_cb(const char *path_name, const struct dirent *sub_di + return true; + } + +-static int remote_support_scan(void *data) ++static int remote_dir_scan(struct remote_layer_data *data) + { +- struct remote_layer_data *remote_data = data; +- return util_scan_subdirs(remote_data->layer_ro, layer_walk_dir_cb, data); ++ return util_scan_subdirs(data->layer_ro, layer_walk_dir_cb, data); + } + + static int remove_one_remote_layer(struct remote_layer_data *data, char *layer_id) +@@ -85,6 +79,11 @@ static int remove_one_remote_layer(struct remote_layer_data *data, char *layer_i + int nret = 0; + int ret = 0; + ++ if (layer_id == NULL) { ++ ERROR("can't delete NULL remote layer"); ++ return -1; ++ } ++ + nret = asprintf(&ro_symlink, "%s/%s", data->layer_home, layer_id); + if (nret < 0 || nret > PATH_MAX) { + SYSERROR("Create layer symbol link path failed"); +@@ -98,11 +97,14 @@ static int remove_one_remote_layer(struct remote_layer_data *data, char *layer_i + goto out; + } + ++ // return 0 if path already removed + if (util_path_remove(clean_path) != 0) { + SYSERROR("Failed to remove link path %s", clean_path); ++ ret = -1; ++ goto out; + } + +- if (remove_memory_stores_with_lock(layer_id) != 0) { ++ if (remote_layer_remove_memory_stores_with_lock(layer_id) != 0) { + ERROR("Failed to remove remote layer store memory"); + ret = -1; + } +@@ -110,7 +112,6 @@ static int remove_one_remote_layer(struct remote_layer_data *data, char *layer_i + out: + free(ro_symlink); + return ret; +- + } + + static int add_one_remote_layer(struct remote_layer_data *data, char *layer_id) +@@ -119,6 +120,11 @@ static int add_one_remote_layer(struct remote_layer_data *data, char *layer_id) + char *layer_dir = NULL; + int ret = 0; + ++ if (layer_id == NULL) { ++ ERROR("can't add NULL remote layer"); ++ return -1; ++ } ++ + ro_symlink = util_path_join(data->layer_home, layer_id); + layer_dir = util_path_join(data->layer_ro, layer_id); + +@@ -140,7 +146,7 @@ static int add_one_remote_layer(struct remote_layer_data *data, char *layer_id) + goto free_out; + } + // insert layer into memory +- if (load_one_layer(layer_id) != 0) { ++ if (remote_load_one_layer(layer_id) != 0) { + ERROR("Failed to load new layer: %s into memory", layer_id); + ret = -1; + } +@@ -152,30 +158,32 @@ free_out: + return ret; + } + +-static int remote_support_add(void *data) ++static int remote_layer_add(struct remote_layer_data *data) + { + int ret = 0; + char **array_added = NULL; + char **array_deleted = NULL; + map_t *tmp_map = NULL; ++ bool exist = true; + int i = 0; + + if (data == NULL) { + return -1; + } + +- array_added = added_layers(layer_byid_old, layer_byid_new); +- array_deleted = deleted_layers(layer_byid_old, layer_byid_new); ++ array_added = remote_added_layers(layer_byid_old, layer_byid_new); ++ array_deleted = remote_deleted_layers(layer_byid_old, layer_byid_new); + + for (i = 0; i < util_array_len((const char **)array_added); i++) { +- if (!overlay_remote_layer_valid(array_added[i]) != 0) { ++ if (!remote_overlay_layer_valid(array_added[i]) != 0) { ++ WARN("remote overlay layer current not valid: %s", array_added[i]); + map_remove(layer_byid_new, (void *)array_added[i]); +- ERROR("remote overlay layer current not valid: %s", array_added[i]); + continue; + } + + if (add_one_remote_layer(data, array_added[i]) != 0) { + ERROR("Failed to add remote layer: %s", array_added[i]); ++ map_remove(layer_byid_new, (void *)array_added[i]); + ret = -1; + } + } +@@ -183,6 +191,7 @@ static int remote_support_add(void *data) + for (i = 0; i < util_array_len((const char **)array_deleted); i++) { + if (remove_one_remote_layer(data, array_deleted[i]) != 0) { + ERROR("Failed to delete remote overlay layer: %s", array_deleted[i]); ++ map_insert(layer_byid_new, array_deleted[i], (void *)&exist); + ret = -1; + } + } +@@ -190,7 +199,7 @@ static int remote_support_add(void *data) + tmp_map = layer_byid_old; + layer_byid_old = layer_byid_new; + layer_byid_new = tmp_map; +- empty_map(layer_byid_new); ++ map_clear(layer_byid_new); + + util_free_array(array_added); + util_free_array(array_deleted); +@@ -198,22 +207,20 @@ static int remote_support_add(void *data) + return ret; + } + +-remote_support *layer_store_impl_remote_support() ++void remote_layer_refresh(struct remote_layer_data *data) + { +- remote_support *rs = util_common_calloc_s(sizeof(remote_support)); +- if (rs == NULL) { +- return NULL; ++ if (remote_dir_scan(data) != 0) { ++ ERROR("remote layer failed to scan dir, skip refresh"); ++ return; + } + +- rs->create = remote_support_create; +- rs->destroy = remote_support_destroy; +- rs->scan_remote_dir = remote_support_scan; +- rs->load_item = remote_support_add; +- +- return rs; ++ if (remote_layer_add(data) != 0) { ++ ERROR("refresh overlay failed"); ++ } + } + +-bool layer_remote_layer_valid(const char *layer_id) ++ ++bool remote_layer_layer_valid(const char *layer_id) + { + return map_search(layer_byid_old, (void *)layer_id) != NULL; + } +diff --git a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/overlay_remote_impl.c b/src/daemon/modules/image/oci/storage/remote_layer_support/overlay_remote_impl.c +similarity index 72% +rename from src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/overlay_remote_impl.c +rename to src/daemon/modules/image/oci/storage/remote_layer_support/overlay_remote_impl.c +index a674a00f..de2e583c 100644 +--- a/src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/overlay_remote_impl.c ++++ b/src/daemon/modules/image/oci/storage/remote_layer_support/overlay_remote_impl.c +@@ -13,13 +13,13 @@ + * Description: provide remote implementation for driver overlay + ******************************************************************************/ + #define _GNU_SOURCE +-#include "driver_overlay2.h" ++#include "remote_support.h" + + #include <stdio.h> + + #include "map.h" +-#include "remote_support.h" + #include "ro_symlink_maintain.h" ++#include "driver_overlay2.h" + #include "isula_libutils/log.h" + #include "utils.h" + #include "utils_array.h" +@@ -29,15 +29,13 @@ + #define OVERLAY_LINK_DIR "l" + #define OVERLAY_LAYER_LINK "link" + +-struct remote_overlay_data { +- const char *overlay_home; +- const char *overlay_ro; +-}; +- ++// key: id, value: short id in 'l' dir ++// store short id to delete symbol link in 'l' dir + static map_t *overlay_byid_old = NULL; + static map_t *overlay_byid_new = NULL; ++static map_t *overlay_id_link = NULL; + +-static void *remote_support_create(const char *remote_home, const char *remote_ro) ++struct remote_overlay_data *remote_overlay_create(const char *remote_home, const char *remote_ro) + { + struct remote_overlay_data *data = util_common_calloc_s(sizeof(struct remote_overlay_data)); + if (data == NULL) { +@@ -48,11 +46,12 @@ static void *remote_support_create(const char *remote_home, const char *remote_r + data->overlay_ro = remote_ro; + overlay_byid_old = map_new(MAP_STR_BOOL, MAP_DEFAULT_CMP_FUNC, MAP_DEFAULT_FREE_FUNC); + overlay_byid_new = map_new(MAP_STR_BOOL, MAP_DEFAULT_CMP_FUNC, MAP_DEFAULT_FREE_FUNC); ++ overlay_id_link = map_new(MAP_STR_STR, MAP_DEFAULT_CMP_FUNC, MAP_DEFAULT_FREE_FUNC); + + return data; + } + +-static void remote_support_destroy(void *data) ++void remote_overlay_destroy(struct remote_overlay_data *data) + { + if (data == NULL) { + return; +@@ -60,6 +59,7 @@ static void remote_support_destroy(void *data) + + map_free(overlay_byid_old); + map_free(overlay_byid_new); ++ map_free(overlay_id_link); + free(data); + } + +@@ -74,10 +74,9 @@ static bool overlay_walk_dir_cb(const char *path_name, const struct dirent *sub_ + return true; + } + +-static int remote_support_scan(void *data) ++static int remote_dir_scan(struct remote_overlay_data *data) + { +- struct remote_overlay_data *remote_data = data; +- return util_scan_subdirs(remote_data->overlay_ro, overlay_walk_dir_cb, data); ++ return util_scan_subdirs(data->overlay_ro, overlay_walk_dir_cb, data); + } + + static int do_diff_symlink(const char *id, char *link_id, const char *driver_home) +@@ -128,10 +127,17 @@ out: + static int remove_one_remote_overlay_layer(struct remote_overlay_data *data, const char *overlay_id) + { + char *ro_symlink = NULL; ++ char *link_path = NULL; ++ char *link_id = NULL; + char clean_path[PATH_MAX] = { 0 }; + int nret = 0; + int ret = 0; + ++ if (overlay_id == NULL) { ++ ERROR("can't remove NULL remote layer"); ++ return -1; ++ } ++ + nret = asprintf(&ro_symlink, "%s/%s", data->overlay_home, overlay_id); + if (nret < 0 || nret > PATH_MAX) { + SYSERROR("Create layer symbol link path failed"); +@@ -149,8 +155,40 @@ static int remove_one_remote_overlay_layer(struct remote_overlay_data *data, con + SYSERROR("Failed to remove link path %s", clean_path); + } + ++ link_id = (char *)map_search(overlay_id_link, (void *)overlay_id); ++ ++ if (link_id == NULL) { ++ ERROR("Failed to find link id for overlay layer: %s", overlay_id); ++ ret = -1; ++ goto out; ++ } ++ ++ nret = asprintf(&link_path, "%s/%s/%s", data->overlay_home, OVERLAY_LINK_DIR, link_id); ++ if (nret < 0 || nret > PATH_MAX) { ++ SYSERROR("Create link path failed"); ++ ret = -1; ++ goto out; ++ } ++ ++ if (util_clean_path(link_path, clean_path, sizeof(clean_path)) == NULL) { ++ ERROR("Failed to clean path: %s", ro_symlink); ++ ret = -1; ++ goto out; ++ } ++ ++ if (util_path_remove(clean_path) != 0) { ++ SYSERROR("Failed to remove link path %s", clean_path); ++ } ++ ++ if (!map_remove(overlay_id_link, (void *)overlay_id)) { ++ ERROR("Failed to remove link id for overlay layers: %s", overlay_id); ++ ret = -1; ++ goto out; ++ } ++ + out: + free(ro_symlink); ++ free(link_path); + return ret; + } + +@@ -162,6 +200,11 @@ static int add_one_remote_overlay_layer(struct remote_overlay_data *data, const + char *diff_symlink = NULL; + int ret = 0; + ++ if (overlay_id == NULL) { ++ ERROR("can't add NULL remote layer"); ++ return -1; ++ } ++ + ro_symlink = util_path_join(data->overlay_home, overlay_id); + if (ro_symlink == NULL) { + ERROR("Failed to join ro symlink path: %s", overlay_id); +@@ -211,6 +254,11 @@ static int add_one_remote_overlay_layer(struct remote_overlay_data *data, const + ret = -1; + } + ++ if (!map_insert(overlay_id_link, util_strdup_s(overlay_id), (void *)diff_symlink)) { ++ ERROR("can't insert remote layer into map"); ++ ret = -1; ++ } ++ + free_out: + free(ro_symlink); + free(layer_dir); +@@ -220,24 +268,26 @@ free_out: + return ret; + } + +-static int remote_support_add(void *data) ++static int remote_image_add(struct remote_overlay_data *data) + { + int ret = 0; + char **array_added = NULL; + char **array_deleted = NULL; + map_t *tmp_map = NULL; ++ bool exist = true; + int i = 0; + + if (data == NULL) { + return -1; + } + +- array_added = added_layers(overlay_byid_old, overlay_byid_new); +- array_deleted = deleted_layers(overlay_byid_old, overlay_byid_new); ++ array_added = remote_added_layers(overlay_byid_old, overlay_byid_new); ++ array_deleted = remote_deleted_layers(overlay_byid_old, overlay_byid_new); + + for (i = 0; i < util_array_len((const char **)array_added); i++) { + if (add_one_remote_overlay_layer(data, array_added[i]) != 0) { + ERROR("Failed to add remote overlay layer: %s", array_added[i]); ++ map_remove(overlay_byid_new, (void *)array_added[i]); + ret = -1; + } + } +@@ -245,6 +295,7 @@ static int remote_support_add(void *data) + for (i = 0; i < util_array_len((const char **)array_deleted); i++) { + if (remove_one_remote_overlay_layer(data, array_deleted[i]) != 0) { + ERROR("Failed to delete remote overlay layer: %s", array_deleted[i]); ++ map_insert(overlay_byid_new, array_deleted[i], (void *)&exist); + ret = -1; + } + } +@@ -252,7 +303,7 @@ static int remote_support_add(void *data) + tmp_map = overlay_byid_old; + overlay_byid_old = overlay_byid_new; + overlay_byid_new = tmp_map; +- empty_map(overlay_byid_new); ++ map_clear(overlay_byid_new); + + util_free_array(array_added); + util_free_array(array_deleted); +@@ -260,23 +311,19 @@ static int remote_support_add(void *data) + return ret; + } + +-remote_support *overlay_driver_impl_remote_support(void) ++void remote_overlay_refresh(struct remote_overlay_data *data) + { +- remote_support *rs = util_common_calloc_s(sizeof(remote_support)); +- if (rs == NULL) { +- ERROR("Failed to calloc overlay supporter"); +- return NULL; ++ if (remote_dir_scan(data) != 0) { ++ ERROR("remote overlay failed to scan dir, skip refresh"); ++ return; + } + +- rs->create = remote_support_create; +- rs->destroy = remote_support_destroy; +- rs->scan_remote_dir = remote_support_scan; +- rs->load_item = remote_support_add; +- +- return rs; ++ if (remote_image_add(data) != 0) { ++ ERROR("refresh overlay failed"); ++ } + } + +-bool overlay_remote_layer_valid(const char *layer_id) ++bool remote_overlay_layer_valid(const char *layer_id) + { + return map_search(overlay_byid_old, (void *)layer_id) != NULL; + } +diff --git a/src/daemon/modules/image/oci/storage/remote_layer_support/remote_support.c b/src/daemon/modules/image/oci/storage/remote_layer_support/remote_support.c +index 9dc096f7..3c7d0f54 100644 +--- a/src/daemon/modules/image/oci/storage/remote_layer_support/remote_support.c ++++ b/src/daemon/modules/image/oci/storage/remote_layer_support/remote_support.c +@@ -15,108 +15,107 @@ + + #include "remote_support.h" + +-#include "layer_store.h" +-#include "image_store.h" ++#include <pthread.h> ++ + #include "isula_libutils/log.h" +-#include "driver_overlay2.h" + #include "utils.h" + +-remote_supporter *create_layer_supporter(const char *remote_home, const char *remote_ro) +-{ +- remote_support *handlers = layer_store_impl_remote_support(); +- if (handlers == NULL || handlers->create == NULL) { +- return NULL; +- } ++struct supporters { ++ struct remote_image_data *image_data; ++ struct remote_layer_data *layer_data; ++ struct remote_overlay_data *overlay_data; ++}; + +- remote_supporter *supporter = (remote_supporter *)util_common_calloc_s(sizeof(remote_supporter)); +- if (supporter == NULL) { +- goto err_out; +- } ++static struct supporters supporters; ++ ++static void *remote_refresh_ro_symbol_link(void *arg) ++{ ++ struct supporters *refresh_supporters = (struct supporters *)arg; ++ prctl(PR_SET_NAME, "RoLayerRefresh"); + +- supporter->handlers = handlers; +- supporter->data = handlers->create(remote_home, remote_ro); ++ while (true) { ++ util_usleep_nointerupt(5 * 1000 * 1000); ++ DEBUG("remote refresh start\n"); + +- return supporter; ++ remote_overlay_refresh(refresh_supporters->overlay_data); ++ remote_layer_refresh(refresh_supporters->layer_data); ++ remote_image_refresh(refresh_supporters->image_data); + +-err_out: +- free(handlers); +- free(supporter); ++ DEBUG("remote refresh end\n"); ++ } + return NULL; + } + +-remote_supporter *create_image_supporter(const char *remote_home, const char *remote_ro) ++int remote_start_refresh_thread(void) + { +- remote_support *handlers = image_store_impl_remote_support(); +- if (handlers == NULL || handlers->create == NULL) { +- return NULL; +- } ++ int res = 0; ++ pthread_t a_thread; ++ maintain_context ctx = get_maintain_context(); + +- remote_supporter *supporter = (remote_supporter *)util_common_calloc_s(sizeof(remote_supporter)); +- if (supporter == NULL) { +- goto err_out; ++ supporters.image_data = remote_image_create(ctx.image_home, NULL); ++ if (supporters.image_data == NULL) { ++ goto free_out; + } + +- supporter->handlers = handlers; +- supporter->data = handlers->create(remote_home, remote_ro); +- +- return supporter; +- +-err_out: +- free(handlers); +- free(supporter); +- return NULL; +-} ++ supporters.layer_data = remote_layer_create(ctx.layer_home, ctx.layer_ro_dir); ++ if (supporters.layer_data == NULL) { ++ goto free_out; ++ } + +-remote_supporter *create_overlay_supporter(const char *remote_home, const char *remote_ro) +-{ +- remote_support *handlers = overlay_driver_impl_remote_support(); +- if (handlers == NULL || handlers->create == NULL) { +- return NULL; ++ supporters.overlay_data = remote_overlay_create(ctx.overlay_home, ctx.overlay_ro_dir); ++ if (supporters.overlay_data == NULL) { ++ goto free_out; + } + +- remote_supporter *supporter = (remote_supporter *)util_common_calloc_s(sizeof(remote_supporter)); +- if (supporter == NULL) { +- goto err_out; ++ res = pthread_create(&a_thread, NULL, remote_refresh_ro_symbol_link, (void *)&supporters); ++ if (res != 0) { ++ CRIT("Thread creation failed"); ++ return -1; + } + +- supporter->handlers = handlers; +- supporter->data = handlers->create(remote_home, remote_ro); ++ if (pthread_detach(a_thread) != 0) { ++ SYSERROR("Failed to detach 0x%lx", a_thread); ++ return -1; ++ } + +- return supporter; ++ return 0; + +-err_out: +- free(handlers); +- free(supporter); +- return NULL; ++free_out: ++ remote_image_destroy(supporters.image_data); ++ remote_layer_destroy(supporters.layer_data); ++ remote_overlay_destroy(supporters.overlay_data); + ++ return -1; + } + +-void destroy_suppoter(remote_supporter *supporter) ++// this function calculate map_a - map_b => diff_list ++// diff_list contains keys inside map_a but not inside map_b ++static char **map_diff(const map_t *map_a, const map_t *map_b) + { +- if (supporter->handlers->destroy == NULL) { +- ERROR("destroy_supporter operation not supported"); +- return; ++ char **array = NULL; ++ map_itor *itor = map_itor_new(map_a); ++ bool *found = NULL; ++ ++ // iter new_map, every item not in old, append them to new_layers ++ for (; map_itor_valid(itor); map_itor_next(itor)) { ++ char *id = map_itor_key(itor); ++ found = map_search(map_b, id); ++ if (found == NULL) { ++ util_array_append(&array, util_strdup_s(id)); ++ } + } + +- supporter->handlers->destroy(supporter->data); +- free(supporter->handlers); +- free(supporter); ++ map_itor_free(itor); ++ ++ return array; + } + +-int scan_remote_dir(remote_supporter *supporter) ++char **remote_deleted_layers(const map_t *old, const map_t *new) + { +- if (supporter->handlers->scan_remote_dir == NULL) { +- ERROR("scan_remote_dir operation not supported"); +- return -1; +- } +- return supporter->handlers->scan_remote_dir(supporter->data); ++ return map_diff(old, new); + } + +-int load_item(remote_supporter *supporter) ++char **remote_added_layers(const map_t *old, const map_t *new) + { +- if (supporter->handlers->scan_remote_dir == NULL) { +- ERROR("load_item operation not supported"); +- return -1; +- } +- return supporter->handlers->load_item(supporter->data); ++ return map_diff(new, old); + } +diff --git a/src/daemon/modules/image/oci/storage/remote_layer_support/remote_support.h b/src/daemon/modules/image/oci/storage/remote_layer_support/remote_support.h +index d1f7af35..892a9155 100644 +--- a/src/daemon/modules/image/oci/storage/remote_layer_support/remote_support.h ++++ b/src/daemon/modules/image/oci/storage/remote_layer_support/remote_support.h +@@ -17,39 +17,59 @@ + #define DAEMON_MODULES_IMAGE_OCI_STORAGE_LAYER_STORE_REMOTE_LAYER_SUPPORT_REMOTE_SUPPORT_H + + #include "linked_list.h" +-#define REMOTE_RO_LAYER_DIR "RO" +-#define OVERLAY_RO_DIR "RO" ++#include "map.h" ++#include "ro_symlink_maintain.h" + + #ifdef __cplusplus + extern "C" { + #endif + +-typedef struct { +- void *(*create)(const char *remote_home, const char *remote_ro); +- void (*destroy)(void *data); +- // populate the list contains all dirs +- int (*scan_remote_dir)(void *data); +- // consume the list contains all dirs +- int (*load_item)(void *data); +-} remote_support; ++struct remote_overlay_data { ++ const char *overlay_home; ++ const char *overlay_ro; ++}; + +-typedef struct { +- void *data; +- remote_support *handlers; +-} remote_supporter; ++struct remote_layer_data { ++ const char *layer_home; ++ const char *layer_ro; ++}; + +-// RemoteSupport *impl_remote_support(); +-remote_supporter *create_image_supporter(const char *remote_home, const char *remote_ro); ++struct remote_image_data { ++ const char *image_home; ++}; + +-remote_supporter *create_layer_supporter(const char *remote_home, const char *remote_ro); ++// image impl ++struct remote_image_data *remote_image_create(const char *image_home, const char *image_ro); + +-remote_supporter *create_overlay_supporter(const char *remote_home, const char *remote_ro); ++void remote_image_destroy(struct remote_image_data *data); + +-void destroy_suppoter(remote_supporter *supporter); ++void remote_image_refresh(struct remote_image_data *data); + +-int scan_remote_dir(remote_supporter *supporter); ++// layer impl ++struct remote_layer_data *remote_layer_create(const char *layer_home, const char *layer_ro); + +-int load_item(remote_supporter *supporter); ++void remote_layer_destroy(struct remote_layer_data *data); ++ ++void remote_layer_refresh(struct remote_layer_data *data); ++ ++bool remote_layer_layer_valid(const char *layer_id); ++ ++// overlay impl ++struct remote_overlay_data *remote_overlay_create(const char *overlay_home, const char *overlay_ro); ++ ++void remote_overlay_destroy(struct remote_overlay_data *data); ++ ++void remote_overlay_refresh(struct remote_overlay_data *data); ++ ++bool remote_overlay_layer_valid(const char *layer_id); ++ ++// start refresh remote ++int remote_start_refresh_thread(void); ++ ++// extra map utils ++char **remote_deleted_layers(const map_t *old, const map_t *new_l); ++ ++char **remote_added_layers(const map_t *old, const map_t *new_l); + + #ifdef __cplusplus + } +diff --git a/src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.c b/src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.c +index 7df7a221..a3aa3aa4 100644 +--- a/src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.c ++++ b/src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.c +@@ -17,19 +17,15 @@ + + #include <sys/prctl.h> + #include <stdio.h> ++#include <stdlib.h> + #include <pthread.h> + #include <unistd.h> +-#include "map.h" ++ + #include "path.h" + #include "linked_list.h" +-#include "layer_store.h" +-#include "layer.h" + #include "isula_libutils/log.h" +-#include "image_store.h" +-#include "remote_support.h" + #include "utils.h" + #include "utils_file.h" +-#include "stdlib.h" + + #define REMOTE_RO_LAYER_DIR "RO" + +@@ -43,14 +39,6 @@ static char *layer_home; + static char *overlay_ro_dir; + static char *overlay_home; + +-struct supporters { +- remote_supporter *image_supporter; +- remote_supporter *layer_supporter; +- remote_supporter *overlay_supporter; +-}; +- +-static struct supporters supporters; +- + int remote_image_init(const char *root_dir) + { + if (root_dir == NULL) { +@@ -134,75 +122,11 @@ void remote_maintain_cleanup(void) + overlay_ro_dir = NULL; + } + +-// to maintain the symbol links, add new symbol link and delete invalid symbol link +-// arg is const char *driver_home +-// scanning driver->home/RO/ directory, build symlink in driver->home +-static void *remote_refresh_ro_symbol_link(void *arg) +-{ +- struct supporters *supporters = (struct supporters *)arg; +- prctl(PR_SET_NAME, "RoLayerRefresh"); +- +- while (true) { +- util_usleep_nointerupt(5 * 1000 * 1000); +- DEBUG("remote refresh start\n"); +- scan_remote_dir(supporters->overlay_supporter); +- load_item(supporters->overlay_supporter); +- scan_remote_dir(supporters->layer_supporter); +- load_item(supporters->layer_supporter); +- scan_remote_dir(supporters->image_supporter); +- load_item(supporters->image_supporter); +- DEBUG("remote refresh end\n"); +- } +- return NULL; +-} +- +-int start_refresh_thread(void) +-{ +- int res = 0; +- pthread_t a_thread; +- +- supporters.image_supporter = create_image_supporter(image_home, NULL); +- if (supporters.image_supporter == NULL) { +- goto free_out; +- } +- +- supporters.layer_supporter = create_layer_supporter(layer_home, layer_ro_dir); +- if (supporters.layer_supporter == NULL) { +- goto free_out; +- } +- +- supporters.overlay_supporter = create_overlay_supporter(overlay_home, overlay_ro_dir); +- if (supporters.overlay_supporter == NULL) { +- goto free_out; +- } +- +- res = pthread_create(&a_thread, NULL, remote_refresh_ro_symbol_link, (void *)&supporters); +- if (res != 0) { +- CRIT("Thread creation failed"); +- return -1; +- } +- +- if (pthread_detach(a_thread) != 0) { +- SYSERROR("Failed to detach 0x%lx", a_thread); +- return -1; +- } +- +- return 0; +- +-free_out: +- destroy_suppoter(supporters.image_supporter); +- destroy_suppoter(supporters.layer_supporter); +- destroy_suppoter(supporters.overlay_supporter); +- +- return -1; +-} +- + static int do_build_ro_dir(const char *home, const char *id) + { + char *ro_symlink = NULL; + char *ro_layer_dir = NULL; + int nret = 0; +- // bool ret = true; + int ret = 0; + + nret = asprintf(&ro_symlink, "%s/%s", home, id); +@@ -305,43 +229,15 @@ int remote_overlay_remove_ro_dir(const char *id) + return do_remove_ro_dir(overlay_home, id); + } + +-static char **map_diff(map_t *map_a, map_t *map_b) +-{ +- char **array = NULL; +- map_itor *itor = map_itor_new(map_a); +- bool *found = NULL; +- +- // iter new_map, every item not in old, append them to new_layers +- for (; map_itor_valid(itor); map_itor_next(itor)) { +- char *id = map_itor_key(itor); +- found = map_search(map_b, id); +- if (found == NULL) { +- util_array_append(&array, util_strdup_s(id)); +- } +- } +- +- map_itor_free(itor); +- +- return array; +-} +- +-char **deleted_layers(map_t *old, map_t *new) +-{ +- return map_diff(old, new); +-} +- +-char **added_layers(map_t *old, map_t *new) ++maintain_context get_maintain_context(void) + { +- return map_diff(new, old); +-} ++ maintain_context ctx = {0x0}; + +-int empty_map(map_t *mp) +-{ +- if (mp == NULL) { +- return -1; +- } ++ ctx.image_home = image_home; ++ ctx.layer_ro_dir = layer_ro_dir; ++ ctx.layer_home = layer_home; ++ ctx.overlay_ro_dir = overlay_ro_dir; ++ ctx.overlay_home = overlay_home; + +- map_clear(mp); +- mp->store->root = mp->store->nil; +- return 0; ++ return ctx; + } +diff --git a/src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.h b/src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.h +index 25712d40..aa2036ea 100644 +--- a/src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.h ++++ b/src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.h +@@ -15,12 +15,21 @@ + #ifndef DAEMON_MODULES_IMAGE_OCI_STORAGE_LAYER_STORE_REMOTE_LAYER_SUPPORT_RO_SYMLINK_MAINTAIN_H + #define DAEMON_MODULES_IMAGE_OCI_STORAGE_LAYER_STORE_REMOTE_LAYER_SUPPORT_RO_SYMLINK_MAINTAIN_H + +-#include "map.h" ++#define REMOTE_RO_LAYER_DIR "RO" ++#define OVERLAY_RO_DIR "RO" + + #ifdef __cplusplus + extern "C" { + #endif + ++typedef struct { ++ const char *image_home; ++ const char *layer_ro_dir; ++ const char *layer_home; ++ const char *overlay_ro_dir; ++ const char *overlay_home; ++} maintain_context; ++ + int remote_image_init(const char *root_dir); + + int remote_layer_init(const char *root_dir); +@@ -29,8 +38,6 @@ int remote_overlay_init(const char *driver_home); + + void remote_maintain_cleanup(void); + +-int start_refresh_thread(void); +- + int remote_layer_build_ro_dir(const char *id); + + int remote_overlay_build_ro_dir(const char *id); +@@ -39,11 +46,7 @@ int remote_layer_remove_ro_dir(const char *id); + + int remote_overlay_remove_ro_dir(const char *id); + +-char **deleted_layers(map_t *old, map_t *new); +- +-char **added_layers(map_t *old, map_t *new); +- +-int empty_map(map_t *mp); ++maintain_context get_maintain_context(void); + + #ifdef __cplusplus + } +diff --git a/src/daemon/modules/image/oci/storage/storage.c b/src/daemon/modules/image/oci/storage/storage.c +index 31812a22..f9830ac3 100644 +--- a/src/daemon/modules/image/oci/storage/storage.c ++++ b/src/daemon/modules/image/oci/storage/storage.c +@@ -43,7 +43,7 @@ + #include "utils_verify.h" + #include "sha256.h" + #ifdef ENABLE_REMOTE_LAYER_STORE +-#include "ro_symlink_maintain.h" ++#include "remote_support.h" + #endif + + static pthread_rwlock_t g_storage_rwlock; +@@ -1874,7 +1874,7 @@ int storage_module_init(struct storage_module_init_options *opts) + } + + #ifdef ENABLE_REMOTE_LAYER_STORE +- if (opts->enable_remote_layer && start_refresh_thread() != 0) { ++ if (opts->enable_remote_layer && remote_start_refresh_thread() != 0) { + ERROR("Failed to start remote refresh thread"); + } + #endif +diff --git a/src/utils/cutils/map/rb_tree.c b/src/utils/cutils/map/rb_tree.c +index e933003a..b85371e3 100644 +--- a/src/utils/cutils/map/rb_tree.c ++++ b/src/utils/cutils/map/rb_tree.c +@@ -134,6 +134,7 @@ void rbtree_clear(rb_tree_t *tree) + return; + } + rbtree_destroy_all(tree, tree->root); ++ tree->root = tree->nil; + } + + void rbtree_free(rb_tree_t *tree) +diff --git a/test/image/oci/registry/CMakeLists.txt b/test/image/oci/registry/CMakeLists.txt +index 13ed95b2..5475b7b5 100644 +--- a/test/image/oci/registry/CMakeLists.txt ++++ b/test/image/oci/registry/CMakeLists.txt +@@ -26,6 +26,7 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/registry_type.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/common/sysinfo.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/storage/image_store/image_store.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/registry/registry.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/registry/registry_apiv2.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/registry/registry_apiv1.c +@@ -57,6 +58,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/storage + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/storage/image_store ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/storage/remote_layer_support + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../src/daemon/modules/image/oci/registry + ${CMAKE_CURRENT_SOURCE_DIR}/../../../mocks + ) +diff --git a/test/image/oci/storage/CMakeLists.txt b/test/image/oci/storage/CMakeLists.txt +index feb81b14..7a9d77fe 100644 +--- a/test/image/oci/storage/CMakeLists.txt ++++ b/test/image/oci/storage/CMakeLists.txt +@@ -3,3 +3,6 @@ project(iSulad_UT) + add_subdirectory(images) + add_subdirectory(rootfs) + add_subdirectory(layers) ++IF (ENABLE_REMOTE_LAYER_STORE) ++add_subdirectory(remote_layer_support) ++ENDIF() +diff --git a/test/image/oci/storage/images/CMakeLists.txt b/test/image/oci/storage/images/CMakeLists.txt +index 3e6b69a4..8446ebba 100644 +--- a/test/image/oci/storage/images/CMakeLists.txt ++++ b/test/image/oci/storage/images/CMakeLists.txt +@@ -21,6 +21,7 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/image_store/image_type.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/registry_type.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/image_store/image_store.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../mocks/storage_mock.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../mocks/isulad_config_mock.cc + storage_images_ut.cc) +@@ -39,6 +40,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/image_store ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/registry + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../mocks + ) +diff --git a/test/image/oci/storage/layers/CMakeLists.txt b/test/image/oci/storage/layers/CMakeLists.txt +index 952e9483..ae0ac9c3 100644 +--- a/test/image/oci/storage/layers/CMakeLists.txt ++++ b/test/image/oci/storage/layers/CMakeLists.txt +@@ -30,6 +30,7 @@ add_executable(${DRIVER_EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/metadata_store.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/wrapper_devmapper.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/quota/project_quota.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../mocks/driver_quota_mock.cc + storage_driver_ut.cc) +@@ -52,6 +53,7 @@ target_include_directories(${DRIVER_EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2 ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/quota + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../mocks + ) +@@ -105,6 +107,7 @@ add_executable(${LAYER_EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper/wrapper_devmapper.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2/driver_overlay2.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/quota/project_quota.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../mocks/driver_quota_mock.cc + storage_layers_ut.cc) + +@@ -129,6 +132,7 @@ target_include_directories(${LAYER_EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2 + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/quota ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../mocks + ) + +diff --git a/test/image/oci/storage/remote_layer_support/CMakeLists.txt b/test/image/oci/storage/remote_layer_support/CMakeLists.txt +new file mode 100644 +index 00000000..c36d9049 +--- /dev/null ++++ b/test/image/oci/storage/remote_layer_support/CMakeLists.txt +@@ -0,0 +1,44 @@ ++project(iSulad_UT) ++ ++SET(EXE remote_layer_support_ut) ++ ++add_executable(${EXE} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../mocks/remote_store_mock.cc ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/map/map.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support/remote_support.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support/overlay_remote_impl.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support/image_remote_impl.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support/layer_remote_impl.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils/utils_file.c ++ remote_layer_ut.cc ++ ) ++ ++target_include_directories(${EXE} PUBLIC ++ ${GTEST_INCLUDE_DIR} ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../include ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/config ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/common ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/api ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/image_store ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/overlay2 ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver/devmapper ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/layer_store/graphdriver ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/utils/cutils ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../mocks ++ ) ++ ++target_link_libraries(${EXE} ++ ${GTEST_BOTH_LIBRARIES} ++ ${GMOCK_LIBRARY} ++ ${GMOCK_MAIN_LIBRARY} ++ ${CMAKE_THREAD_LIBS_INIT} ++ ${ISULA_LIBUTILS_LIBRARY} ++ -lgtest -lgtest_main libutils_ut -lcrypto -lyajl -lz) ++ ++add_test(NAME ${EXE} COMMAND ${EXE} --gtest_output=xml:${EXE}-Results.xml) ++set_tests_properties(${EXE} PROPERTIES TIMEOUT 120) +diff --git a/test/image/oci/storage/remote_layer_support/remote_layer_ut.cc b/test/image/oci/storage/remote_layer_support/remote_layer_ut.cc +new file mode 100644 +index 00000000..5f5e92fb +--- /dev/null ++++ b/test/image/oci/storage/remote_layer_support/remote_layer_ut.cc +@@ -0,0 +1,93 @@ ++/****************************************************************************** ++ * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved. ++ * iSulad licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * Author: wangrunze ++ * Create: 2023-03-16 ++ * Description: provide remote layer support ut ++ ******************************************************************************/ ++#include <gtest/gtest.h> ++ ++#include "remote_store_mock.h" ++#include "ro_symlink_maintain.h" ++#include "remote_support.h" ++#include "map.h" ++ ++using ::testing::Invoke; ++ ++bool invokeOverlayRemoteLayerValid(const char *id) ++{ ++ return true; /* currently always valid overlay layer */ ++} ++ ++bool invokeLayerRemoteLayerValid(const char *id) ++{ ++ return true; ++} ++ ++int invokeLayerLoadOneLayer(const char *id) ++{ ++ return 0; ++} ++ ++int invokeLayerRemoveOneLayer(const char *id) ++{ ++ return 0; ++} ++ ++int invokeImageAppendOneImage(const char *id) ++{ ++ return 0; ++} ++ ++int invokeImageRemoveOneImage(const char *id) ++{ ++ return 0; ++} ++ ++char *invokeImageGetTopLayer(const char *id) ++{ ++ return NULL; ++} ++ ++int invokeImageValidSchemaV1(const char *path, bool *valid) ++{ ++ return 0; ++} ++ ++void mockCommonAll(MockRemoteStore *mock) ++{ ++ EXPECT_CALL(*mock, LayerLoadOneLayer(::testing::_)).WillRepeatedly(Invoke(invokeLayerLoadOneLayer)); ++ EXPECT_CALL(*mock, LayerRemoveOneLayer(::testing::_)).WillRepeatedly(Invoke(invokeLayerRemoveOneLayer)); ++ ++ EXPECT_CALL(*mock, ImageAppendOneImage(::testing::_)).WillRepeatedly(Invoke(invokeImageAppendOneImage)); ++ EXPECT_CALL(*mock, ImageRemoveOneImage(::testing::_)).WillRepeatedly(Invoke(invokeImageRemoveOneImage)); ++ EXPECT_CALL(*mock, ImageGetTopLayer(::testing::_)).WillRepeatedly(Invoke(invokeImageGetTopLayer)); ++ EXPECT_CALL(*mock, ImageValidSchemaV1(::testing::_, ::testing::_)).WillRepeatedly(Invoke(invokeImageValidSchemaV1)); ++} ++ ++TEST(remote_Layer_ut, test_map_diff) ++{ ++ // old: a b x ++ // new: x b c ++ map_t *old_one = map_new(MAP_STR_BOOL, MAP_DEFAULT_CMP_FUNC, MAP_DEFAULT_FREE_FUNC); ++ map_t *new_one = map_new(MAP_STR_BOOL, MAP_DEFAULT_CMP_FUNC, MAP_DEFAULT_FREE_FUNC); ++ bool exist = true; ++ ++ map_insert(old_one, (void *)"a", (void *)&exist); ++ map_insert(old_one, (void *)"b", (void *)&exist); ++ map_insert(new_one, (void *)"b", (void *)&exist); ++ map_insert(new_one, (void *)"c", (void *)&exist); ++ ++ char **added = remote_added_layers(old_one, new_one); ++ char **deleted = remote_deleted_layers(old_one, new_one); ++ ++ ASSERT_EQ(added[0][0], 'c'); ++ ASSERT_EQ(deleted[0][0], 'a'); ++} +diff --git a/test/image/oci/storage/rootfs/CMakeLists.txt b/test/image/oci/storage/rootfs/CMakeLists.txt +index 4d7d3533..5383fbac 100644 +--- a/test/image/oci/storage/rootfs/CMakeLists.txt ++++ b/test/image/oci/storage/rootfs/CMakeLists.txt +@@ -22,6 +22,7 @@ add_executable(${EXE} + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/utils_images.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/rootfs_store/rootfs.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/rootfs_store/rootfs_store.c ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support/ro_symlink_maintain.c + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../mocks/storage_mock.cc + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../mocks/isulad_config_mock.cc + storage_rootfs_ut.cc) +@@ -41,6 +42,7 @@ target_include_directories(${EXE} PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage + ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/rootfs_store ++ ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../src/daemon/modules/image/oci/storage/remote_layer_support + ) + + target_link_libraries(${EXE} ${GTEST_BOTH_LIBRARIES} ${GMOCK_LIBRARY} ${GMOCK_MAIN_LIBRARY} ${CMAKE_THREAD_LIBS_INIT} ${ISULA_LIBUTILS_LIBRARY} -lcrypto -lyajl -lz) +diff --git a/test/mocks/remote_store_mock.cc b/test/mocks/remote_store_mock.cc +new file mode 100644 +index 00000000..c6428623 +--- /dev/null ++++ b/test/mocks/remote_store_mock.cc +@@ -0,0 +1,68 @@ ++/****************************************************************************** ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. ++ * iSulad licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * Author: wangrunze ++ * Create: 2023-03-09 ++ * Description: provide mock for image store, layer store and driver overlay ++ ******************************************************************************/ ++ ++#include "remote_store_mock.h" ++ ++namespace { ++MockRemoteStore *g_remote_store_mock = nullptr; ++} ++ ++int remote_load_one_layer(const char *id) ++{ ++ if (g_remote_store_mock != nullptr) { ++ return g_remote_store_mock->LayerLoadOneLayer(id); ++ } ++ return -1; ++} ++ ++int remote_layer_remove_memory_stores_with_lock(const char *id) ++{ ++ if (g_remote_store_mock != nullptr) { ++ return g_remote_store_mock->LayerRemoveOneLayer(id); ++ } ++ return -1; ++} ++ ++int image_store_validate_manifest_schema_version_1(const char *path, bool *valid) ++{ ++ if (g_remote_store_mock != nullptr) { ++ return g_remote_store_mock->ImageValidSchemaV1(path, valid); ++ } ++ return -1; ++} ++ ++int remote_append_image_by_directory_with_lock(const char *image_dir) ++{ ++ if (g_remote_store_mock != nullptr) { ++ return g_remote_store_mock->ImageAppendOneImage(image_dir); ++ } ++ return -1; ++} ++ ++int remote_remove_image_from_memory_with_lock(const char *id) ++{ ++ if (g_remote_store_mock != nullptr) { ++ return g_remote_store_mock->ImageRemoveOneImage(id); ++ } ++ return -1; ++} ++ ++char *remote_image_get_top_layer_from_json(const char *img_id) ++{ ++ if (g_remote_store_mock != nullptr) { ++ return g_remote_store_mock->ImageGetTopLayer(img_id); ++ } ++ return nullptr; ++} +diff --git a/test/mocks/remote_store_mock.h b/test/mocks/remote_store_mock.h +new file mode 100644 +index 00000000..e8d73ef1 +--- /dev/null ++++ b/test/mocks/remote_store_mock.h +@@ -0,0 +1,40 @@ ++/****************************************************************************** ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. ++ * iSulad licensed under the Mulan PSL v2. ++ * You can use this software according to the terms and conditions of the Mulan PSL v2. ++ * You may obtain a copy of Mulan PSL v2 at: ++ * http://license.coscl.org.cn/MulanPSL2 ++ * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR ++ * PURPOSE. ++ * See the Mulan PSL v2 for more details. ++ * Author: wangrunze ++ * Create: 2023-03-09 ++ * Description: provide mock for image store, layer store and driver overlay ++ ******************************************************************************/ ++ ++#ifndef _ISULAD_TEST_MOCKS_REMOTE_STORE_MOCK_H ++#define _ISULAD_TEST_MOCKS_REMOTE_STORE_MOCK_H ++ ++#include <gmock/gmock.h> ++ ++#include "image_store.h" ++#include "layer_store.h" ++#include "driver_overlay2.h" ++ ++class MockRemoteStore { ++public: ++ virtual ~MockRemoteStore() = default; ++ // MOCK_METHOD1(OverlayRemoteLayerValid, bool(const char *)); ++ ++ // MOCK_METHOD1(LayerRemoteLayerValid, bool(const char *)); ++ MOCK_METHOD1(LayerLoadOneLayer, int(const char *)); ++ MOCK_METHOD1(LayerRemoveOneLayer, int(const char *)); ++ ++ MOCK_METHOD1(ImageAppendOneImage, int(const char *)); ++ MOCK_METHOD1(ImageRemoveOneImage, int(const char *)); ++ MOCK_METHOD1(ImageGetTopLayer, char *(const char *)); ++ MOCK_METHOD2(ImageValidSchemaV1, int(const char *, bool *)); ++}; ++ ++#endif // _ISULAD_TEST_MOCKS_IMAGE_MOCK_H +-- +2.25.1 + |