517 lines
15 KiB
Diff
517 lines
15 KiB
Diff
From 4527dc8b6f7ab438742a8f7403b24420f646236d Mon Sep 17 00:00:00 2001
|
|
From: liuxu <liuxu156@huawei.com>
|
|
Date: Mon, 8 Apr 2024 11:57:16 +0800
|
|
Subject: [PATCH 61/69] cdi:support modules operate/registry/annotations
|
|
|
|
---
|
|
.../modules/device/cdi/cdi_annotations.c | 72 +++++++
|
|
src/daemon/modules/device/cdi/cdi_registry.c | 14 +-
|
|
src/daemon/modules/device/cdi_operate.c | 53 +++++-
|
|
src/utils/cutils/utils.c | 11 ++
|
|
src/utils/cutils/utils.h | 2 +
|
|
src/utils/cutils/utils_array.c | 175 +++++++++++++++++-
|
|
src/utils/cutils/utils_array.h | 31 ++++
|
|
7 files changed, 350 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/src/daemon/modules/device/cdi/cdi_annotations.c b/src/daemon/modules/device/cdi/cdi_annotations.c
|
|
index cfe6e099..020816d7 100644
|
|
--- a/src/daemon/modules/device/cdi/cdi_annotations.c
|
|
+++ b/src/daemon/modules/device/cdi/cdi_annotations.c
|
|
@@ -21,12 +21,84 @@
|
|
|
|
#include "error.h"
|
|
#include "utils.h"
|
|
+#include "utils_array.h"
|
|
#include "cdi_parser.h"
|
|
|
|
#define CDI_ANNOTATIONS_PREFIX "cdi.k8s.io/"
|
|
|
|
+static int parse_devices(string_array *devices, const char *value, char **error)
|
|
+{
|
|
+ __isula_auto_array_t char **parts = NULL;
|
|
+ char **pos;
|
|
+
|
|
+ parts = util_string_split(value, ',');
|
|
+ if (parts == NULL) {
|
|
+ ERROR("Invalid CDI device value %s", value);
|
|
+ format_errorf(error, "Invalid CDI device value %s", value);
|
|
+ return -1;
|
|
+ }
|
|
+ for (pos = parts; pos != NULL && *pos != NULL; pos++) {
|
|
+ if (!cdi_parser_is_qualified_name(*pos)) {
|
|
+ ERROR("Invalid CDI device name %s", *pos);
|
|
+ format_errorf(error, "Invalid CDI device name %s", *pos);
|
|
+ return -1;
|
|
+ }
|
|
+ if (util_append_string_array(devices, *pos) != 0) {
|
|
+ ERROR("Out of memory");
|
|
+ *error = util_strdup_s("Out of memory");
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int cdi_parse_annotations(json_map_string_string *annotations, string_array **keys,
|
|
string_array **devices, char **error)
|
|
{
|
|
+ char *key = NULL;
|
|
+ char *value = NULL;
|
|
+ size_t i;
|
|
+ __isula_auto_string_array_t string_array *keys_array = NULL;
|
|
+ __isula_auto_string_array_t string_array *devices_array = NULL;
|
|
+
|
|
+ if (annotations == NULL || keys == NULL || devices == NULL || error == NULL) {
|
|
+ ERROR("Invalid argument");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ keys_array = util_common_calloc_s(sizeof(*keys_array));
|
|
+ if (keys_array == NULL) {
|
|
+ ERROR("Out of memory");
|
|
+ *error = util_strdup_s("Out of memory");
|
|
+ return -1;
|
|
+ }
|
|
+ devices_array = util_common_calloc_s(sizeof(*devices_array));
|
|
+ if (devices_array == NULL) {
|
|
+ ERROR("Out of memory");
|
|
+ *error = util_strdup_s("Out of memory");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < annotations->len; i++) {
|
|
+ key = annotations->keys[i];
|
|
+ value = annotations->values[i];
|
|
+ if (!util_has_prefix(key, CDI_ANNOTATIONS_PREFIX)) {
|
|
+ continue;
|
|
+ }
|
|
+ if (parse_devices(devices_array, value, error) != 0) {
|
|
+ return -1;
|
|
+ }
|
|
+ if (util_append_string_array(keys_array, key) != 0) {
|
|
+ ERROR("Out of memory");
|
|
+ *error = util_strdup_s("Out of memory");
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ *keys = keys_array;
|
|
+ keys_array = NULL;
|
|
+ *devices = devices_array;
|
|
+ devices_array = NULL;
|
|
return 0;
|
|
}
|
|
diff --git a/src/daemon/modules/device/cdi/cdi_registry.c b/src/daemon/modules/device/cdi/cdi_registry.c
|
|
index 68767a5f..be381132 100644
|
|
--- a/src/daemon/modules/device/cdi/cdi_registry.c
|
|
+++ b/src/daemon/modules/device/cdi/cdi_registry.c
|
|
@@ -14,12 +14,24 @@
|
|
******************************************************************************/
|
|
#include "cdi_registry.h"
|
|
|
|
+#include <util_atomic.h>
|
|
+#include <isula_libutils/auto_cleanup.h>
|
|
+
|
|
+static struct cdi_registry g_cdi_reg = { 0 };
|
|
+
|
|
int cdi_registry_init(string_array *spec_dirs)
|
|
{
|
|
+ // isulad will use default dirs when spec_dirs == NULL
|
|
+ g_cdi_reg.cdi_cache = cdi_new_cache(spec_dirs);
|
|
+ if (g_cdi_reg.cdi_cache == NULL) {
|
|
+ ERROR("Failed to init registry");
|
|
+ return -1;
|
|
+ }
|
|
+ g_cdi_reg.ops = cdi_get_cache_ops();
|
|
return 0;
|
|
}
|
|
|
|
struct cdi_registry *cdi_get_registry(void)
|
|
{
|
|
- return NULL;
|
|
+ return &g_cdi_reg;
|
|
}
|
|
diff --git a/src/daemon/modules/device/cdi_operate.c b/src/daemon/modules/device/cdi_operate.c
|
|
index c5187ab1..f99bb7e4 100644
|
|
--- a/src/daemon/modules/device/cdi_operate.c
|
|
+++ b/src/daemon/modules/device/cdi_operate.c
|
|
@@ -14,23 +14,66 @@
|
|
******************************************************************************/
|
|
#include "cdi_operate_api.h"
|
|
|
|
+#include <isula_libutils/log.h>
|
|
+
|
|
+#include "utils.h"
|
|
+#include "error.h"
|
|
+#include "cdi_registry.h"
|
|
+#include "cdi_annotations.h"
|
|
+#include "cdi_spec_dirs.h"
|
|
+
|
|
int cdi_operate_registry_init(char **specs_dirs, size_t specs_dirs_len)
|
|
{
|
|
- return 0;
|
|
+ string_array spec_dirs_array = {
|
|
+ .items = specs_dirs,
|
|
+ .len = specs_dirs_len,
|
|
+ .cap = specs_dirs_len,
|
|
+ };
|
|
+
|
|
+ return cdi_registry_init(&spec_dirs_array);
|
|
}
|
|
|
|
int cdi_operate_refresh(void)
|
|
{
|
|
- return 0;
|
|
+ struct cdi_registry *registry = cdi_get_registry();
|
|
+ if (registry == NULL || registry->ops == NULL || registry->ops->refresh == NULL) {
|
|
+ ERROR("Failed to get registry");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return registry->ops->refresh(registry->cdi_cache);
|
|
}
|
|
|
|
int cdi_operate_inject_devices(oci_runtime_spec *spec, string_array *devices)
|
|
{
|
|
- return 0;
|
|
+ struct cdi_registry *registry = NULL;
|
|
+
|
|
+ if (spec == NULL || devices == NULL) {
|
|
+ ERROR("Invalid params");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ registry = cdi_get_registry();
|
|
+ if (registry == NULL || registry->ops == NULL || registry->ops->inject_devices == NULL) {
|
|
+ ERROR("Failed to get registry");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return registry->ops->inject_devices(registry->cdi_cache, spec, devices);
|
|
}
|
|
|
|
int cdi_operate_parse_annotations(json_map_string_string *annotations, string_array **keys,
|
|
string_array **devices, char **error)
|
|
{
|
|
- return 0;
|
|
-}
|
|
\ No newline at end of file
|
|
+ if (error == NULL) {
|
|
+ ERROR("Invalid argument");
|
|
+ return -1;
|
|
+ }
|
|
+ if (annotations == NULL || keys == NULL || devices == NULL) {
|
|
+ ERROR("Invalid params");
|
|
+ *error = util_strdup_s("Invalid params");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return cdi_parse_annotations(annotations, keys, devices, error);
|
|
+}
|
|
diff --git a/src/utils/cutils/utils.c b/src/utils/cutils/utils.c
|
|
index 8da2cc60..9a33f935 100644
|
|
--- a/src/utils/cutils/utils.c
|
|
+++ b/src/utils/cutils/utils.c
|
|
@@ -59,6 +59,17 @@ int malloc_trim(size_t pad)
|
|
}
|
|
#endif
|
|
|
|
+void util_swap_ptr(void **p1, void **p2)
|
|
+{
|
|
+ void *tmp;
|
|
+ if (p1 == NULL || p2 == NULL) {
|
|
+ return;
|
|
+ }
|
|
+ tmp = *p1;
|
|
+ *p1 = *p2;
|
|
+ *p2 = tmp;
|
|
+}
|
|
+
|
|
int util_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize)
|
|
{
|
|
void *tmp = NULL;
|
|
diff --git a/src/utils/cutils/utils.h b/src/utils/cutils/utils.h
|
|
index 3acf0698..3671272a 100644
|
|
--- a/src/utils/cutils/utils.h
|
|
+++ b/src/utils/cutils/utils.h
|
|
@@ -320,6 +320,8 @@ struct signame {
|
|
} \
|
|
} while (0)
|
|
|
|
+void util_swap_ptr(void **p1, void **p2);
|
|
+
|
|
int util_mem_realloc(void **newptr, size_t newsize, void *oldptr, size_t oldsize);
|
|
|
|
int util_check_inherited(bool closeall, int fd_to_ignore);
|
|
diff --git a/src/utils/cutils/utils_array.c b/src/utils/cutils/utils_array.c
|
|
index 25f19b8b..72294005 100644
|
|
--- a/src/utils/cutils/utils_array.c
|
|
+++ b/src/utils/cutils/utils_array.c
|
|
@@ -86,6 +86,27 @@ void util_free_sensitive_array(char **array)
|
|
free(array);
|
|
}
|
|
|
|
+char **util_copy_array_by_len(char **array, size_t len)
|
|
+{
|
|
+ char **new_array = NULL;
|
|
+ size_t i;
|
|
+
|
|
+ if (array == NULL || len == 0) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ new_array = util_smart_calloc_s(sizeof(char *), len);
|
|
+ if (new_array == NULL) {
|
|
+ ERROR("Out of memory");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < len; i++) {
|
|
+ new_array[i] = util_strdup_s(array[i]);
|
|
+ }
|
|
+ return new_array;
|
|
+}
|
|
+
|
|
int util_array_append(char ***array, const char *element)
|
|
{
|
|
size_t len;
|
|
@@ -166,7 +187,7 @@ bool util_array_contain(const char **array, const char *element)
|
|
return false;
|
|
}
|
|
|
|
-static size_t get_string_array_scale_size(size_t old_size)
|
|
+static size_t get_array_scale_size(size_t old_size)
|
|
{
|
|
#define DOUBLE_THRESHOLD 1024
|
|
const size_t max_threshold = MAX_MEMORY_SIZE / sizeof(char *);
|
|
@@ -188,7 +209,7 @@ static size_t get_string_array_scale_size(size_t old_size)
|
|
|
|
static bool do_expand_array(string_array *array)
|
|
{
|
|
- size_t new_size = get_string_array_scale_size(array->cap);
|
|
+ size_t new_size = get_array_scale_size(array->cap);
|
|
char **new_items = NULL;
|
|
|
|
// array capability sure less than MAX_MEMORY_SIZE
|
|
@@ -237,6 +258,29 @@ out:
|
|
return 0;
|
|
}
|
|
|
|
+string_array *util_copy_string_array(string_array *sarr)
|
|
+{
|
|
+ string_array *ptr = NULL;
|
|
+ size_t i;
|
|
+
|
|
+ if (sarr == NULL) {
|
|
+ ERROR("Invalid string array");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ ptr = util_string_array_new(sarr->cap);
|
|
+ if (ptr == NULL) {
|
|
+ ERROR("Out of memory");
|
|
+ return NULL;
|
|
+ }
|
|
+ for (i = 0; i < sarr->len; i++) {
|
|
+ ptr->items[i] = util_strdup_s(sarr->items[i]);
|
|
+ ptr->len += 1;
|
|
+ }
|
|
+
|
|
+ return ptr;
|
|
+}
|
|
+
|
|
bool util_string_array_contain(const string_array *sarr, const char *elem)
|
|
{
|
|
size_t i;
|
|
@@ -339,3 +383,130 @@ int util_common_array_append_pointer(void ***array, void *element)
|
|
|
|
return 0;
|
|
}
|
|
+
|
|
+void *util_clone_ptr(void *item)
|
|
+{
|
|
+ return item;
|
|
+}
|
|
+
|
|
+common_array *util_common_array_new(size_t len, free_common_array_item_cb free_item_cb,
|
|
+ clone_common_array_item_cb clone_item_cb)
|
|
+{
|
|
+ common_array *ptr = NULL;
|
|
+
|
|
+ if (len == 0 || free_item_cb == NULL || clone_item_cb == NULL) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ ptr = (common_array *)util_common_calloc_s(sizeof(common_array));
|
|
+ if (ptr == NULL) {
|
|
+ ERROR("Out of memory");
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ ptr->items = (void **)util_smart_calloc_s(sizeof(void *), len);
|
|
+ if (ptr->items == NULL) {
|
|
+ ERROR("Out of memory");
|
|
+ free(ptr);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ ptr->len = 0;
|
|
+ ptr->cap = len;
|
|
+ ptr->free_item_cb = free_item_cb;
|
|
+ ptr->clone_item_cb = clone_item_cb;
|
|
+
|
|
+ return ptr;
|
|
+}
|
|
+
|
|
+void util_free_common_array(common_array *ptr)
|
|
+{
|
|
+ size_t i;
|
|
+
|
|
+ if (ptr == NULL || ptr->free_item_cb == NULL) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < ptr->len; i++) {
|
|
+ ptr->free_item_cb(ptr->items[i]);
|
|
+ ptr->items[i] = NULL;
|
|
+ }
|
|
+ free(ptr->items);
|
|
+ ptr->items = NULL;
|
|
+ ptr->len = 0;
|
|
+ ptr->cap = 0;
|
|
+ ptr->free_item_cb = NULL;
|
|
+ ptr->clone_item_cb = NULL;
|
|
+
|
|
+ free(ptr);
|
|
+}
|
|
+
|
|
+static bool do_expand_common_array(common_array *array)
|
|
+{
|
|
+ size_t new_size = get_array_scale_size(array->cap);
|
|
+ void **new_items = NULL;
|
|
+
|
|
+ // array capability sure less than MAX_MEMORY_SIZE
|
|
+ // so we need to check Overflow:
|
|
+ if (new_size == array->cap) {
|
|
+ ERROR("Too large common array, overflow memory");
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ // new_size * sizeof(*new_items) and list->len * sizeof(*list->items)
|
|
+ if (util_mem_realloc((void **)&new_items, new_size * sizeof(void *), (void *)array->items,
|
|
+ array->len * sizeof(void *)) != 0) {
|
|
+ ERROR("Out of memory");
|
|
+ return false;
|
|
+ }
|
|
+ array->items = new_items;
|
|
+ array->cap = new_size;
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+int util_append_common_array(common_array *arr, void *val)
|
|
+{
|
|
+ if (arr == NULL || arr->clone_item_cb == NULL) {
|
|
+ ERROR("Invalid common array");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (val == NULL) {
|
|
+ DEBUG("Empty new item, just ignore it");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (arr->len < arr->cap) {
|
|
+ goto out;
|
|
+ }
|
|
+
|
|
+ // expand common array
|
|
+ if (!do_expand_common_array(arr)) {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+out:
|
|
+ arr->items[arr->len] = arr->clone_item_cb(val);
|
|
+ arr->len += 1;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int util_merge_common_array(common_array *dest_arr, common_array *src_arr)
|
|
+{
|
|
+ size_t i;
|
|
+
|
|
+ if (dest_arr == NULL || dest_arr->clone_item_cb == NULL ||
|
|
+ src_arr == NULL || src_arr->clone_item_cb == NULL) {
|
|
+ ERROR("Invalid common array");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < src_arr->len; i++) {
|
|
+ if (util_append_common_array(dest_arr, src_arr->items[i]) != 0) {
|
|
+ ERROR("Failed to append element");
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
diff --git a/src/utils/cutils/utils_array.h b/src/utils/cutils/utils_array.h
|
|
index 1c084595..0c4fd217 100644
|
|
--- a/src/utils/cutils/utils_array.h
|
|
+++ b/src/utils/cutils/utils_array.h
|
|
@@ -30,6 +30,8 @@ void util_free_array_by_len(char **array, size_t len);
|
|
|
|
void util_free_array(char **array);
|
|
|
|
+char **util_copy_array_by_len(char **array, size_t len);
|
|
+
|
|
int util_grow_array(char ***orig_array, size_t *orig_capacity, size_t size,
|
|
size_t increment);
|
|
|
|
@@ -52,6 +54,8 @@ void util_free_string_array(string_array *ptr);
|
|
|
|
int util_append_string_array(string_array *sarr, const char *val);
|
|
|
|
+string_array *util_copy_string_array(string_array *sarr);
|
|
+
|
|
bool util_string_array_contain(const string_array *sarr, const char *elem);
|
|
|
|
void util_free_sensitive_array(char **array);
|
|
@@ -63,6 +67,33 @@ define_auto_cleanup_callback(util_free_array, char *);
|
|
// define auto free macro for char *
|
|
#define __isula_auto_array_t auto_cleanup_tag(util_free_array)
|
|
|
|
+define_auto_cleanup_callback(util_free_string_array, string_array);
|
|
+#define __isula_auto_string_array_t auto_cleanup_tag(util_free_string_array)
|
|
+
|
|
+typedef void (*free_common_array_item_cb)(void *item);
|
|
+typedef void *(*clone_common_array_item_cb)(void *item);
|
|
+typedef struct common_array_t {
|
|
+ void **items;
|
|
+ size_t len;
|
|
+ size_t cap;
|
|
+ free_common_array_item_cb free_item_cb;
|
|
+ clone_common_array_item_cb clone_item_cb;
|
|
+} common_array;
|
|
+
|
|
+void *util_clone_ptr(void *item);
|
|
+
|
|
+common_array *util_common_array_new(size_t len, free_common_array_item_cb free_item_cb,
|
|
+ clone_common_array_item_cb clone_item_cb);
|
|
+
|
|
+void util_free_common_array(common_array *ptr);
|
|
+
|
|
+int util_append_common_array(common_array *arr, void *val);
|
|
+
|
|
+int util_merge_common_array(common_array *dest_arr, common_array *src_arr);
|
|
+
|
|
+define_auto_cleanup_callback(util_free_common_array, common_array);
|
|
+#define __isula_auto_common_array_t auto_cleanup_tag(util_free_common_array)
|
|
+
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
--
|
|
2.34.1
|
|
|