提交 b8770356 编写于 作者: H haozi007 提交者: lifeng68

refactor digest store

Signed-off-by: Nhaozi007 <liuhao27@huawei.com>
上级 1de52502
...@@ -42,6 +42,11 @@ typedef struct __layer_store_metadata_t { ...@@ -42,6 +42,11 @@ typedef struct __layer_store_metadata_t {
size_t layers_list_len; size_t layers_list_len;
} layer_store_metadata; } layer_store_metadata;
typedef struct digest_layer {
struct linked_list layer_list;
size_t layer_list_len;
} digest_layer_t;
static layer_store_metadata g_metadata; static layer_store_metadata g_metadata;
static char *g_root_dir; static char *g_root_dir;
static char *g_run_dir; static char *g_run_dir;
...@@ -50,9 +55,11 @@ static inline char *tar_split_path(const char *id); ...@@ -50,9 +55,11 @@ static inline char *tar_split_path(const char *id);
static inline char *mountpoint_json_path(const char *id); static inline char *mountpoint_json_path(const char *id);
static inline char *layer_json_path(const char *id); static inline char *layer_json_path(const char *id);
static int insert_digest_into_map(map_t *by_digest, const char *digest, const char *id);
static int delete_digest_from_map(map_t *by_digest, const char *digest, const char *id);
static bool remove_name(const char *name); static bool remove_name(const char *name);
static void recover_name(const char *name); static void recover_name(const char *name);
static int update_digest_map(map_t *by_digest, const char *old_val, const char *new_val, const char *id);
static inline bool layer_store_lock(bool writable) static inline bool layer_store_lock(bool writable)
{ {
...@@ -87,18 +94,28 @@ void layer_store_cleanup() ...@@ -87,18 +94,28 @@ void layer_store_cleanup()
struct linked_list *next = NULL; struct linked_list *next = NULL;
map_free(g_metadata.by_id); map_free(g_metadata.by_id);
g_metadata.by_id = NULL;
map_free(g_metadata.by_name); map_free(g_metadata.by_name);
g_metadata.by_name = NULL;
map_free(g_metadata.by_compress_digest); map_free(g_metadata.by_compress_digest);
g_metadata.by_compress_digest = NULL;
map_free(g_metadata.by_uncompress_digest); map_free(g_metadata.by_uncompress_digest);
g_metadata.by_uncompress_digest = NULL;
linked_list_for_each_safe(item, &(g_metadata.layers_list), next) { linked_list_for_each_safe(item, &(g_metadata.layers_list), next) {
linked_list_del(item); linked_list_del(item);
layer_ref_dec((layer_t *)item->elem); layer_ref_dec((layer_t *)item->elem);
free(item); free(item);
item = NULL;
} }
g_metadata.layers_list_len = 0; g_metadata.layers_list_len = 0;
pthread_rwlock_destroy(&(g_metadata.rwlock)); pthread_rwlock_destroy(&(g_metadata.rwlock));
free(g_run_dir);
g_run_dir = NULL;
free(g_root_dir);
g_root_dir = NULL;
} }
/* layers map kvfree */ /* layers map kvfree */
...@@ -107,11 +124,33 @@ static void layer_map_kvfree(void *key, void *value) ...@@ -107,11 +124,33 @@ static void layer_map_kvfree(void *key, void *value)
free(key); free(key);
} }
static void free_digest_layer_t(digest_layer_t *ptr)
{
struct linked_list *item = NULL;
struct linked_list *next = NULL;
if (ptr == NULL) {
return;
}
linked_list_for_each_safe(item, &(ptr->layer_list), next) {
linked_list_del(item);
free(item->elem);
item->elem = NULL;
free(item);
item = NULL;
}
ptr->layer_list_len = 0;
free(ptr);
}
static void digest_map_kvfree(void *key, void *value) static void digest_map_kvfree(void *key, void *value)
{ {
free(key); digest_layer_t *val = (digest_layer_t *)value;
util_free_array((char **)value); free(key);
free_digest_layer_t(val);
} }
static inline void insert_g_layer_list_item(struct linked_list *item) static inline void insert_g_layer_list_item(struct linked_list *item)
...@@ -302,43 +341,39 @@ static int load_layers_from_json_files() ...@@ -302,43 +341,39 @@ static int load_layers_from_json_files()
} }
if (!map_insert(g_metadata.by_name, (void *)tl->slayer->names[i], (void *)tl)) { if (!map_insert(g_metadata.by_name, (void *)tl->slayer->names[i], (void *)tl)) {
ERROR("Insert name: %s for layer failed", tl->slayer->names[i]); ERROR("Insert name: %s for layer failed", tl->slayer->names[i]);
goto err_out; goto unlock_out;
} }
} }
ret = update_digest_map(g_metadata.by_compress_digest, NULL, tl->slayer->compressed_diff_digest, tl->slayer->id); ret = insert_digest_into_map(g_metadata.by_compress_digest, tl->slayer->compressed_diff_digest, tl->slayer->id);
if (ret != 0) { if (ret != 0) {
ERROR("update layer: %s compress failed", tl->slayer->id); ERROR("update layer: %s compress failed", tl->slayer->id);
goto err_out; goto unlock_out;
} }
ret = update_digest_map(g_metadata.by_uncompress_digest, NULL, tl->slayer->diff_digest, tl->slayer->id); ret = insert_digest_into_map(g_metadata.by_uncompress_digest, tl->slayer->diff_digest, tl->slayer->id);
if (ret != 0) { if (ret != 0) {
ERROR("update layer: %s uncompress failed", tl->slayer->id); ERROR("update layer: %s uncompress failed", tl->slayer->id);
goto err_out; goto unlock_out;
} }
// check complete // check complete
if (tl->incompelte) { if (tl->incompelte) {
if (layer_store_delete(tl->slayer->id) != 0) { if (layer_store_delete(tl->slayer->id) != 0) {
ERROR("delete layer: %s failed", tl->slayer->id); ERROR("delete layer: %s failed", tl->slayer->id);
goto err_out; goto unlock_out;
} }
should_save = true; should_save = true;
} }
if (should_save && save_layer(tl) != 0) { if (should_save && save_layer(tl) != 0) {
ERROR("save layer: %s failed", tl->slayer->id); ERROR("save layer: %s failed", tl->slayer->id);
goto err_out; goto unlock_out;
} }
} }
ret = 0; ret = 0;
goto unlock_out; goto unlock_out;
err_out:
// clear memory store
layer_store_cleanup();
ret = -1;
unlock_out: unlock_out:
layer_store_unlock(); layer_store_unlock();
return ret; return ret;
...@@ -643,70 +678,78 @@ free_out: ...@@ -643,70 +678,78 @@ free_out:
return ret; return ret;
} }
static int update_digest_map(map_t *by_digest, const char *old_val, const char *new_val, const char *id) static int delete_digest_from_map(map_t *by_digest, const char *digest, const char *id)
{ {
char **old_list = NULL; digest_layer_t *old_list = NULL;
size_t old_len = 0; struct linked_list *item = NULL;
int ret = 0; struct linked_list *next = NULL;
size_t i = 0;
if (new_val != NULL) { if (digest == NULL) {
char **tmp_new_list = NULL; return 0;
char **new_list = (char **)map_search(by_digest, (void *)new_val); }
size_t new_len = util_array_len((const char **)new_list);
tmp_new_list = util_smart_calloc_s(sizeof(char *), new_len + 2); old_list = (digest_layer_t *)map_search(by_digest, (void *)digest);
if (tmp_new_list == NULL) { if (old_list == NULL) {
ERROR("Out of memory"); return 0;
ret = -1; }
goto out;
}
for (i = 0; i < new_len; i++) {
tmp_new_list[new_len] = new_list[i];
new_list[i] = NULL;
}
tmp_new_list[new_len] = util_strdup_s(id);
if (!map_replace(by_digest, (void *)new_val, (void *)tmp_new_list)) { linked_list_for_each_safe(item, &(old_list->layer_list), next) {
ERROR("Insert new digest failed"); char *t_id = (char *)item->elem;
// recover new list if (strcmp(t_id, id) == 0) {
for (i = 0; i < new_len; i++) { linked_list_del(item);
new_list[i] = tmp_new_list[i]; free(item->elem);
} free(item);
free(tmp_new_list[new_len]); item = NULL;
free(tmp_new_list); old_list->layer_list_len -= 1;
ret = -1; break;
goto out;
} }
} }
if (old_val != NULL) { if (old_list->layer_list_len == 0 && !map_remove(by_digest, (void *)digest)) {
size_t idx = 0; WARN("Remove old failed");
size_t new_len; }
old_list = (char **)map_search(by_digest, (void *)old_val);
old_len = util_array_len((const char **)old_list);
new_len = old_len;
for (; idx < old_len; idx++) { return 0;
if (strcmp(old_list[idx], id) == 0) { }
new_len--;
free(old_list[idx]); static int insert_digest_into_map(map_t *by_digest, const char *digest, const char *id)
old_list[idx] = NULL; {
break; digest_layer_t *old_list = NULL;
} struct linked_list *item = NULL;
} digest_layer_t *new_list = NULL;
for (idx = idx + 1; idx < old_len; idx++) {
old_list[idx - 1] = old_list[idx]; if (digest == NULL) {
old_list[idx] = NULL; INFO("Layer: %s with empty digest", id);
} return 0;
}
if (new_len == 0 && !map_remove(by_digest, (void *)old_val)) { old_list = (digest_layer_t *)map_search(by_digest, (void *)digest);
WARN("Remove old failed"); if (old_list == NULL) {
new_list = (digest_layer_t *)util_common_calloc_s(sizeof(digest_layer_t));
if (new_list == NULL) {
ERROR("Out of memory");
return -1;
} }
old_list = new_list;
} }
out: item = (struct linked_list *)util_common_calloc_s(sizeof(struct linked_list));
return ret; if (item == NULL) {
ERROR("Out of memory");
goto free_out;
}
linked_list_add_elem(item, (void *)util_strdup_s(id));
linked_list_add_tail(&(old_list->layer_list), item);
old_list->layer_list_len += 1;
if (!map_replace(by_digest, (void *)digest, (void *)old_list)) {
goto free_out;
}
return 0;
free_out:
free_digest_layer_t(new_list);
return -1;
} }
static int remove_memory_stores(const char *id) static int remove_memory_stores(const char *id)
...@@ -723,12 +766,12 @@ static int remove_memory_stores(const char *id) ...@@ -723,12 +766,12 @@ static int remove_memory_stores(const char *id)
return -1; return -1;
} }
if (update_digest_map(g_metadata.by_compress_digest, l->slayer->compressed_diff_digest, NULL, l->slayer->id) != 0) { if (delete_digest_from_map(g_metadata.by_compress_digest, l->slayer->compressed_diff_digest, l->slayer->id) != 0) {
ERROR("Remove %s from compress digest failed", id); ERROR("Remove %s from compress digest failed", id);
ret = -1; ret = -1;
goto out; goto out;
} }
if (update_digest_map(g_metadata.by_uncompress_digest, l->slayer->diff_digest, NULL, l->slayer->id) != 0) { if (delete_digest_from_map(g_metadata.by_uncompress_digest, l->slayer->diff_digest, l->slayer->id) != 0) {
// ignore this error, because only happen at out of memory; // ignore this error, because only happen at out of memory;
// we cannot to recover before operator, so just go on. // we cannot to recover before operator, so just go on.
WARN("Remove %s from uncompress failed", id); WARN("Remove %s from uncompress failed", id);
...@@ -811,6 +854,8 @@ static int apply_diff(const char *id, const struct io_read_wrapper *diff) ...@@ -811,6 +854,8 @@ static int apply_diff(const char *id, const struct io_read_wrapper *diff)
INFO("Apply layer get size: %lld", size); INFO("Apply layer get size: %lld", size);
// TODO: save split tar
return ret; return ret;
} }
...@@ -901,19 +946,20 @@ static int layer_store_remove_layer(const char *id) ...@@ -901,19 +946,20 @@ static int layer_store_remove_layer(const char *id)
{ {
char *rpath = NULL; char *rpath = NULL;
int ret = 0; int ret = 0;
int nret = 0;
if (id == NULL) { if (id == NULL) {
return 0; return 0;
} }
rpath = layer_json_path(id); nret = asprintf(&rpath, "%s/%s", g_root_dir, id);
if (rpath == NULL) { if (nret < 0 || nret > PATH_MAX) {
WARN("Generate rpath for layer %s failed, jsut ignore", id); SYSERROR("Create layer json path failed");
return 0; return -1;
} }
ret = util_path_remove(rpath); ret = util_path_remove(rpath);
free(rpath); free(rpath);
return ret; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册