Signed-off-by: zhongtao <zhongtao17@huawei.com> (cherry picked from commit fc7c8485b85f940b9d1346514f476f1cd53560e5)
84 lines
3.9 KiB
Diff
84 lines
3.9 KiB
Diff
From 1639a5ae0ec656f1c67f730e163cb1ccca5fd205 Mon Sep 17 00:00:00 2001
|
|
From: zhongtao <zhongtao17@huawei.com>
|
|
Date: Fri, 1 Mar 2024 15:04:09 +0800
|
|
Subject: [PATCH 201/204] bugfix for the concurrency competition between the
|
|
reuse layer and the creation layer
|
|
|
|
Signed-off-by: zhongtao <zhongtao17@huawei.com>
|
|
---
|
|
src/daemon/modules/image/oci/oci_load.c | 9 ++++++++-
|
|
src/daemon/modules/image/oci/registry/registry.c | 9 ++++++++-
|
|
2 files changed, 16 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/src/daemon/modules/image/oci/oci_load.c b/src/daemon/modules/image/oci/oci_load.c
|
|
index efffa6f5..af4d134c 100644
|
|
--- a/src/daemon/modules/image/oci/oci_load.c
|
|
+++ b/src/daemon/modules/image/oci/oci_load.c
|
|
@@ -676,6 +676,12 @@ static int oci_load_set_layers_info(load_image_t *im, const image_manifest_items
|
|
char *parent_chain_id_sha256 = "";
|
|
char *id = NULL;
|
|
char *parent_chain_id = NULL;
|
|
+ // exist_flag is used to mark whether a non-existent layer has been encountered during this layer reuse process.
|
|
+ // 1.exist_flag is true if the layers are currently reusable;
|
|
+ // 2.exist_flag is false if encounter an uncreated layer that cannot be reused
|
|
+ // Prevent concurrent competition between the creation layer function
|
|
+ // and the reuse layer function on the im -> layer_of_hold_refs variable
|
|
+ bool exist_flag = true;
|
|
|
|
if (im == NULL || manifest == NULL || dstdir == NULL) {
|
|
ERROR("Invalid input params image or manifest is null");
|
|
@@ -757,7 +763,7 @@ static int oci_load_set_layers_info(load_image_t *im, const image_manifest_items
|
|
goto out;
|
|
}
|
|
|
|
- if (storage_inc_hold_refs(id) == 0) {
|
|
+ if (exist_flag && storage_inc_hold_refs(id) == 0) {
|
|
free(im->layer_of_hold_refs);
|
|
im->layer_of_hold_refs = util_strdup_s(id);
|
|
if (parent_chain_id != NULL && storage_dec_hold_refs(parent_chain_id) != 0) {
|
|
@@ -777,6 +783,7 @@ static int oci_load_set_layers_info(load_image_t *im, const image_manifest_items
|
|
continue;
|
|
}
|
|
|
|
+ exist_flag = false;
|
|
if (check_and_set_digest_from_tarball(im->layers[i], conf->rootfs->diff_ids[i]) != 0) {
|
|
ERROR("Check layer digest failed");
|
|
ret = -1;
|
|
diff --git a/src/daemon/modules/image/oci/registry/registry.c b/src/daemon/modules/image/oci/registry/registry.c
|
|
index 5265b5ab..b612a618 100644
|
|
--- a/src/daemon/modules/image/oci/registry/registry.c
|
|
+++ b/src/daemon/modules/image/oci/registry/registry.c
|
|
@@ -1510,6 +1510,12 @@ static int fetch_all(pull_descriptor *desc)
|
|
struct layer_list *list = NULL;
|
|
pthread_t tid = 0;
|
|
struct timespec ts = { 0 };
|
|
+ // exist_flag is used to mark whether a non-existent layer has been encountered during this layer reuse process.
|
|
+ // 1.exist_flag is true if the layers are currently reusable;
|
|
+ // 2.exist_flag is false if encounter an uncreated layer that cannot be reused
|
|
+ // Prevent concurrent competition between the creation layer function
|
|
+ // and the reuse layer function on the im -> layer_of_hold_refs variable
|
|
+ bool exist_flag = true;
|
|
|
|
if (desc == NULL) {
|
|
ERROR("Invalid NULL param");
|
|
@@ -1541,7 +1547,7 @@ static int fetch_all(pull_descriptor *desc)
|
|
|
|
// Skip layer that already exist in local store
|
|
list = storage_layers_get_by_compress_digest(desc->layers[i].digest);
|
|
- if (list != NULL) {
|
|
+ if (exist_flag && list != NULL) {
|
|
for (j = 0; j < list->layers_len; j++) {
|
|
if ((list->layers[j]->parent == NULL && i == 0) ||
|
|
(parent_chain_id != NULL && list->layers[j]->parent != NULL &&
|
|
@@ -1573,6 +1579,7 @@ static int fetch_all(pull_descriptor *desc)
|
|
continue;
|
|
}
|
|
}
|
|
+ exist_flag = false;
|
|
|
|
// parent_chain_id = NULL means no parent chain match from now on, so no longer need
|
|
// to get layers by compressed digest to reuse layer.
|
|
--
|
|
2.25.1
|
|
|