libbbfdm-ubus: refactor ubus_ctx handling for greater flexibility

This commit is contained in:
Amin Ben Romdhane 2025-10-17 16:34:52 +00:00 committed by IOPSYS Dev
parent 69134df069
commit a332ebef29
No known key found for this signature in database
4 changed files with 79 additions and 77 deletions

View file

@ -85,9 +85,7 @@ int main(int argc, char **argv)
uloop_run(); uloop_run();
exit: exit:
if (err != -5) // Error code is not -5, indicating that ubus_ctx is connected, proceed with shutdown bbfdm_ubus_register_free(&bbfdm_ctx);
bbfdm_ubus_register_free(&bbfdm_ctx);
closelog(); closelog();
return err; return err;

View file

@ -37,6 +37,13 @@
static void *deamon_lib_handle = NULL; static void *deamon_lib_handle = NULL;
static uint8_t s_log_level = 0xff; static uint8_t s_log_level = 0xff;
static void bbfdm_ctx_init(struct bbfdm_context *bbfdm_ctx)
{
INIT_LIST_HEAD(&bbfdm_ctx->event_handlers);
INIT_LIST_HEAD(&bbfdm_ctx->config.apply_handlers);
INIT_LIST_HEAD(&bbfdm_ctx->changed_uci);
}
static void bbfdm_ctx_cleanup(struct bbfdm_context *u) static void bbfdm_ctx_cleanup(struct bbfdm_context *u)
{ {
bbf_global_clean(DEAMON_DM_ROOT_OBJ); bbf_global_clean(DEAMON_DM_ROOT_OBJ);
@ -134,7 +141,7 @@ static int bbfdm_start_deferred(bbfdm_data_t *data, void (*EXEC_CB)(bbfdm_data_t
BBF_ERR("fork error"); BBF_ERR("fork error");
goto err_out; goto err_out;
} else if (child == 0) { } else if (child == 0) {
u = container_of(data->ctx, struct bbfdm_context, ubus_ctx); u = container_of(data->obj, struct bbfdm_context, ubus_obj);
if (u == NULL) { if (u == NULL) {
BBF_ERR("{fork} Failed to get the bbfdm context"); BBF_ERR("{fork} Failed to get the bbfdm context");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -142,7 +149,7 @@ static int bbfdm_start_deferred(bbfdm_data_t *data, void (*EXEC_CB)(bbfdm_data_t
/* free fd's and memory inherited from parent */ /* free fd's and memory inherited from parent */
uloop_done(); uloop_done();
ubus_shutdown(data->ctx); ubus_free(data->ctx);
async_req_free(r); async_req_free(r);
fclose(stdin); fclose(stdin);
fclose(stdout); fclose(stdout);
@ -221,7 +228,7 @@ static const struct blobmsg_policy dm_schema_policy[] = {
[DM_SCHEMA_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE}, [DM_SCHEMA_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE},
}; };
static int bbfdm_schema_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), static int bbfdm_schema_handler(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method __attribute__((unused)), struct ubus_request_data *req, const char *method __attribute__((unused)),
struct blob_attr *msg) struct blob_attr *msg)
{ {
@ -232,7 +239,7 @@ static int bbfdm_schema_handler(struct ubus_context *ctx, struct ubus_object *ob
memset(&data, 0, sizeof(bbfdm_data_t)); memset(&data, 0, sizeof(bbfdm_data_t));
u = container_of(ctx, struct bbfdm_context, ubus_ctx); u = container_of(obj, struct bbfdm_context, ubus_obj);
if (u == NULL) { if (u == NULL) {
BBF_ERR("Failed to get the bbfdm context"); BBF_ERR("Failed to get the bbfdm context");
return UBUS_STATUS_UNKNOWN_ERROR; return UBUS_STATUS_UNKNOWN_ERROR;
@ -401,7 +408,7 @@ static const struct blobmsg_policy dm_operate_policy[__DM_OPERATE_MAX] = {
[DM_OPERATE_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE }, [DM_OPERATE_OPTIONAL] = { .name = "optional", .type = BLOBMSG_TYPE_TABLE },
}; };
static int bbfdm_operate_handler(struct ubus_context *ctx, struct ubus_object *obj __attribute__((unused)), static int bbfdm_operate_handler(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method __attribute__((unused)), struct ubus_request_data *req, const char *method __attribute__((unused)),
struct blob_attr *msg) struct blob_attr *msg)
{ {
@ -424,6 +431,7 @@ static int bbfdm_operate_handler(struct ubus_context *ctx, struct ubus_object *o
data.ctx = ctx; data.ctx = ctx;
data.req = req; data.req = req;
data.obj = obj;
data.bbf_ctx.in_param = path; data.bbf_ctx.in_param = path;
data.bbf_ctx.linker = tb[DM_OPERATE_COMMAND_KEY] ? blobmsg_get_string(tb[DM_OPERATE_COMMAND_KEY]) : ""; data.bbf_ctx.linker = tb[DM_OPERATE_COMMAND_KEY] ? blobmsg_get_string(tb[DM_OPERATE_COMMAND_KEY]) : "";
@ -612,34 +620,15 @@ static struct ubus_method bbf_methods[] = {
static struct ubus_object_type bbf_type = UBUS_OBJECT_TYPE("", bbf_methods); static struct ubus_object_type bbf_type = UBUS_OBJECT_TYPE("", bbf_methods);
static struct ubus_object bbf_object = { static int regiter_ubus_object(struct bbfdm_context *bbfdm_ctx)
.name = "",
.type = &bbf_type,
.methods = bbf_methods,
.n_methods = ARRAY_SIZE(bbf_methods)
};
static int regiter_ubus_object(struct ubus_context *ctx)
{ {
struct bbfdm_context *u; bbfdm_ctx->ubus_obj.name = bbfdm_ctx->config.out_name;
bbfdm_ctx->ubus_obj.type = &bbf_type;
bbfdm_ctx->ubus_obj.type->name = bbfdm_ctx->config.out_name;
bbfdm_ctx->ubus_obj.methods = bbf_methods;
bbfdm_ctx->ubus_obj.n_methods = ARRAY_SIZE(bbf_methods);
u = container_of(ctx, struct bbfdm_context, ubus_ctx); return ubus_add_object(bbfdm_ctx->ubus_ctx, &bbfdm_ctx->ubus_obj);
if (u == NULL) {
BBF_ERR("failed to get the bbfdm context");
return -1;
}
bbf_object.name = u->config.out_name;
bbf_object.type->name = u->config.out_name;
return ubus_add_object(ctx, &bbf_object);
}
static void bbfdm_ctx_init(struct bbfdm_context *bbfdm_ctx)
{
INIT_LIST_HEAD(&bbfdm_ctx->event_handlers);
INIT_LIST_HEAD(&bbfdm_ctx->config.apply_handlers);
INIT_LIST_HEAD(&bbfdm_ctx->changed_uci);
} }
static void free_apply_handlers(bbfdm_config_t *config) static void free_apply_handlers(bbfdm_config_t *config)
@ -999,35 +988,49 @@ static void bbfdm_apply_event_cb(struct ubus_context *ctx __attribute__((unused)
} }
} }
static void register_bbfdm_apply_event(struct bbfdm_context *bbfdm_ctx) static int register_bbfdm_apply_event(struct bbfdm_context *bbfdm_ctx)
{ {
if (bbfdm_ctx == NULL) if (bbfdm_ctx == NULL)
return; return -1;
memset(&bbfdm_ctx->apply_event, 0, sizeof(struct ubus_event_handler)); memset(&bbfdm_ctx->apply_event, 0, sizeof(struct ubus_event_handler));
bbfdm_ctx->apply_event.cb = bbfdm_apply_event_cb; bbfdm_ctx->apply_event.cb = bbfdm_apply_event_cb;
ubus_register_event_handler(&bbfdm_ctx->ubus_ctx, &bbfdm_ctx->apply_event, "bbfdm.apply"); ubus_register_event_handler(bbfdm_ctx->ubus_ctx, &bbfdm_ctx->apply_event, "bbfdm.apply");
return 0;
}
static int bbfdm_ubus_init(struct bbfdm_context *bbfdm_ctx)
{
bbfdm_ctx->ubus_ctx = ubus_connect(NULL);
if (!bbfdm_ctx->ubus_ctx) {
BBF_ERR("Failed to connect to ubus");
return -1;
}
uloop_init();
ubus_add_uloop(bbfdm_ctx->ubus_ctx);
bbfdm_ctx->internal_ubus_ctx = true;
return 0;
} }
int bbfdm_ubus_register_init(struct bbfdm_context *bbfdm_ctx) int bbfdm_ubus_register_init(struct bbfdm_context *bbfdm_ctx)
{ {
int err = 0; int err = 0;
err = ubus_connect_ctx(&bbfdm_ctx->ubus_ctx, NULL);
if (err != UBUS_STATUS_OK) {
BBF_ERR("Failed to connect to ubus");
return -5; // Error code -5 indicating that ubus_ctx is not connected
}
// Set the logmask with default, if not already set by api // Set the logmask with default, if not already set by api
if (s_log_level == 0xff) { if (s_log_level == 0xff) {
BBF_INFO("Log level not set, setting default value %d", LOG_ERR); BBF_INFO("Log level not set, setting default value %d", LOG_ERR);
bbfdm_ubus_set_log_level(LOG_ERR); bbfdm_ubus_set_log_level(LOG_ERR);
} }
uloop_init(); if (bbfdm_ctx->ubus_ctx == NULL) {
ubus_add_uloop(&bbfdm_ctx->ubus_ctx); err = bbfdm_ubus_init(bbfdm_ctx);
if (err) {
BBF_ERR("Failed to initialize ubus_ctx internally");
return err;
}
}
bbfdm_ctx_init(bbfdm_ctx); bbfdm_ctx_init(bbfdm_ctx);
@ -1043,7 +1046,7 @@ int bbfdm_ubus_register_init(struct bbfdm_context *bbfdm_ctx)
return err; return err;
} }
err = regiter_ubus_object(&bbfdm_ctx->ubus_ctx); err = regiter_ubus_object(bbfdm_ctx);
if (err != UBUS_STATUS_OK) if (err != UBUS_STATUS_OK)
return -1; return -1;
@ -1053,20 +1056,30 @@ int bbfdm_ubus_register_init(struct bbfdm_context *bbfdm_ctx)
return -1; return -1;
} }
register_bbfdm_apply_event(bbfdm_ctx); err = register_bbfdm_apply_event(bbfdm_ctx);
if (err) {
BBF_ERR("Failed to register bbfdm apply event");
return -1;
}
return register_events_to_ubus(&bbfdm_ctx->ubus_ctx, &bbfdm_ctx->event_handlers); return register_events_to_ubus(bbfdm_ctx->ubus_ctx, &bbfdm_ctx->event_handlers);
} }
int bbfdm_ubus_register_free(struct bbfdm_context *bbfdm_ctx) int bbfdm_ubus_register_free(struct bbfdm_context *bbfdm_ctx)
{ {
free_apply_handlers(&bbfdm_ctx->config); free_apply_handlers(&bbfdm_ctx->config);
free_changed_uci(bbfdm_ctx); free_changed_uci(bbfdm_ctx);
ubus_unregister_event_handler(&bbfdm_ctx->ubus_ctx, &bbfdm_ctx->apply_event);
free_ubus_event_handler(&bbfdm_ctx->ubus_ctx, &bbfdm_ctx->event_handlers); if (bbfdm_ctx->ubus_ctx) {
ubus_unregister_event_handler(bbfdm_ctx->ubus_ctx, &bbfdm_ctx->apply_event);
free_ubus_event_handler(bbfdm_ctx->ubus_ctx, &bbfdm_ctx->event_handlers);
}
if (bbfdm_ctx->ubus_ctx && bbfdm_ctx->internal_ubus_ctx) {
ubus_free(bbfdm_ctx->ubus_ctx);
uloop_done();
}
bbfdm_ctx_cleanup(bbfdm_ctx); bbfdm_ctx_cleanup(bbfdm_ctx);
uloop_done();
ubus_shutdown(&bbfdm_ctx->ubus_ctx);
return 0; return 0;
} }

View file

@ -32,15 +32,18 @@ typedef struct bbfdm_config {
struct bbfdm_context { struct bbfdm_context {
bbfdm_config_t config; bbfdm_config_t config;
struct ubus_event_handler apply_event; struct ubus_event_handler apply_event;
struct ubus_context ubus_ctx; struct ubus_context *ubus_ctx;
struct ubus_object ubus_obj;
struct list_head event_handlers; struct list_head event_handlers;
struct uloop_timeout sync_timer; struct uloop_timeout sync_timer;
struct list_head changed_uci; struct list_head changed_uci;
bool internal_ubus_ctx;
char uci_change_proto[10]; char uci_change_proto[10];
}; };
typedef struct bbfdm_data { typedef struct bbfdm_data {
struct ubus_context *ctx; struct ubus_context *ctx;
struct ubus_object *obj;
struct ubus_request_data *req; struct ubus_request_data *req;
struct list_head *plist; struct list_head *plist;
struct dmctx bbf_ctx; struct dmctx bbf_ctx;

View file

@ -26,7 +26,7 @@ struct dm_path_node {
struct ev_handler_node { struct ev_handler_node {
char *ev_name; char *ev_name;
struct ubus_event_handler *ev_handler; struct ubus_event_handler ev_handler;
struct list_head dm_paths_list; // For dm path list struct list_head dm_paths_list; // For dm path list
struct list_head list; // For event list struct list_head list; // For event list
}; };
@ -68,26 +68,22 @@ void event_callback(const void *arg1, void *arg2)
free(e_args); free(e_args);
} }
static void bbfdm_event_handler(struct ubus_context *ctx, struct ubus_event_handler *ev, static void bbfdm_event_handler_cb(struct ubus_context *ctx __attribute__((unused)), struct ubus_event_handler *ev,
const char *type, struct blob_attr *msg) const char *type __attribute__((unused)), struct blob_attr *msg)
{ {
(void)ev;
struct ev_handler_node *ev_node = NULL; struct ev_handler_node *ev_node = NULL;
struct dm_path_node *dp_iter = NULL; struct dm_path_node *dp_iter = NULL;
struct bbfdm_context *u = NULL;
u = container_of(ctx, struct bbfdm_context, ubus_ctx); ev_node = container_of(ev, struct ev_handler_node, ev_handler);
if (u == NULL) { if (!ev_node) {
BBF_ERR("Failed to get the bbfdm context"); BBF_ERR("Failed to get event node");
return; return;
} }
if (!msg || !type) if (!msg) {
return; BBF_ERR("Failed to get message from event");
ev_node = get_event_node(&u->event_handlers, type);
if (!ev_node)
return; return;
}
list_for_each_entry(dp_iter, &ev_node->dm_paths_list, list) { list_for_each_entry(dp_iter, &ev_node->dm_paths_list, list) {
char dm_path[MAX_DM_PATH]; char dm_path[MAX_DM_PATH];
@ -185,13 +181,8 @@ static void add_ubus_event_handler(struct ubus_context *ctx, const char *ev_name
list_add_tail(&node->list, ev_list); list_add_tail(&node->list, ev_list);
node->ev_name = strdup(ev_name); node->ev_name = strdup(ev_name);
node->ev_handler = (struct ubus_event_handler *)calloc(1, sizeof(struct ubus_event_handler)); node->ev_handler.cb = bbfdm_event_handler_cb;
if (node->ev_handler) { ubus_register_event_handler(ctx, &node->ev_handler, ev_name);
node->ev_handler->cb = bbfdm_event_handler;
if (ubus_register_event_handler(ctx, node->ev_handler, ev_name) != 0) {
BBF_ERR("Failed to register: %s", ev_name);
}
}
} }
add_dm_path(node, dm_path); add_dm_path(node, dm_path);
@ -250,10 +241,7 @@ void free_ubus_event_handler(struct ubus_context *ctx, struct list_head *ev_list
return; return;
list_for_each_entry_safe(iter, tmp, ev_list, list) { list_for_each_entry_safe(iter, tmp, ev_list, list) {
if (iter->ev_handler != NULL) { ubus_unregister_event_handler(ctx, &iter->ev_handler);
ubus_unregister_event_handler(ctx, iter->ev_handler);
free(iter->ev_handler);
}
if (iter->ev_name) if (iter->ev_name)
free(iter->ev_name); free(iter->ev_name);