Define memhead list inside bbf context structure

This commit is contained in:
Amin Ben Romdhane 2024-03-18 15:31:20 +00:00
parent f9de22032b
commit 7997de62b7
9 changed files with 333 additions and 79 deletions

View file

@ -16,7 +16,7 @@
#include "plugin/json_plugin.h"
extern struct list_head global_memhead;
static LIST_HEAD(plugin_mem);
static uint8_t find_number_of_objects(DM_MAP_OBJ *dynamic_obj)
{
@ -43,6 +43,8 @@ int load_dotso_plugin(void **lib_handle, const char *file_path, DMOBJ **main_ent
return -1;
}
dm_dynamic_initmem(&plugin_mem);
*lib_handle = handle;
//Dynamic Object
@ -55,14 +57,14 @@ int load_dotso_plugin(void **lib_handle, const char *file_path, DMOBJ **main_ent
return -1;
}
DMOBJ *dm_entryobj = (DMOBJ *)dm_dynamic_calloc(&global_memhead, obj_num + 1, sizeof(DMOBJ));
DMOBJ *dm_entryobj = (DMOBJ *)dm_dynamic_calloc(&plugin_mem, obj_num + 1, sizeof(DMOBJ));
if (dm_entryobj == NULL) {
ERR("No Memory exists\n");
return -1;
}
for (int i = 0; dynamic_obj[i].path; i++) {
char *node_obj = dm_dynamic_strdup(&global_memhead, dynamic_obj[i].path);
char *node_obj = dm_dynamic_strdup(&plugin_mem, dynamic_obj[i].path);
unsigned int len = strlen(node_obj);
if (strncmp(node_obj, ROOT_NODE, strlen(ROOT_NODE)) != 0 || node_obj[len-1] != '.') {
@ -93,6 +95,7 @@ int free_dotso_plugin(void *lib_handle)
if (lib_handle)
dlclose(lib_handle);
dm_dynamic_cleanmem(&plugin_mem);
return 0;
}

View file

@ -158,7 +158,6 @@ typedef struct dm_map_obj {
struct dm_leaf_s *root_leaf;
} DM_MAP_OBJ;
struct dm_reference {
char *path;
char *value;
@ -172,6 +171,7 @@ struct dmctx {
int (*checkobj)(DMOBJECT_ARGS);
int (*checkleaf)(DMOBJECT_ARGS);
struct list_head list_parameter;
struct list_head *memhead;
DMOBJ *dm_entryobj;
bool nextlevel;
bool iswildcard;

View file

@ -187,18 +187,6 @@ enum option_type_enum {
if ((dir = opendir(path)) == NULL) return 0; \
while ((ent = readdir(dir)) != NULL) \
#define sysfs_foreach_file_sorted(path,max_num_files) \
struct dirent *ent = NULL; \
DIR *dir = NULL; \
if ((dir = opendir(path)) == NULL) return; \
int num_files = 0; \
char *files[max_num_files]; \
while ((ent = readdir(dir)) != NULL && num_files < max_num_files) \
files[num_files++] = dmstrdup(ent->d_name); \
closedir(dir); \
qsort(files, num_files, sizeof(char*), compare_strings); \
for (int i = 0; i < num_files; i++)
struct dmmap_sect {
struct list_head list;
char *section_name;

View file

@ -46,6 +46,7 @@ void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj)
{
INIT_LIST_HEAD(&ctx->list_parameter);
ctx->dm_entryobj = tEntryObj;
bbfdm_init_mem(ctx);
dm_uci_init();
}
@ -55,7 +56,7 @@ void bbf_ctx_clean(struct dmctx *ctx)
dm_uci_exit();
dmubus_free();
dmcleanmem();
bbfdm_clean_mem(ctx);
}
void bbf_ctx_init_sub(struct dmctx *ctx, DMOBJ *tEntryObj)
@ -244,6 +245,7 @@ int bbf_entry_method(struct dmctx *ctx, int cmd)
void bbf_global_init(DMOBJ *dm_entryobj, const char *plugin_path)
{
dm_dynamic_initmem(&global_memhead);
load_plugins(dm_entryobj, plugin_path);
}

View file

@ -9,28 +9,70 @@
*
*/
#include "dmbbf.h"
#include "dmmem.h"
LIST_HEAD(memhead);
#define CHECK_MEM_LIST(mem_list) \
do { \
if (mem_list == NULL) { \
BBF_ERR("mem_list is not initialized !!!"); \
return NULL; \
} \
} while(0)
inline void *__dmmalloc(struct list_head *mem_list, size_t size)
struct dmmem {
struct list_head list;
char mem[0];
};
void __dminitmem(struct list_head *mem_list)
{
INIT_LIST_HEAD(mem_list);
}
void __dmcleanmem(struct list_head *mem_list)
{
struct dmmem *dmm;
while (mem_list->next != mem_list) {
dmm = list_entry(mem_list->next, struct dmmem, list);
list_del(&dmm->list);
FREE(dmm);
}
}
void dmfree(void *m)
{
if (m == NULL) return;
struct dmmem *rm;
rm = container_of(m, struct dmmem, mem);
list_del(&rm->list);
FREE(rm);
}
void *__dmmalloc(struct list_head *mem_list, size_t size)
{
CHECK_MEM_LIST(mem_list);
struct dmmem *m = malloc(sizeof(struct dmmem) + size);
if (m == NULL) return NULL;
list_add(&m->list, mem_list);
return (void *)m->mem;
}
inline void *__dmcalloc(struct list_head *mem_list, int n, size_t size)
void *__dmcalloc(struct list_head *mem_list, int n, size_t size)
{
CHECK_MEM_LIST(mem_list);
struct dmmem *m = calloc(n, sizeof(struct dmmem) + size);
if (m == NULL) return NULL;
list_add(&m->list, mem_list);
return (void *)m->mem;
}
inline void *__dmrealloc(struct list_head *mem_list, void *n, size_t size)
void *__dmrealloc(struct list_head *mem_list, void *n, size_t size)
{
CHECK_MEM_LIST(mem_list);
struct dmmem *m = NULL;
if (n != NULL) {
m = container_of(n, struct dmmem, mem);
@ -49,25 +91,6 @@ inline void *__dmrealloc(struct list_head *mem_list, void *n, size_t size)
return (void *)m->mem;
}
inline void dmfree(void *m)
{
if (m == NULL) return;
struct dmmem *rm;
rm = container_of(m, struct dmmem, mem);
list_del(&rm->list);
free(rm);
}
inline void __dmcleanmem(struct list_head *mem_list)
{
struct dmmem *dmm;
while (mem_list->next != mem_list) {
dmm = list_entry(mem_list->next, struct dmmem, list);
list_del(&dmm->list);
free(dmm);
}
}
char *__dmstrdup(struct list_head *mem_list, const char *s)
{
if (s == NULL)
@ -97,7 +120,7 @@ int __dmasprintf(struct list_head *mem_list, char **s, const char *format, ...)
*s = __dmstrdup(mem_list, str);
free(str);
FREE(str);
if (*s == NULL)
return -1;
@ -118,3 +141,166 @@ int __dmastrcat(struct list_head *mem_list, char **s, char *obj, char *lastname)
return 0;
}
/*
*
* New BBFDM Memory Management APIs
*
*/
static struct list_head *dm_memhead_ptr = NULL;
static struct list_head *get_ctx_memhead_list(struct dmctx *ctx)
{
if (!ctx) {
if (!dm_memhead_ptr) {
BBF_ERR("'ctx->mem_head' and 'dm_memhead_ptr' are not initialized! You should initialize 'ctx->mem_head' before using bbfdm memory APIs");
return NULL;
}
return dm_memhead_ptr;
}
if (!ctx->memhead) {
BBF_ERR("'ctx->mem_head' is not initialized! You should initialize 'ctx->mem_head' before using bbfdm memory APIs");
return NULL;
}
return ctx->memhead;
}
void bbfdm_init_mem(struct dmctx *ctx)
{
struct list_head *memory_list_head = calloc(1, sizeof(struct list_head));
// Check if memory allocation was successful
if (memory_list_head == NULL) {
BBF_ERR("Failed to allocate memory for the list head!!!");
return;
}
// Initialize the list head
INIT_LIST_HEAD(memory_list_head);
ctx->memhead = dm_memhead_ptr = memory_list_head;
}
void bbfdm_clean_mem(struct dmctx *ctx)
{
struct dmmem *dmm = NULL;
if (ctx->memhead == NULL) {
BBF_ERR("Memory list is NULL!");
return;
}
while (ctx->memhead->next != ctx->memhead) {
dmm = list_entry(ctx->memhead->next, struct dmmem, list);
list_del(&dmm->list);
FREE(dmm);
}
FREE(ctx->memhead);
dm_memhead_ptr = NULL;
}
void *bbfdm_malloc(struct dmctx *ctx, size_t size)
{
struct list_head *ctx_memhead = get_ctx_memhead_list(ctx);
if (ctx_memhead == NULL)
return NULL;
struct dmmem *m = malloc(sizeof(struct dmmem) + size);
if (m == NULL) return NULL;
list_add(&m->list, ctx_memhead);
return (void *)m->mem;
}
void *bbfdm_calloc(struct dmctx *ctx, int n, size_t size)
{
struct list_head *ctx_memhead = get_ctx_memhead_list(ctx);
if (ctx_memhead == NULL)
return NULL;
struct dmmem *m = calloc(n, sizeof(struct dmmem) + size);
if (m == NULL) return NULL;
list_add(&m->list, ctx_memhead);
return (void *)m->mem;
}
void *bbfdm_realloc(struct dmctx *ctx, void *n, size_t size)
{
struct list_head *ctx_memhead = get_ctx_memhead_list(ctx);
if (ctx_memhead == NULL)
return NULL;
struct dmmem *m = NULL;
if (n != NULL) {
m = container_of(n, struct dmmem, mem);
list_del(&m->list);
}
struct dmmem *new_m = realloc(m, sizeof(struct dmmem) + size);
if (new_m == NULL) {
dmfree(m);
return NULL;
} else {
m = new_m;
}
list_add(&m->list, ctx_memhead);
return (void *)m->mem;
}
char *bbfdm_strdup(struct dmctx *ctx, const char *s)
{
if (s == NULL)
return NULL;
size_t len = strlen(s) + 1;
void *new = bbfdm_malloc(ctx, len);
if (new == NULL)
return NULL;
return (char *) memcpy(new, s, len);
}
int bbfdm_asprintf(struct dmctx *ctx, char **s, const char *format, ...)
{
va_list arg;
char *str = NULL;
int size = 0;
va_start(arg, format);
size = vasprintf(&str, format, arg);
va_end(arg);
if (size < 0 || str == NULL)
return -1;
*s = bbfdm_strdup(ctx, str);
FREE(str);
if (*s == NULL)
return -1;
return 0;
}
int bbfdm_astrcat(struct dmctx *ctx, char **s, char *obj, char *lastname)
{
char buf[2048] = {0};
if (obj == NULL || lastname == NULL)
return -1;
int olen = strlen(obj);
memcpy(buf, obj, olen);
int llen = strlen(lastname) + 1;
memcpy(buf + olen, lastname, llen);
*s = bbfdm_strdup(ctx, buf);
if (*s == NULL)
return -1;
return 0;
}

View file

@ -18,36 +18,99 @@
#include <string.h>
#include <libubox/list.h>
extern struct list_head memhead;
#include "dmapi.h"
void dmfree(void *m);
struct dmmem {
struct list_head list;
char mem[0];
};
void __dminitmem(struct list_head *mem_list);
void __dmcleanmem(struct list_head *mem_list);
void *__dmmalloc(struct list_head *mem_list, size_t size);
void *__dmcalloc(struct list_head *mem_list, int n, size_t size);
void *__dmrealloc(struct list_head *mem_list, void *n, size_t size);
char *__dmstrdup(struct list_head *mem_list, const char *s);
int __dmasprintf(struct list_head *mem_list, char **s, const char *format, ...);
int __dmastrcat(struct list_head *mem_list, char **s, char *obj, char *lastname);
void __dmcleanmem(struct list_head *mem_list);
#define dmmalloc(x) __dmmalloc(&memhead, x)
#define dmcalloc(n, x) __dmcalloc(&memhead, n, x)
#define dmrealloc(x, n) __dmrealloc(&memhead, x, n)
#define dmstrdup(x) __dmstrdup(&memhead, x)
#define dmasprintf(s, format, ...) __dmasprintf(&memhead, s, format, ## __VA_ARGS__)
#define dmastrcat(s, b, m) __dmastrcat(&memhead, s, b, m)
#define dmcleanmem() __dmcleanmem(&memhead)
/*
* Initialize memory management.
* @param ctx - Pointer to bbf context
*/
void bbfdm_init_mem(struct dmctx *ctx);
/*
* Clean up memory management.
* @param ctx - Pointer to bbf context
*/
void bbfdm_clean_mem(struct dmctx *ctx);
/*
* Allocate memory block of the specified size.
* @param ctx - Pointer to bbf context
* @param size - Size of memory block to allocate
* @return Pointer to the allocated memory block
*/
void *bbfdm_malloc(struct dmctx *ctx, size_t size);
/*
* Allocate memory for an array of n elements, each of size bytes, initialized to zero.
* @param ctx - Pointer to bbf context
* @param n - Number of elements
* @param size - Size of each element
* @return Pointer to the allocated memory block
*/
void *bbfdm_calloc(struct dmctx *ctx, int n, size_t size);
/*
* Resize the memory block pointed to by n to the new size size.
* @param ctx - Pointer to bbf context
* @param n - Pointer to the memory block to resize
* @param size - New size of the memory block
* @return Pointer to the resized memory block
*/
void *bbfdm_realloc(struct dmctx *ctx, void *n, size_t size);
/*
* Duplicate the string s.
* @param ctx - Pointer to bbf context
* @param s - Pointer to the string to duplicate
* @return Pointer to the duplicated string
*/
char *bbfdm_strdup(struct dmctx *ctx, const char *s);
/*
* Allocate a string with a format similar to printf.
* @param ctx - Pointer to bbf context
* @param s - Pointer to store the resulting string
* @param format - Format string
* @param ... - Additional arguments for the format string
* @return 0 on success, -1 on failure
*/
int bbfdm_asprintf(struct dmctx *ctx, char **s, const char *format, ...);
/*
* Concatenate the string lastname to the string obj.
* @param ctx - Pointer to bbf context
* @param s - Pointer to store the resulting string
* @param obj - Pointer to the first string
* @param lastname - Pointer to the second string to concatenate
* @return 0 on success, -1 on failure
*/
int bbfdm_astrcat(struct dmctx *ctx, char **s, char *obj, char *lastname);
#define dmmalloc(x) bbfdm_malloc(0, x)
#define dmcalloc(n, x) bbfdm_calloc(0, n, x)
#define dmrealloc(x, n) bbfdm_realloc(0, x, n)
#define dmstrdup(x) bbfdm_strdup(0, x)
#define dmasprintf(s, format, ...) bbfdm_asprintf(0, s, format, ## __VA_ARGS__)
#define dmastrcat(s, b, m) bbfdm_astrcat(0, s, b, m)
#define dm_dynamic_malloc(m, x) __dmmalloc(m, x)
#define dm_dynamic_calloc(m, n, x) __dmcalloc(m, n, x)
#define dm_dynamic_realloc(m, x, n) __dmrealloc(m, x, n)
#define dm_dynamic_strdup(m, x) __dmstrdup(m, x)
#define dm_dynamic_asprintf(m, s, format, ...) __dmasprintf(m, s, format, ## __VA_ARGS__)
#define dm_dynamic_initmem(m) __dminitmem(m)
#define dm_dynamic_cleanmem(m) __dmcleanmem(m)
#endif /* __DMMEM_H */

View file

@ -262,8 +262,8 @@ static int plugin_obj_match(char *in_param, struct dmnode *node)
return FAULT_9005;
}
static void dm_check_dynamic_obj(DMNODE *parent_node, DMOBJ *entryobj, char *full_obj, DMOBJ **root_entry);
static void dm_check_dynamic_obj_entry(DMNODE *parent_node, DMOBJ *entryobj, char *parent_obj, char *full_obj, DMOBJ **root_entry)
static void dm_check_dynamic_obj(struct list_head *mem_list, DMNODE *parent_node, DMOBJ *entryobj, char *full_obj, DMOBJ **root_entry);
static void dm_check_dynamic_obj_entry(struct list_head *mem_list, DMNODE *parent_node, DMOBJ *entryobj, char *parent_obj, char *full_obj, DMOBJ **root_entry)
{
DMNODE node = {0};
node.obj = entryobj;
@ -271,7 +271,7 @@ static void dm_check_dynamic_obj_entry(DMNODE *parent_node, DMOBJ *entryobj, cha
node.instance_level = parent_node->instance_level;
node.matched = parent_node->matched;
dmasprintf(&(node.current_object), "%s%s.", parent_obj, entryobj->obj);
dm_dynamic_asprintf(mem_list, &(node.current_object), "%s%s.", parent_obj, entryobj->obj);
if (DM_STRCMP(node.current_object, full_obj) == 0) {
*root_entry = entryobj;
return;
@ -282,15 +282,15 @@ static void dm_check_dynamic_obj_entry(DMNODE *parent_node, DMOBJ *entryobj, cha
return;
if (entryobj->nextobj || entryobj->nextdynamicobj)
dm_check_dynamic_obj(&node, entryobj->nextobj, full_obj, root_entry);
dm_check_dynamic_obj(mem_list, &node, entryobj->nextobj, full_obj, root_entry);
}
static void dm_check_dynamic_obj(DMNODE *parent_node, DMOBJ *entryobj, char *full_obj, DMOBJ **root_entry)
static void dm_check_dynamic_obj(struct list_head *mem_list, DMNODE *parent_node, DMOBJ *entryobj, char *full_obj, DMOBJ **root_entry)
{
char *parent_obj = parent_node->current_object;
for (; (entryobj && entryobj->obj); entryobj++) {
dm_check_dynamic_obj_entry(parent_node, entryobj, parent_obj, full_obj, root_entry);
dm_check_dynamic_obj_entry(mem_list, parent_node, entryobj, parent_obj, full_obj, root_entry);
if (*root_entry != NULL)
return;
}
@ -303,7 +303,7 @@ static void dm_check_dynamic_obj(DMNODE *parent_node, DMOBJ *entryobj, char *ful
for (int j = 0; next_dyn_array->nextobj[j]; j++) {
DMOBJ *jentryobj = next_dyn_array->nextobj[j];
for (; (jentryobj && jentryobj->obj); jentryobj++) {
dm_check_dynamic_obj_entry(parent_node, jentryobj, parent_obj, full_obj, root_entry);
dm_check_dynamic_obj_entry(mem_list, parent_node, jentryobj, parent_obj, full_obj, root_entry);
if (*root_entry != NULL)
return;
}
@ -321,13 +321,16 @@ DMOBJ *find_entry_obj(DMOBJ *entryobj, char *obj_path)
DMNODE node = {.current_object = ""};
DMOBJ *obj = NULL;
LIST_HEAD(local_mem);
char in_obj[1024] = {0};
replace_str(obj_path, ".{i}.", ".", in_obj, sizeof(in_obj));
if (strlen(in_obj) == 0)
return NULL;
dm_check_dynamic_obj(&node, entryobj, in_obj, &obj);
dm_check_dynamic_obj(&local_mem, &node, entryobj, in_obj, &obj);
dm_dynamic_cleanmem(&local_mem);
return obj;
}
@ -456,12 +459,7 @@ int get_leaf_idx(DMLEAF **entryleaf)
void load_plugins(DMOBJ *dm_entryobj, const char *plugin_path)
{
int max_num_files = 256;
if (DM_STRLEN(plugin_path) == 0)
return;
if (!folder_exists(plugin_path))
if (DM_STRLEN(plugin_path) == 0 || !folder_exists(plugin_path))
return;
free_json_plugins();
@ -469,7 +467,23 @@ void load_plugins(DMOBJ *dm_entryobj, const char *plugin_path)
free_dotso_plugins();
free_specific_dynamic_node(dm_entryobj, INDX_LIBRARY_MOUNT);
sysfs_foreach_file_sorted(plugin_path, max_num_files) {
struct dirent *ent = NULL;
DIR *dir = opendir(plugin_path);
if (dir == NULL)
return;
int num_files = 0;
char *files[256];
while ((ent = readdir(dir)) != NULL && num_files < 256) {
files[num_files++] = strdup(ent->d_name);
}
closedir(dir);
qsort(files, num_files, sizeof(char *), compare_strings);
for (int i = 0; i < num_files; i++) {
char buf[512] = {0};
snprintf(buf, sizeof(buf), "%s/%s", plugin_path, files[i]);
@ -480,7 +494,7 @@ void load_plugins(DMOBJ *dm_entryobj, const char *plugin_path)
load_dotso_plugins(dm_entryobj, buf);
}
dmfree(files[i]);
free(files[i]);
}
}

View file

@ -6,8 +6,11 @@
#include <libbbfdm-api/dmcommon.h>
#include <libbbfdm-api/dmmem.h>
static struct dmctx bbf_ctx = {0};
static int setup_teardown(void **state)
{
bbfdm_init_mem(&bbf_ctx);
dm_uci_init();
return 0;
}
@ -16,7 +19,7 @@ static int group_teardown(void **state)
{
dm_uci_exit();
dmubus_free();
dmcleanmem();
bbfdm_clean_mem(&bbf_ctx);
return 0;
}

View file

@ -590,7 +590,7 @@ static void test_api_bbfdm_json_get_value(void **state)
assert_true(&first_entry->list != &ctx->list_parameter);
bbf_ctx_clean_sub(ctx);
bbf_ctx_init(ctx, TR181_ROOT_TREE);
bbf_ctx_init_sub(ctx, TR181_ROOT_TREE);
/*
* Test of JSON Parameter Path
@ -601,9 +601,6 @@ static void test_api_bbfdm_json_get_value(void **state)
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
assert_true(&first_entry->list != &ctx->list_parameter);
bbf_ctx_clean_sub(ctx);
bbf_ctx_init(ctx, TR181_ROOT_TREE);
}
static void test_api_bbfdm_json_add_object(void **state)
@ -651,7 +648,7 @@ static void test_api_bbfdm_library_get_value(void **state)
assert_true(&first_entry->list != &ctx->list_parameter);
bbf_ctx_clean_sub(ctx);
bbf_ctx_init(ctx, TR181_ROOT_TREE);
bbf_ctx_init_sub(ctx, TR181_ROOT_TREE);
ctx->in_param = "Device.WiFi.SSID.1.Enable";
@ -660,8 +657,6 @@ static void test_api_bbfdm_library_get_value(void **state)
first_entry = list_first_entry(&ctx->list_parameter, struct dm_parameter, list);
assert_true(&first_entry->list != &ctx->list_parameter);
bbf_ctx_clean_sub(ctx);
}
static void test_api_bbfdm_library_add_object(void **state)