Define memhead list inside bbf context structure

This commit is contained in:
Amin Ben Romdhane 2024-03-20 11:54:51 +00:00 committed by Vivek Kumar Dutta
parent 72ad1ac91a
commit b0614ecfd3
12 changed files with 390 additions and 105 deletions

View file

@ -45,9 +45,10 @@ extern struct list_head json_memhead;
LIST_HEAD(head_registered_service);
static void register_periodic_timers(struct ubus_context *ctx);
static void cancel_periodic_timers(struct ubus_context *ctx);
static void run_schema_updater(struct bbfdm_context *u);
static void periodic_instance_updater(struct uloop_timeout *t);
static void register_instance_refresh_timer(struct ubus_context *ctx, int start_sec);
// Global variables
static void *deamon_lib_handle = NULL;
@ -583,6 +584,7 @@ int bbfdm_set_handler(struct ubus_context *ctx, struct ubus_object *obj,
if (data.trans_id == 0) {
// Transaction-id is not defined so create an internal transaction
cancel_periodic_timers(ctx);
trans_id = transaction_start(&data, "INT_SET", 0);
if (trans_id == 0) {
WARNING("Failed to get the lock for the transaction");
@ -595,6 +597,7 @@ int bbfdm_set_handler(struct ubus_context *ctx, struct ubus_object *obj,
if (data.trans_id == 0) {
// Internal transaction: need to commit the changes
register_instance_refresh_timer(ctx, 100);
transaction_commit(NULL, trans_id, true);
}
@ -703,6 +706,7 @@ int bbfdm_add_handler(struct ubus_context *ctx, struct ubus_object *obj,
if (data.trans_id == 0) {
// Transaction-id is not defined so create an internal transaction
cancel_periodic_timers(ctx);
trans_id = transaction_start(&data, "INT_ADD", 0);
if (trans_id == 0) {
ERR("Failed to get the lock for the transaction");
@ -717,6 +721,7 @@ int bbfdm_add_handler(struct ubus_context *ctx, struct ubus_object *obj,
if (data.trans_id == 0) {
// Internal transaction: need to abort the changes
register_instance_refresh_timer(ctx, 0);
transaction_abort(NULL, trans_id);
}
@ -735,6 +740,7 @@ int bbfdm_add_handler(struct ubus_context *ctx, struct ubus_object *obj,
if (data.trans_id == 0) {
// Internal transaction: need to abort the changes
register_instance_refresh_timer(ctx, 0);
transaction_abort(NULL, trans_id);
}
@ -751,6 +757,7 @@ int bbfdm_add_handler(struct ubus_context *ctx, struct ubus_object *obj,
if (data.trans_id == 0) {
// Internal transaction: need to commit the changes
register_instance_refresh_timer(ctx, 100);
transaction_commit(NULL, trans_id, true);
}
@ -826,6 +833,7 @@ int bbfdm_del_handler(struct ubus_context *ctx, struct ubus_object *obj,
if (data.trans_id == 0) {
// Transaction-id is not defined so create an internal transaction
cancel_periodic_timers(ctx);
trans_id = transaction_start(&data, "INT_DEL", 0);
if (trans_id == 0) {
WARNING("Failed to get the lock for the transaction");
@ -838,6 +846,7 @@ int bbfdm_del_handler(struct ubus_context *ctx, struct ubus_object *obj,
if (data.trans_id == 0) {
// Internal transaction: need to commit the changes
register_instance_refresh_timer(ctx, 100);
transaction_commit(NULL, trans_id, true);
}
@ -915,11 +924,11 @@ static int bbfdm_transaction_handler(struct ubus_context *ctx, struct ubus_objec
transaction_status(&data.bb);
}
} else if (is_str_eq(trans_cmd, "commit")) {
register_periodic_timers(ctx);
register_instance_refresh_timer(ctx, 100);
ret = transaction_commit(&data, data.trans_id, is_service_restart);
blobmsg_add_u8(&data.bb, "status", (ret == 0));
} else if (is_str_eq(trans_cmd, "abort")) {
register_periodic_timers(ctx);
register_instance_refresh_timer(ctx, 0);
ret = transaction_abort(&data, data.trans_id);
blobmsg_add_u8(&data.bb, "status", (ret == 0));
} else if (is_str_eq(trans_cmd, "status")) {
@ -1185,7 +1194,6 @@ static void update_instances_list(struct list_head *inst)
bbf_cleanup(&bbf_ctx);
}
static void periodic_instance_updater(struct uloop_timeout *t);
static void instance_fork_done(struct uloop_process *p, int ret)
{
struct bbfdm_async_req *r = container_of(p, struct bbfdm_async_req, process);
@ -1251,6 +1259,7 @@ static int fork_instance_checker(struct bbfdm_context *u)
}
child = fork();
if (child == 0) {
INFO("{fork} Instances checker entry");
prctl(PR_SET_NAME, (unsigned long) "bbfdm_instance");
// child initialise signal to prevent segfaults
signal_init();
@ -1262,10 +1271,10 @@ static int fork_instance_checker(struct bbfdm_context *u)
fclose(stdout);
fclose(stderr);
DEBUG("subprocess instances checker");
instance_compare_publish(u);
bbfdm_cleanup(u);
closelog();
INFO("{fork} Instances checker exit");
/* write result and exit */
exit(EXIT_SUCCESS);
}
@ -1306,17 +1315,30 @@ static void periodic_instance_updater(struct uloop_timeout *t)
return;
}
if (list_empty(&u->instances)) {
if (!list_empty(&u->old_instances)) {
list_splice_init(&u->old_instances, &u->instances);
} else {
update_instances_list(&u->instances);
DEBUG("Creating timer for instance update checker, init instances");
u->instance_timer.cb = periodic_instance_updater;
uloop_timeout_set(&u->instance_timer, u->config.refresh_time);
return;
}
}
free_path_list(&u->old_instances);
list_splice_init(&u->instances, &u->old_instances);
update_instances_list(&u->instances);
if (list_empty(&u->instances)) {
update_instances_list(&u->instances);
DEBUG("Creating timer for instance update checker, init instances");
WARNING("Failed to get current instances, restart the timer");
u->instance_timer.cb = periodic_instance_updater;
uloop_timeout_set(&u->instance_timer, u->config.refresh_time);
return;
}
list_splice_init(&u->instances, &u->old_instances);
update_instances_list(&u->instances);
// fork a process and send it to compare, when process completes
// delete the old instances and add a new timer
fork_instance_checker(u);
@ -1569,9 +1591,10 @@ static void cancel_periodic_timers(struct ubus_context *ctx)
}
}
static void register_periodic_timers(struct ubus_context *ctx)
static void register_instance_refresh_timer(struct ubus_context *ctx, int start_in)
{
struct bbfdm_context *u;
unsigned refresh_time = 0;
u = container_of(ctx, struct bbfdm_context, ubus_ctx);
if (u == NULL) {
@ -1579,10 +1602,16 @@ static void register_periodic_timers(struct ubus_context *ctx)
return;
}
DEBUG("Register instance_timer %d", u->config.refresh_time);
if (start_in <= 0) {
refresh_time = u->config.refresh_time;
} else {
refresh_time = start_in;
}
DEBUG("Register instance refresh timer in %d ms...", refresh_time);
if (u->config.refresh_time != 0) {
u->instance_timer.cb = periodic_instance_updater;
uloop_timeout_set(&u->instance_timer, u->config.refresh_time);
uloop_timeout_set(&u->instance_timer, refresh_time);
}
}
@ -1716,12 +1745,13 @@ int main(int argc, char **argv)
ubus_add_uloop(&bbfdm_ctx.ubus_ctx);
ubus_init_done = true;
periodic_instance_updater(&bbfdm_ctx.instance_timer);
err = bbfdm_regiter_ubus(&bbfdm_ctx.ubus_ctx);
if (err != UBUS_STATUS_OK)
goto exit;
run_schema_updater(&bbfdm_ctx);
register_instance_refresh_timer(&bbfdm_ctx.ubus_ctx, 1000);
if (is_micro_service == false) { // It's not a micro-service instance
err = register_events_to_ubus(&bbfdm_ctx.ubus_ctx, &bbfdm_ctx.event_handlers);
if (err != 0)

View file

@ -16,7 +16,7 @@
#include "plugin/json_plugin.h"
extern struct list_head global_memhead;
static LIST_HEAD(plugin_mem);
int load_dotso_plugin(void **lib_handle, const char *file_path,
DMOBJ **main_entry,
@ -34,13 +34,15 @@ int load_dotso_plugin(void **lib_handle, const char *file_path,
return -1;
}
dm_dynamic_initmem(&plugin_mem);
*lib_handle = handle;
//Dynamic Object
DM_MAP_OBJ *dynamic_obj = NULL;
*(void **) (&dynamic_obj) = dlsym(handle, "tDynamicObj");
if (dynamic_obj) {
char *node_obj = dm_dynamic_strdup(&global_memhead, dynamic_obj[0].path);
char *node_obj = dm_dynamic_strdup(&plugin_mem, dynamic_obj[0].path);
unsigned int len = strlen(node_obj);
if (strncmp(node_obj, ROOT_NODE, strlen(ROOT_NODE)) != 0 || node_obj[len-1] != '.') {
@ -48,7 +50,7 @@ int load_dotso_plugin(void **lib_handle, const char *file_path,
return -1;
}
DMOBJ *dm_entryobj = (DMOBJ *)dm_dynamic_calloc(&global_memhead, 2, sizeof(DMOBJ));
DMOBJ *dm_entryobj = (DMOBJ *)dm_dynamic_calloc(&plugin_mem, 2, sizeof(DMOBJ));
if (dm_entryobj == NULL) {
ERR("No Memory exists\n");
return -1;
@ -91,6 +93,7 @@ int free_dotso_plugin(void *lib_handle)
if (lib_handle)
dlclose(lib_handle);
dm_dynamic_cleanmem(&plugin_mem);
return 0;
}

View file

@ -181,6 +181,7 @@ struct dmctx {
int (*checkobj)(DMOBJECT_ARGS);
int (*checkleaf)(DMOBJECT_ARGS);
struct list_head list_parameter;
struct list_head *memhead;
DMOBJ *dm_entryobj;
DM_MAP_VENDOR *dm_vendor_extension[2];
DM_MAP_VENDOR_EXCLUDE *dm_vendor_extension_exclude;

View file

@ -183,18 +183,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 0; \
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

@ -51,6 +51,7 @@ void bbf_ctx_init(struct dmctx *ctx, DMOBJ *tEntryObj,
ctx->dm_vendor_extension[0] = tVendorExtension ? tVendorExtension[0] : NULL;
ctx->dm_vendor_extension[1] = tVendorExtension ? tVendorExtension[1] : NULL;
ctx->dm_vendor_extension_exclude = tVendorExtensionExclude;
bbfdm_init_mem(ctx);
dm_uci_init();
}
@ -60,7 +61,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,
@ -251,6 +252,7 @@ int bbf_entry_method(struct dmctx *ctx, int cmd)
void bbf_global_init(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, const char *plugin_path)
{
dm_dynamic_initmem(&global_memhead);
load_plugins(dm_entryobj, dm_VendorExtension,dm_VendorExtensionExclude, 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) { \
TRACE("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) {
TRACE("'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) {
TRACE("'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) {
TRACE("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) {
TRACE("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

@ -246,8 +246,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;
@ -255,7 +255,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;
@ -266,15 +266,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;
}
@ -287,7 +287,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;
}
@ -305,11 +305,14 @@ DMOBJ *find_entry_obj(DMOBJ *entryobj, char *obj_path)
DMNODE node = {.current_object = ""};
DMOBJ *obj = NULL;
LIST_HEAD(local_mem);
char *in_obj = replace_str(obj_path, ".{i}.", ".");
dm_check_dynamic_obj(&node, entryobj, in_obj, &obj);
dm_check_dynamic_obj(&local_mem, &node, entryobj, in_obj, &obj);
FREE(in_obj);
dm_dynamic_cleanmem(&local_mem);
return obj;
}
@ -385,24 +388,40 @@ int get_leaf_idx(DMLEAF **entryleaf)
return idx;
}
int load_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, const char *plugin_path)
void load_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, const char *plugin_path)
{
int max_num_files = 256;
#ifdef BBF_VENDOR_EXTENSION
// Load objects and parameters exposed via vendor extension plugin
load_vendor_dynamic_arrays(dm_entryobj, dm_VendorExtension, dm_VendorExtensionExclude);
#endif /* BBF_VENDOR_EXTENSION */
if (DM_STRLEN(plugin_path) == 0) // If empty, return without further action
return 0;
return;
if (!folder_exists(plugin_path)) {
TRACE("(%s) doesn't exist", plugin_path);
return 0;
return;
}
sysfs_foreach_file_sorted(plugin_path, max_num_files) {
struct dirent *ent = NULL;
int num_files = 0;
char *files[256];
DIR *dir = opendir(plugin_path);
if (dir == NULL) {
TRACE("Cannot open (%s) directory", plugin_path);
return;
}
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]);
@ -413,10 +432,8 @@ int load_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP
load_dotso_plugins(dm_entryobj, buf);
}
dmfree(files[i]);
free(files[i]);
}
return 0;
}
void free_plugins(DMOBJ *dm_entryobj)

View file

@ -20,7 +20,7 @@ int get_entry_idx(DMOBJ *entryobj);
int get_obj_idx(DMOBJ **entryobj);
int get_leaf_idx(DMLEAF **entryleaf);
int load_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, const char *plugin_path);
void load_plugins(DMOBJ *dm_entryobj, DM_MAP_VENDOR *dm_VendorExtension[], DM_MAP_VENDOR_EXCLUDE *dm_VendorExtensionExclude, const char *plugin_path);
void free_plugins(DMOBJ *dm_entryobj);
#endif //__DMPLUGIN_H__

View file

@ -72,17 +72,16 @@ static void overwrite_obj(DMOBJ *entryobj, DMOBJ *dmobj)
static void load_vendor_extension_arrays(DMOBJ *entryobj, DM_MAP_VENDOR *vendor_map_obj)
{
char *pch = NULL, *pchr = NULL;
char vendor_list[512] = {0};
size_t length = 0;
DM_STRNCPY(vendor_list, BBF_VENDOR_LIST, sizeof(vendor_list));
char **tokens = strsplit(vendor_list, ",", &length);
for (int idx = length - 1; idx >= 0; idx--) {
for (pch = strtok_r(vendor_list, ",", &pchr); pch != NULL; pch = strtok_r(NULL, ",", &pchr)) {
for (int j = 0; vendor_map_obj && vendor_map_obj[j].vendor; j++) {
if (DM_STRCMP(vendor_map_obj[j].vendor, tokens[idx]) != 0)
if (DM_STRCMP(vendor_map_obj[j].vendor, pch) != 0)
continue;
DM_MAP_OBJ *vendor_obj = vendor_map_obj[j].vendor_obj;
@ -142,17 +141,16 @@ static void load_vendor_extension_arrays(DMOBJ *entryobj, DM_MAP_VENDOR *vendor_
static void load_vendor_extension_overwrite_arrays(DMOBJ *entryobj, DM_MAP_VENDOR *vendor_map_obj)
{
char *pch = NULL, *pchr = NULL;
char vendor_list[512] = {0};
size_t length = 0;
DM_STRNCPY(vendor_list, BBF_VENDOR_LIST, sizeof(vendor_list));
char **tokens = strsplit(vendor_list, ",", &length);
for (int idx = length - 1; idx >= 0; idx--) {
for (pch = strtok_r(vendor_list, ",", &pchr); pch != NULL; pch = strtok_r(NULL, ",", &pchr)) {
for (int j = 0; vendor_map_obj && vendor_map_obj[j].vendor; j++) {
if (DM_STRCMP(vendor_map_obj[j].vendor, tokens[idx]) != 0)
if (DM_STRCMP(vendor_map_obj[j].vendor, pch) != 0)
continue;
DM_MAP_OBJ *dynamic_overwrite_obj = vendor_map_obj[j].vendor_obj;
@ -228,17 +226,16 @@ static void exclude_param(DMOBJ *dm_entryobj, char *in_param)
static void load_vendor_extension_exclude_arrays(DMOBJ *entryobj, DM_MAP_VENDOR_EXCLUDE *vendor_map_exclude_obj)
{
char *pch = NULL, *pchr = NULL;
char vendor_list[512] = {0};
size_t length = 0;
DM_STRNCPY(vendor_list, BBF_VENDOR_LIST, sizeof(vendor_list));
char **tokens = strsplit(vendor_list, ",", &length);
for (int idx = length - 1; idx >= 0; idx--) {
for (pch = strtok_r(vendor_list, ",", &pchr); pch != NULL; pch = strtok_r(NULL, ",", &pchr)) {
for (int j = 0; vendor_map_exclude_obj && vendor_map_exclude_obj[j].vendor; j++) {
if (DM_STRCMP(vendor_map_exclude_obj[j].vendor, tokens[idx]) != 0)
if (DM_STRCMP(vendor_map_exclude_obj[j].vendor, pch) != 0)
continue;
char **dynamic_exclude_obj = vendor_map_exclude_obj[j].vendor_obj;

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

@ -592,7 +592,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, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
bbf_ctx_init_sub(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
/*
* Test of JSON Parameter Path
@ -603,9 +603,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, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
}
static void test_api_bbfdm_json_add_object(void **state)
@ -653,7 +650,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, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
bbf_ctx_init_sub(ctx, TR181_ROOT_TREE, TR181_VENDOR_EXTENSION, TR181_VENDOR_EXTENSION_EXCLUDE);
ctx->in_param = "Device.WiFi.SSID.1.Enable";
@ -662,8 +659,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)