提交 cd503ba4 编写于 作者: W wujing 提交者: lifeng68

rootfs store interface implement

Signed-off-by: Nwujing <wujing50@huawei.com>
上级 4537c008
......@@ -290,3 +290,72 @@ char *oci_strip_dockerio_prefix(const char *name)
return util_strdup_s(name);
}
static bool should_use_origin_name(const char *name)
{
size_t i;
for (i = 0; i < strlen(name); i++) {
char ch = name[i];
if (ch != '.' && !(ch >= '0' && ch <= '9') && !(ch >= 'a' && ch <= 'z')) {
return false;
}
}
return true;
}
// Convert a BigData key name into an acceptable file name.
char *make_big_data_base_name(const char *key)
{
int ret = 0;
int nret = 0;
char *b64_encode_name = NULL;
size_t b64_encode_name_len = 0;
char *base_name = NULL;
size_t name_size;
if (should_use_origin_name(key)) {
return util_strdup_s(key);
}
b64_encode_name_len = util_base64_encode_len(strlen(key));
b64_encode_name = util_common_calloc_s(b64_encode_name_len + 1);
if (b64_encode_name == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
nret = util_base64_encode((unsigned char *)key, strlen(key), b64_encode_name, b64_encode_name_len);
if (nret < 0) {
ret = -1;
ERROR("Encode auth to base64 failed");
goto out;
}
name_size = 1 + strlen(b64_encode_name) + 1; // '=' + encode string + '\0'
base_name = (char *)util_common_calloc_s(name_size * sizeof(char));
if (base_name == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
nret = snprintf(base_name, name_size, "=%s", b64_encode_name);
if (nret < 0 || (size_t)nret >= name_size) {
ERROR("Out of memory");
ret = -1;
goto out;
}
DEBUG("big data file name : %s", base_name);
out:
if (ret != 0) {
free(base_name);
base_name = NULL;
}
free(b64_encode_name);
return base_name;
}
......@@ -39,6 +39,7 @@ char *oci_normalize_image_name(const char *name);
int oci_split_image_name(const char *image_name, char **host, char **name, char **tag);
char *oci_full_image_name(const char *host, const char *name, const char *tag);
char *oci_strip_dockerio_prefix(const char *name);
char *make_big_data_base_name(const char *key);
#ifdef __cplusplus
}
......
......@@ -15,6 +15,8 @@
#ifndef __IMAGE_REGISTRY_H
#define __IMAGE_REGISTRY_H
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
......
......@@ -23,7 +23,6 @@
#include <unistd.h>
#include <string.h>
#include <stddef.h>
#include <libwebsockets.h>
#include <sha256.h>
#include "utils.h"
#include "log.h"
......@@ -1296,75 +1295,6 @@ out:
return ret;
}
static bool should_use_origin_name(const char *name)
{
size_t i;
for (i = 0; i < strlen(name); i++) {
char ch = name[i];
if (ch != '.' && !(ch >= '0' && ch <= '9') && !(ch >= 'a' && ch <= 'z')) {
return false;
}
}
return true;
}
// Convert a BigData key name into an acceptable file name.
static char *make_big_data_base_name(const char *key)
{
int ret = 0;
int nret = 0;
char *b64_encode_name = NULL;
size_t b64_encode_name_len = 0;
char *base_name = NULL;
size_t name_size;
if (should_use_origin_name(key)) {
return util_strdup_s(key);
}
b64_encode_name_len = util_base64_encode_len(strlen(key));
b64_encode_name = util_common_calloc_s(b64_encode_name_len + 1);
if (b64_encode_name == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
nret = util_base64_encode((unsigned char *)key, strlen(key), b64_encode_name, b64_encode_name_len);
if (nret < 0) {
ret = -1;
ERROR("Encode auth to base64 failed");
goto out;
}
name_size = 1 + strlen(b64_encode_name) + 1; // '=' + encode string + '\0'
base_name = (char *)util_common_calloc_s(name_size * sizeof(char));
if (base_name == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
nret = snprintf(base_name, name_size, "=%s", b64_encode_name);
if (nret < 0 || (size_t)nret >= name_size) {
ERROR("Out of memory");
ret = -1;
goto out;
}
DEBUG("big data file name : %s", base_name);
out:
if (ret != 0) {
free(base_name);
base_name = NULL;
}
free(b64_encode_name);
return base_name;
}
static int get_data_path(const char *id, const char *key, char *path, size_t len)
{
int ret = 0;
......@@ -1779,7 +1709,7 @@ int image_store_set_names(const char *id, const char **names, size_t names_len)
}
if (!image_store_lock(EXCLUSIVE)) {
ERROR("Failed to lock image store with exclusive lock, not allowed to change image name assignments");
ERROR("Failed to lock image store with exclusive lock, not allowed to change image names assignments");
return -1;
}
......@@ -1914,7 +1844,11 @@ int image_store_set_metadata(const char *id, const char *metadata)
free(img->simage->metadata);
img->simage->metadata = util_strdup_s(metadata);
save_image(img);
if (save_image(img) != 0) {
ERROR("Failed to save image");
ret = -1;
goto out;
}
out:
image_ref_dec(img);
......@@ -2357,7 +2291,11 @@ int image_store_set_image_size(const char *id, uint64_t size)
}
img->simage->size = size;
save_image(img);
if (save_image(img) != 0) {
ERROR("Failed to save image");
ret = -1;
goto out;
}
out:
image_ref_dec(img);
......
......@@ -51,7 +51,7 @@ cntrootfs_t *new_rootfs(storage_rootfs *scntr)
return NULL;
}
c->scontainer = scntr;
c->srootfs = scntr;
return c;
......@@ -86,8 +86,8 @@ void free_rootfs_t(cntrootfs_t *ptr)
if (ptr == NULL) {
return;
}
free_storage_rootfs(ptr->scontainer);
ptr->scontainer = NULL;
free_storage_rootfs(ptr->srootfs);
ptr->srootfs = NULL;
free(ptr);
}
......
......@@ -26,7 +26,7 @@ extern "C" {
#endif
typedef struct _cntrootfs_t {
storage_rootfs *scontainer;
storage_rootfs *srootfs;
uint64_t refcnt;
} cntrootfs_t;
......
......@@ -10,7 +10,7 @@
* See the Mulan PSL v2 for more details.
* Author: wujing
* Create: 2020-05-12
* Description: provide image store functions
* Description: provide container rootfs store functions
******************************************************************************/
#define _GNU_SOURCE
#include "rootfs_store.h"
......@@ -47,17 +47,23 @@ typedef struct rootfs_store {
bool loaded;
} rootfs_store_t;
enum lock_type {
SHARED = 0,
EXCLUSIVE
};
rootfs_store_t *g_rootfs_store = NULL;
static inline bool rootfs_store_lock(bool writable)
static inline bool rootfs_store_lock(enum lock_type type)
{
int nret = 0;
if (writable) {
nret = pthread_rwlock_wrlock(&g_rootfs_store->rwlock);
} else {
if (type == SHARED) {
nret = pthread_rwlock_rdlock(&g_rootfs_store->rwlock);
} else {
nret = pthread_rwlock_wrlock(&g_rootfs_store->rwlock);
}
if (nret != 0) {
ERROR("Lock memory store failed: %s", strerror(nret));
return false;
......@@ -121,6 +127,44 @@ static void rootfs_store_field_kvfree(void *key, void *value)
free(key);
}
static inline int get_data_dir(const char *id, char *path, size_t len)
{
int nret = snprintf(path, len, "%s/%s", g_rootfs_store->dir, id);
return (nret < 0 || (size_t)nret >= len) ? -1 : 0;
}
static int get_data_path(const char *id, const char *key, char *path, size_t len)
{
int ret = 0;
int nret = 0;
char *data_base_name = NULL;
char data_dir[PATH_MAX] = { 0x00 };
data_base_name = make_big_data_base_name(key);
if (data_base_name == NULL) {
ERROR("Failed to make big data base name");
return -1;
}
if (get_data_dir(id, data_dir, sizeof(data_dir)) != 0) {
ERROR("Failed to get rootfs data dir: %s", id);
ret = -1;
goto out;
}
nret = snprintf(path, len, "%s/%s", data_dir, data_base_name);
if (nret < 0 || (size_t)nret >= len) {
ERROR("Failed to get big data base path");
ret = -1;
goto out;
}
out:
free(data_base_name);
return ret;
}
static int do_append_container(storage_rootfs *c)
{
cntrootfs_t *cntr = NULL;
......@@ -190,7 +234,7 @@ static int get_containers_from_json()
char *id_patten = "^[a-f0-9]{64}$";
char container_path[PATH_MAX] = { 0x00 };
if (!rootfs_store_lock(true)) {
if (!rootfs_store_lock(EXCLUSIVE)) {
ERROR("Failed to lock container store");
return -1;
}
......@@ -242,30 +286,30 @@ static int remove_name(cntrootfs_t *cntr, const char *name)
return 0;
}
for (i = 0; i < cntr->scontainer->names_len; i++) {
if (strcmp(cntr->scontainer->names[i], name) == 0) {
for (i = 0; i < cntr->srootfs->names_len; i++) {
if (strcmp(cntr->srootfs->names[i], name) == 0) {
count++;
}
}
new_size = (cntr->scontainer->names_len - count) * sizeof(char *);
new_size = (cntr->srootfs->names_len - count) * sizeof(char *);
tmp_names = (char **)util_common_calloc_s(new_size);
if (tmp_names == NULL) {
ERROR("Out of memory");
return -1;
}
for (i = 0; i < cntr->scontainer->names_len; i++) {
if (strcmp(cntr->scontainer->names[i], name) != 0) {
tmp_names[index++] = util_strdup_s(cntr->scontainer->names[i]);
for (i = 0; i < cntr->srootfs->names_len; i++) {
if (strcmp(cntr->srootfs->names[i], name) != 0) {
tmp_names[index++] = util_strdup_s(cntr->srootfs->names[i]);
}
free(cntr->scontainer->names[i]);
cntr->scontainer->names[i] = NULL;
free(cntr->srootfs->names[i]);
cntr->srootfs->names[i] = NULL;
}
free(cntr->scontainer->names);
cntr->scontainer->names = tmp_names;
cntr->scontainer->names_len = index;
free(cntr->srootfs->names);
cntr->srootfs->names = tmp_names;
cntr->srootfs->names_len = index;
tmp_names = NULL;
return 0;
......@@ -286,8 +330,8 @@ static int save_rootfs(cntrootfs_t *cntr)
parser_error err = NULL;
char *json_data = NULL;
if (get_container_path(cntr->scontainer->id, container_path, sizeof(container_path)) != 0) {
ERROR("Failed to get container path by id: %s", cntr->scontainer->id);
if (get_container_path(cntr->srootfs->id, container_path, sizeof(container_path)) != 0) {
ERROR("Failed to get container path by id: %s", cntr->srootfs->id);
return -1;
}
......@@ -298,7 +342,7 @@ static int save_rootfs(cntrootfs_t *cntr)
return -1;
}
json_data = storage_rootfs_generate_json(cntr->scontainer, NULL, &err);
json_data = storage_rootfs_generate_json(cntr->srootfs, NULL, &err);
if (json_data == NULL) {
ERROR("Failed to generate container json path string:%s", err ? err : " ");
ret = -1;
......@@ -324,27 +368,27 @@ static int load_container_to_store_field(cntrootfs_t *cntr)
bool should_save = false;
size_t i;
if (!map_replace(g_rootfs_store->byid, (void *)cntr->scontainer->id, (void *)cntr)) {
if (!map_replace(g_rootfs_store->byid, (void *)cntr->srootfs->id, (void *)cntr)) {
ERROR("Failed to insert container to id index");
return -1;
}
if (!map_replace(g_rootfs_store->bylayer, (void *)cntr->scontainer->layer, (void *)cntr)) {
if (!map_replace(g_rootfs_store->bylayer, (void *)cntr->srootfs->layer, (void *)cntr)) {
ERROR("Failed to insert container to layer index");
return -1;
}
for (i = 0; i < cntr->scontainer->names_len; i++) {
cntrootfs_t *conflict_container = (cntrootfs_t *)map_search(g_rootfs_store->byname, (void *)cntr->scontainer->names[i]);
for (i = 0; i < cntr->srootfs->names_len; i++) {
cntrootfs_t *conflict_container = (cntrootfs_t *)map_search(g_rootfs_store->byname, (void *)cntr->srootfs->names[i]);
if (conflict_container != NULL) {
if (remove_name(conflict_container, cntr->scontainer->names[i]) != 0) {
if (remove_name(conflict_container, cntr->srootfs->names[i]) != 0) {
ERROR("Failed to remove name from conflict container");
ret = -1;
goto out;
}
should_save = true;
}
if (!map_replace(g_rootfs_store->byname, (void *)cntr->scontainer->names[i], (void *)cntr)) {
if (!map_replace(g_rootfs_store->byname, (void *)cntr->srootfs->names[i], (void *)cntr)) {
ERROR("Failed to insert containes to name index");
ret = -1;
goto out;
......@@ -723,7 +767,7 @@ char *rootfs_store_create(const char *id, const char **names, size_t names_len,
return NULL;
}
if (!rootfs_store_lock(true)) {
if (!rootfs_store_lock(EXCLUSIVE)) {
ERROR("Failed to lock container store, not allowed to create new containers");
return NULL;
}
......@@ -856,19 +900,6 @@ found:
return value;
}
static inline cntrootfs_t *lookup_with_lock(const char *id)
{
cntrootfs_t *cntr = NULL;
if (!rootfs_store_lock(false)) {
return NULL;
}
cntr = lookup(id);
rootfs_store_unlock();
return cntr;
}
char *rootfs_store_lookup(const char *id)
{
char *container_id = NULL;
......@@ -884,24 +915,24 @@ char *rootfs_store_lookup(const char *id)
return NULL;
}
cntr = lookup_with_lock(id);
if (!rootfs_store_lock(SHARED)) {
ERROR("Failed to lock rootfs store, not allowed to lookup rootfs id assginments");
return NULL;
}
cntr = lookup(id);
if (cntr == NULL) {
ERROR("Container not known");
return NULL;
}
container_id = util_strdup_s(cntr->scontainer->id);
container_id = util_strdup_s(cntr->srootfs->id);
rootfs_ref_dec(cntr);
rootfs_store_unlock();
return container_id;
}
static inline int get_data_dir(const char *id, char *path, size_t len)
{
int nret = snprintf(path, len, "%s/%s", g_rootfs_store->dir, id);
return (nret < 0 || (size_t)nret >= len) ? -1 : 0;
}
static int remove_rootfs_from_memory(const char *id)
{
struct linked_list *item = NULL;
......@@ -922,14 +953,14 @@ static int remove_rootfs_from_memory(const char *id)
goto out;
}
if (!map_remove(g_rootfs_store->bylayer, cntr->scontainer->layer)) {
if (!map_remove(g_rootfs_store->bylayer, cntr->srootfs->layer)) {
ERROR("Failed to remove rootfs from layers map in rootfs store");
ret = -1;
goto out;
}
for (; i < cntr->scontainer->names_len; i++) {
if (!map_remove(g_rootfs_store->byname, (void *)cntr->scontainer->names[i])) {
for (; i < cntr->srootfs->names_len; i++) {
if (!map_remove(g_rootfs_store->byname, (void *)cntr->srootfs->names[i])) {
ERROR("Failed to remove rootfs from names index in rootfs store");
ret = -1;
goto out;
......@@ -938,7 +969,7 @@ static int remove_rootfs_from_memory(const char *id)
linked_list_for_each_safe(item, &(g_rootfs_store->rootfs_list), next) {
cntrootfs_t *tmp = (cntrootfs_t *)item->elem;
if (strcmp(tmp->scontainer->id, id) != 0) {
if (strcmp(tmp->srootfs->id, id) != 0) {
continue;
}
linked_list_del(item);
......@@ -986,7 +1017,7 @@ int rootfs_store_delete(const char *id)
return -1;
}
if (!rootfs_store_lock(true)) {
if (!rootfs_store_lock(EXCLUSIVE)) {
ERROR("Failed to lock rootfs store");
ret = -1;
goto out;
......@@ -999,13 +1030,13 @@ int rootfs_store_delete(const char *id)
goto out;
}
if (remove_rootfs_from_memory(cntr->scontainer->id) != 0) {
if (remove_rootfs_from_memory(cntr->srootfs->id) != 0) {
ERROR("Failed to remove rootfs from memory");
ret = -1;
goto out;
}
if (remove_rootfs_dir(cntr->scontainer->id) != 0) {
if (remove_rootfs_dir(cntr->srootfs->id) != 0) {
ERROR("Failed to delete rootfs directory");
ret = -1;
goto out;
......@@ -1038,13 +1069,13 @@ static int delete_rootfs_from_store_without_lock(const char *id)
return -1;
}
if (remove_rootfs_from_memory(cntr->scontainer->id) != 0) {
if (remove_rootfs_from_memory(cntr->srootfs->id) != 0) {
ERROR("Failed to remove rootfs from memory");
ret = -1;
goto out;
}
if (remove_rootfs_dir(cntr->scontainer->id) != 0) {
if (remove_rootfs_dir(cntr->srootfs->id) != 0) {
ERROR("Failed to delete rootfs directory");
ret = -1;
goto out;
......@@ -1068,13 +1099,13 @@ int rootfs_store_wipe()
return -1;
}
if (!rootfs_store_lock(true)) {
if (!rootfs_store_lock(EXCLUSIVE)) {
ERROR("Failed to lock rootfs store, not allowed to delete rootfs");
ret = -1;
}
linked_list_for_each_safe(item, &(g_rootfs_store->rootfs_list), next) {
id = util_strdup_s(((cntrootfs_t *)item->elem)->scontainer->id);
id = util_strdup_s(((cntrootfs_t *)item->elem)->srootfs->id);
if (delete_rootfs_from_store_without_lock(id) != 0) {
ERROR("Failed to delete rootfs: %s", id);
ret = -1;
......@@ -1090,63 +1121,704 @@ out:
return ret;
}
int rootfs_store_set_big_data(const char *id, const char *key, const char *data)
static bool get_value_from_json_map_string_int64(json_map_string_int64 *map, const char *key, int64_t *value)
{
return 0;
}
size_t i;
int rootfs_store_set_names(const char *id, const char **names, size_t names_len)
{
return 0;
}
for (i = 0; i < map->len; i++) {
if (strcmp(key, map->keys[i]) == 0) {
*value = map->values[i];
return true;
}
}
int rootfs_store_set_metadata(const char *id, const char *metadata)
{
return 0;
return false;
}
int rootfs_store_save(cntrootfs_t *c)
static char *get_value_from_json_map_string_string(json_map_string_string *map, const char *key)
{
return 0;
}
size_t i;
bool rootfs_store_exists(const char *id)
{
return false;
}
if (map == NULL) {
return NULL;
}
storage_rootfs *rootfs_store_get_rootfs(const char *id)
{
return NULL;
}
for (i = 0; i < map->len; i++) {
if (strcmp(key, map->keys[i]) == 0) {
return util_strdup_s(map->values[i]);
}
}
char *rootfs_store_big_data(const char *id, const char *key)
{
return NULL;
}
int64_t rootfs_store_big_data_size(const char *id, const char *key)
static int append_big_data_name(storage_rootfs *rootfs, const char *name)
{
return -1;
size_t new_size, old_size;
char **tmp_names = NULL;
if (name == NULL) {
return 0;
}
old_size = rootfs->big_data_names_len * sizeof(char *);
new_size = old_size + sizeof(char *);
if (mem_realloc((void **)&tmp_names, new_size, (void *)rootfs->big_data_names, old_size) != 0) {
ERROR("Failed to realloc memory");
return -1;
}
rootfs->big_data_names = tmp_names;
rootfs->big_data_names[rootfs->big_data_names_len++] = util_strdup_s(name);
return 0;
}
char *rootfs_store_big_data_digest(const char *id, const char *key)
static int update_rootfs_with_big_data(cntrootfs_t *img, const char *key, const char *data, bool *should_save)
{
return NULL;
}
int ret = 0;
size_t i;
bool size_found = false;
bool add_name = true;
int64_t old_size;
char *old_digest = NULL;
char *new_digest = NULL;
char *full_digest = NULL;
if (img->srootfs->big_data_sizes == NULL) {
img->srootfs->big_data_sizes = (json_map_string_int64 *)util_common_calloc_s(sizeof(json_map_string_int64));
if (img->srootfs->big_data_sizes == NULL) {
ERROR("Out of memory");
return -1;
}
}
int rootfs_store_big_data_names(const char *id, char ***names, size_t *names_len)
size_found = get_value_from_json_map_string_int64(img->srootfs->big_data_sizes, key, &old_size);
append_json_map_string_int64(img->srootfs->big_data_sizes, key, (int64_t)strlen(data));
if (img->srootfs->big_data_digests == NULL) {
img->srootfs->big_data_digests = (json_map_string_string *)util_common_calloc_s(sizeof(json_map_string_string));
if (img->srootfs->big_data_digests == NULL) {
ERROR("Out of memory");
return -1;
}
}
old_digest = get_value_from_json_map_string_string(img->srootfs->big_data_digests, key);
new_digest = sha256_digest_str(data);
full_digest = util_full_digest(new_digest);
append_json_map_string_string(img->srootfs->big_data_digests, key, full_digest);
if (!size_found || old_size != (int64_t)strlen(data) ||
old_digest == NULL || strcmp(old_digest, full_digest) != 0) {
*should_save = true;
}
for (i = 0; i < img->srootfs->big_data_names_len; i++) {
if (strcmp(img->srootfs->big_data_names[i], key) == 0) {
add_name = false;
break;
}
}
if (add_name) {
if (append_big_data_name(img->srootfs, key) != 0) {
ERROR("Failed to append big data name");
ret = -1;
goto out;
}
*should_save = true;
}
out:
free(old_digest);
free(new_digest);
free(full_digest);
return ret;
}
int rootfs_store_set_big_data(const char *id, const char *key, const char *data)
{
return 0;
int ret = 0;
cntrootfs_t *cntr = NULL;
const char *rootfs_id = NULL;
char rootfs_dir[PATH_MAX] = { 0x00 };
char big_data_file[PATH_MAX] = { 0x00 };
bool save = false;
if (key == NULL || strlen(key) == 0) {
ERROR("Not a valid name for a big data item, can't set empty name for rootfs big data item");
return -1;
}
if (g_rootfs_store == NULL) {
ERROR("Rootfs store is not ready");
return -1;
}
if (!rootfs_store_lock(EXCLUSIVE)) {
ERROR("Failed to lock rootfs store with exclusive lock, not allowed to change rootfs big data assignments");
ret = -1;
goto out;
}
cntr = lookup(id);
if (cntr == NULL) {
ERROR("Failed to lookup rootfs from store");
ret = -1;
goto out;
}
rootfs_id = cntr->srootfs->id;
if (get_data_dir(rootfs_id, rootfs_dir, sizeof(rootfs_dir)) != 0) {
ERROR("Failed to get rootfs data dir: %s", id);
ret = -1;
goto out;
}
ret = util_mkdir_p(rootfs_dir, IMAGE_STORE_PATH_MODE);
if (ret < 0) {
ERROR("Unable to create directory %s.", rootfs_dir);
ret = -1;
goto out;
}
if (get_data_path(rootfs_id, key, big_data_file, sizeof(big_data_file)) != 0) {
ERROR("Failed to get big data file path: %s.", key);
ret = -1;
goto out;
}
if (util_atomic_write_file(big_data_file, data, strlen(data), SECURE_CONFIG_FILE_MODE) != 0) {
ERROR("Failed to save big data file: %s", big_data_file);
ret = -1;
goto out;
}
if (update_rootfs_with_big_data(cntr, key, data, &save) != 0) {
ERROR("Failed to update rootfs big data");
ret = -1;
goto out;
}
if (save && save_rootfs(cntr) != 0) {
ERROR("Failed to complete persistence to disk");
ret = -1;
goto out;
}
out:
rootfs_ref_dec(cntr);
rootfs_store_unlock();
return ret;
}
char *rootfs_store_metadata(const char *id)
int rootfs_store_set_names(const char *id, const char **names, size_t names_len)
{
return NULL;
int ret = 0;
cntrootfs_t *cntr = NULL;
cntrootfs_t *other_cntr = NULL;
char **unique_names = NULL;
size_t unique_names_len = 0;
size_t i;
if (id == NULL) {
ERROR("Invalid paratemer, id is NULL");
return -1;
}
if (names == NULL || names_len == 0) {
ERROR("Cannot leave the rootfs name empty");
return -1;
}
if (g_rootfs_store == NULL) {
ERROR("Container store is not ready");
return -1;
}
if (!rootfs_store_lock(EXCLUSIVE)) {
ERROR("Failed to lock rootfs store with exclusive lock, not allowed to change rootfs names assignments");
return -1;
}
cntr = lookup(id);
if (cntr == NULL) {
ERROR("Rootfs not known");
ret = -1;
goto out;
}
if (util_string_array_unique((const char **)names, names_len, &unique_names, &unique_names_len) != 0) {
ERROR("Failed to unique names");
ret = -1;
goto out;
}
for (i = 0; i < cntr->srootfs->names_len; i++) {
if (!map_remove(g_rootfs_store->byname, (void *)cntr->srootfs->names[i])) {
ERROR("Failed to remove rootfs from ids map in rootfs store : %s", cntr->srootfs->names[i]);
ret = -1;
goto out;
}
}
for (i = 0; i < unique_names_len; i++) {
other_cntr = (cntrootfs_t *)map_search(g_rootfs_store->byname, (void *)unique_names[i]);
if (other_cntr != NULL && remove_name(other_cntr, unique_names[i]) != 0) {
ERROR("Failed to remove name from other container rootfs");
ret = -1;
goto out;
}
if (!map_replace(g_rootfs_store->byname, unique_names[i], (void *)cntr)) {
ERROR("Failed to update byname map in rootfs store");
ret = -1;
goto out;
}
}
util_free_array_by_len(cntr->srootfs->names, cntr->srootfs->names_len);
cntr->srootfs->names = unique_names;
cntr->srootfs->names_len = unique_names_len;
unique_names = NULL;
unique_names_len = 0;
if (save_rootfs(cntr) != 0) {
ERROR("Failed to update container");
ret = -1;
goto out;
}
out:
util_free_array_by_len(unique_names, unique_names_len);
rootfs_ref_dec(cntr);
rootfs_store_unlock();
return ret;
}
int rootfs_store_get_all_rootfs(struct rootfs_list *all_rootfs)
int rootfs_store_set_metadata(const char *id, const char *metadata)
{
return 0;
int ret = 0;
cntrootfs_t *cntr = NULL;
if (id == NULL || metadata == NULL) {
ERROR("Invalid paratemer: id(%s), metadata(%s)", id, metadata);
return -1;
}
if (g_rootfs_store == NULL) {
ERROR("Container store is not ready");
return -1;
}
if (!rootfs_store_lock(EXCLUSIVE)) {
ERROR("Failed to lock rootfs store with exclusive lock, not allowed to modify rootfs metadata");
return -1;
}
cntr = lookup(id);
if (cntr == NULL) {
ERROR("Rootfs not known");
ret = -1;
goto out;
}
free(cntr->srootfs->metadata);
cntr->srootfs->metadata = util_strdup_s(metadata);
if (save_rootfs(cntr) != 0) {
ERROR("Failed to save container rootfs");
ret = -1;
goto out;
}
out:
rootfs_ref_dec(cntr);
rootfs_store_unlock();
return ret;
}
int rootfs_store_save(cntrootfs_t *c)
{
int ret = 0;
if (c == NULL) {
ERROR("Invalid parameter, container rootfs is NULL");
return -1;
}
if (g_rootfs_store == NULL) {
ERROR("Rootfs store is not ready");
return -1;
}
if (!rootfs_store_lock(SHARED)) {
ERROR("Failed to lock rootfs store with shared lock, not allowed to save rootfs");
return -1;
}
ret = save_rootfs(c);
rootfs_store_unlock();
return ret;
}
bool rootfs_store_exists(const char *id)
{
bool ret = true;
cntrootfs_t *cntr = NULL;
if (id == NULL) {
ERROR("Invalid paratemer, id is NULL");
return false;
}
if (g_rootfs_store == NULL) {
ERROR("Rootfs store is not ready");
return false;
}
if (!rootfs_store_lock(SHARED)) {
ERROR("Failed to lock rootfs store with shared lock, not allowed to get rootfs exist info");
return false;
}
cntr = lookup(id);
if (cntr == NULL) {
ERROR("Rootfs not known");
ret = false;
goto out;
}
out:
rootfs_ref_dec(cntr);
rootfs_store_unlock();
return ret;
}
static storage_rootfs *copy_rootfs(const storage_rootfs *rootfs)
{
char *json = NULL;
parser_error err = NULL;
storage_rootfs *ans = NULL;
if (rootfs == NULL) {
return NULL;
}
json = storage_rootfs_generate_json(rootfs, NULL, &err);
if (json == NULL) {
ERROR("Failed to generate json: %s", err);
goto out;
}
ans = storage_rootfs_parse_data(json, NULL, &err);
if (ans == NULL) {
ERROR("Failed to parse json: %s", err);
goto out;
}
out:
free(err);
free(json);
return ans;
}
storage_rootfs *rootfs_store_get_rootfs(const char *id)
{
cntrootfs_t *cntr = NULL;
storage_rootfs *dup_rootfs = NULL;
if (id == NULL) {
ERROR("Invalid parameter, id is NULL");
return NULL;
}
if (g_rootfs_store == NULL) {
ERROR("Rootfs store is not ready");
return NULL;
}
if (!rootfs_store_lock(SHARED)) {
ERROR("Failed to rootfs store with shared lock, not allowed to get rootfs from store");
return NULL;
}
cntr = lookup(id);
if (cntr == NULL) {
ERROR("Rootfs not known");
goto out;
}
dup_rootfs = copy_rootfs(cntr->srootfs);
out:
rootfs_ref_dec(cntr);
rootfs_store_unlock();
return dup_rootfs;
}
char *rootfs_store_big_data(const char *id, const char *key)
{
int ret = 0;
cntrootfs_t *cntr = NULL;
size_t filesize;
char filename[PATH_MAX] = { 0x00 };
char *content = NULL;
if (id == NULL) {
ERROR("Invalid parameter, id is NULL");
return NULL;
}
if (key == NULL || strlen(key) == 0) {
ERROR("Not a valid name for a big data item, can't retrieve rootfs big data value for empty name");
return NULL;
}
if (g_rootfs_store == NULL) {
ERROR("Rootfs store is not read");
return NULL;
}
if (!rootfs_store_lock(SHARED)) {
ERROR("Failed to lock rootfs store with shared lock, not allowed to get rootfs big data");
return NULL;
}
cntr = lookup(id);
if (cntr == NULL) {
ERROR("Rootfs not known");
goto out;
}
ret = get_data_path(cntr->srootfs->id, key, filename, sizeof(filename));
if (ret != 0) {
ERROR("Failed to get big data file path: %s.", key);
goto out;
}
content = read_file(filename, &filesize);
out:
rootfs_ref_dec(cntr);
rootfs_store_unlock();
return content;
}
static int get_size_with_update_big_data(const char *id, const char *key, int64_t *size)
{
int ret = 0;
cntrootfs_t *cntr = NULL;
char *data = NULL;
data = rootfs_store_big_data(id, key);
if (data == NULL) {
return -1;
}
if (rootfs_store_set_big_data(id, key, data) != 0) {
free(data);
return -1;
}
free(data);
if (!rootfs_store_lock(SHARED)) {
ERROR("Failed to lock rootfs store with shared lock, not allowed to get rootfs big data size assignments");
return -1;
}
cntr = lookup(id);
if (cntr == NULL) {
ERROR("Rootfs not known");
ret = -1;
goto out;
}
(void)get_value_from_json_map_string_int64(cntr->srootfs->big_data_sizes, key, size);
out:
rootfs_ref_dec(cntr);
rootfs_store_unlock();
return ret;
}
int64_t rootfs_store_big_data_size(const char *id, const char *key)
{
bool bret = false;
cntrootfs_t *cntr = NULL;
int64_t size = -1;
if (id == NULL) {
ERROR("Invalid parameter, id is NULL");
return -1;
}
if (key == NULL || strlen(key) == 0) {
ERROR("Not a valid name for a big data item, can't retrieve rootfs big data value for empty name");
return -1;
}
if (g_rootfs_store == NULL) {
ERROR("Rootfs store is not ready");
return -1;
}
if (!rootfs_store_lock(SHARED)) {
ERROR("Failed to lock rootfs store with shared lock, not allowed to get rootfs big data size assignments");
return -1;
}
cntr = lookup(id);
if (cntr == NULL) {
ERROR("Rootfs not known");
goto out;
}
bret = get_value_from_json_map_string_int64(cntr->srootfs->big_data_sizes, key, &size);
rootfs_ref_dec(cntr);
if (bret || get_size_with_update_big_data(id, key, &size) == 0) {
goto out;
}
ERROR("Size is not known");
out:
rootfs_store_unlock();
return size;
}
char *rootfs_store_big_data_digest(const char *id, const char *key)
{
return NULL;
}
int rootfs_store_big_data_names(const char *id, char ***names, size_t *names_len)
{
int ret = 0;
cntrootfs_t *cntr = NULL;
if (id == NULL) {
ERROR("Invalid parameter, id is NULL");
return -1;
}
if (g_rootfs_store == NULL) {
ERROR("Rootfs store is not ready");
return -1;
}
if (!rootfs_store_lock(SHARED)) {
ERROR("Failed to lock rootfs store with shared lock, not allowed to get rootfs big data names assignments");
return -1;
}
cntr = lookup(id);
if (cntr == NULL) {
ERROR("Rootfs not known");
ret = -1;
goto out;
}
if (dup_array_of_strings((const char **)cntr->srootfs->big_data_names, cntr->srootfs->big_data_names_len, names,
names_len) != 0) {
ERROR("Failed to dup rootfs's names");
ret = -1;
goto out;
}
out:
rootfs_ref_dec(cntr);
rootfs_store_unlock();
return ret;
}
char *rootfs_store_metadata(const char *id)
{
cntrootfs_t *img = NULL;
char *metadata = NULL;
if (id == NULL) {
ERROR("Invalid parameter, id is NULL");
return NULL;
}
if (g_rootfs_store == NULL) {
ERROR("Rootfs store is not ready");
return NULL;
}
if (!rootfs_store_lock(SHARED)) {
ERROR("Failed to lock rootfs store with shared lock, not allowed to get rootfs metadata assignments");
return NULL;
}
img = lookup(id);
if (img == NULL) {
ERROR("Rootfs not known");
goto out;
}
metadata = util_strdup_s(img->srootfs->metadata);
out:
rootfs_ref_dec(img);
rootfs_store_unlock();
return metadata;
}
int rootfs_store_get_all_rootfs(struct rootfs_list *all_rootfs)
{
int ret = 0;
struct linked_list *item = NULL;
struct linked_list *next = NULL;
if (all_rootfs == NULL) {
ERROR("Invalid input paratemer, memory should be allocated first");
return -1;
}
if (g_rootfs_store == NULL) {
ERROR("Rootfs store is not already!");
return -1;
}
if (!rootfs_store_lock(SHARED)) {
ERROR("Failed to lock rootfs store with shared lock, not allowed to get all the known rootfss");
return -1;
}
if (g_rootfs_store->rootfs_list_len == 0) {
goto out;
}
all_rootfs->rootfs = util_common_calloc_s(g_rootfs_store->rootfs_list_len * sizeof(storage_rootfs *));
if (all_rootfs->rootfs == NULL) {
ERROR("Out of memory");
ret = -1;
goto out;
}
linked_list_for_each_safe(item, &(g_rootfs_store->rootfs_list), next) {
storage_rootfs *tmp_rootfs = NULL;
cntrootfs_t *img = (cntrootfs_t *)item->elem;
tmp_rootfs = copy_rootfs(img->srootfs);
if (tmp_rootfs == NULL) {
ERROR("Failed to copy container rootfs");
ret = -1;
goto out;
}
all_rootfs->rootfs[all_rootfs->rootfs_len++] = tmp_rootfs;
tmp_rootfs = NULL;
}
out:
rootfs_store_unlock();
return ret;
}
......@@ -20,6 +20,7 @@
#include <stddef.h>
#include "types_def.h"
#include "storage_image.h"
#include "storage_rootfs.h"
#include "imagetool_images_list.h"
#include "imagetool_fs_info.h"
......@@ -46,7 +47,7 @@ struct layer_list {
};
struct rootfs_list {
struct storage_rootfs **rootfs;
storage_rootfs **rootfs;
size_t rootfs_len;
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册