mirror of
https://dev.iopsys.eu/bbf/bbfdm.git
synced 2025-12-10 07:44:39 +01:00
Register external handler
This commit is contained in:
parent
227d121ee5
commit
2cd0a1ef6b
8 changed files with 707 additions and 101 deletions
|
|
@ -162,6 +162,7 @@ typedef struct dm_map_obj {
|
|||
struct dm_leaf_s *root_leaf;
|
||||
int (*init_module)(void *data);
|
||||
int (*clean_module)(void *data);
|
||||
int (*uci_sync_handler)(void);
|
||||
} DM_MAP_OBJ;
|
||||
|
||||
struct dm_reference {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "plugin.h"
|
||||
|
||||
#define BBFDM_DEFAULT_MICROSERVICE_MODULE_PATH "/usr/share/bbfdm/micro_services"
|
||||
#define BBFDM_SERVICE_CONFIG_PATH "/etc/bbfdm/services"
|
||||
|
||||
// Global variables
|
||||
static void *deamon_lib_handle = NULL;
|
||||
|
|
@ -636,6 +637,118 @@ static int regiter_ubus_object(struct ubus_context *ctx)
|
|||
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);
|
||||
}
|
||||
|
||||
static void free_apply_handlers(bbfdm_config_t *config)
|
||||
{
|
||||
struct apply_handler_node *node = NULL, *tmp = NULL;
|
||||
|
||||
if (config == NULL)
|
||||
return;
|
||||
|
||||
list_for_each_entry_safe(node, tmp, &config->apply_handlers, list) {
|
||||
list_del(&node->list);
|
||||
BBFDM_FREE(node->file_path);
|
||||
BBFDM_FREE(node);
|
||||
}
|
||||
}
|
||||
|
||||
static int load_apply_handlers_from_file(bbfdm_config_t *config)
|
||||
{
|
||||
char serv_config[MAX_DM_PATH] = {0};
|
||||
|
||||
if (config == NULL) {
|
||||
BBF_ERR("bbfdm_config is null");
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(serv_config, sizeof(serv_config), "%s/%s.json", BBFDM_SERVICE_CONFIG_PATH, config->service_name);
|
||||
if (!bbfdm_file_exists(serv_config) || !bbfdm_is_regular_file(serv_config)) {
|
||||
BBF_ERR("Config file %s not exists for service %s", serv_config, config->service_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
json_object *json_root = json_object_from_file(serv_config);
|
||||
if (!json_root) {
|
||||
BBF_ERR("Failed to read json file %s", serv_config);
|
||||
return -1;
|
||||
}
|
||||
|
||||
json_object *daemon_config = NULL;
|
||||
json_object_object_get_ex(json_root, "daemon", &daemon_config);
|
||||
if (!daemon_config) {
|
||||
BBFDM_ERR("Failed to find daemon object");
|
||||
json_object_put(json_root);
|
||||
return -1;
|
||||
}
|
||||
|
||||
json_object *apply_handler = NULL;
|
||||
json_object_object_get_ex(daemon_config, "apply_handler", &apply_handler);
|
||||
if (!apply_handler) {
|
||||
json_object_put(json_root);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char type[2][8] = { "dmmap", "uci" };
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
json_object *array = NULL;
|
||||
|
||||
if (!json_object_object_get_ex(apply_handler, type[i], &array) ||
|
||||
json_object_get_type(array) != json_type_array) {
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t count = json_object_array_length(array);
|
||||
for (size_t j = 0; j < count; j++) {
|
||||
json_object *hndl_obj = json_object_array_get_idx(array, j);
|
||||
json_object *files = NULL;
|
||||
|
||||
json_object_object_get_ex(hndl_obj, "file", &files);
|
||||
if (!files || json_object_get_type(files) != json_type_array) {
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t f_count = json_object_array_length(files);
|
||||
for (size_t k = 0; k < f_count; k++) {
|
||||
char path[MAX_DM_PATH] = {0};
|
||||
|
||||
json_object *f_inst = json_object_array_get_idx(files, k);
|
||||
snprintf(path, sizeof(path), "/etc/%s/%s",
|
||||
(strcmp(type[i], "uci") == 0) ? "config" : "bbfdm/dmmap", json_object_get_string(f_inst));
|
||||
|
||||
// check if already present
|
||||
bool exist = false;
|
||||
struct apply_handler_node *node = NULL;
|
||||
list_for_each_entry(node, &config->apply_handlers, list) {
|
||||
if (DM_STRCMP(node->file_path, path) == 0) {
|
||||
exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (exist == true)
|
||||
continue;
|
||||
|
||||
node = (struct apply_handler_node *)calloc(1, sizeof(struct apply_handler_node));
|
||||
if (node == NULL) {
|
||||
BBFDM_ERR("Failed to allocate memory for apply handlers");
|
||||
free_apply_handlers(config);
|
||||
json_object_put(json_root);
|
||||
return -1;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&node->list);
|
||||
list_add_tail(&node->list, &config->apply_handlers);
|
||||
|
||||
node->file_path = strdup(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json_object_put(json_root);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_micro_service_config(bbfdm_config_t *config)
|
||||
|
|
@ -647,6 +760,11 @@ static int load_micro_service_config(bbfdm_config_t *config)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (load_apply_handlers_from_file(config) != 0) {
|
||||
BBF_ERR("Failed to load handlers from service file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (INTERNAL_ROOT_TREE == NULL) {
|
||||
// This API will only be called with micro-services started with '-m' option
|
||||
|
||||
|
|
@ -709,6 +827,8 @@ int bbfdm_print_data_model_schema(struct bbfdm_context *bbfdm_ctx, const enum bb
|
|||
};
|
||||
int err = 0;
|
||||
|
||||
bbfdm_ctx_init(bbfdm_ctx);
|
||||
|
||||
err = load_micro_service_config(&bbfdm_ctx->config);
|
||||
if (err) {
|
||||
fprintf(stderr, "Failed to load micro-service config\n");
|
||||
|
|
@ -752,10 +872,86 @@ int bbfdm_print_data_model_schema(struct bbfdm_context *bbfdm_ctx, const enum bb
|
|||
|
||||
bbf_cleanup(&bbf_ctx);
|
||||
|
||||
free_apply_handlers(&bbfdm_ctx->config);
|
||||
|
||||
bbfdm_ctx_cleanup(bbfdm_ctx);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void perform_uci_sync_op(struct uloop_timeout *timeout)
|
||||
{
|
||||
DM_MAP_OBJ *dynamic_obj = INTERNAL_ROOT_TREE;
|
||||
|
||||
if (dynamic_obj == NULL)
|
||||
return;
|
||||
|
||||
for (int i = 0; dynamic_obj[i].path; i++) {
|
||||
if (dynamic_obj[i].uci_sync_handler) {
|
||||
dynamic_obj[i].uci_sync_handler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bbfdm_apply_event_cb(struct ubus_context *ctx __attribute__((unused)),
|
||||
struct ubus_event_handler *ev,
|
||||
const char *type __attribute__((unused)),
|
||||
struct blob_attr *msg)
|
||||
{
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
struct bbfdm_context *bbfdm_ctx = container_of(ev, struct bbfdm_context, apply_event);
|
||||
if (bbfdm_ctx == NULL)
|
||||
return;
|
||||
|
||||
bbfdm_config_t *config = &bbfdm_ctx->config;
|
||||
|
||||
const struct blobmsg_policy p[2] = {
|
||||
{ "proto", BLOBMSG_TYPE_STRING },
|
||||
{ "uci_changed", BLOBMSG_TYPE_ARRAY }
|
||||
};
|
||||
|
||||
struct blob_attr *tb[2] = {NULL, NULL};
|
||||
blobmsg_parse(p, 2, tb, blob_data(msg), blob_len(msg));
|
||||
|
||||
if (!tb[0] || !tb[1])
|
||||
return;
|
||||
|
||||
const char *proto = blobmsg_get_string(tb[0]);
|
||||
struct blob_attr *attr = NULL;
|
||||
int rem = 0;
|
||||
|
||||
blobmsg_for_each_attr(attr, tb[1], rem) {
|
||||
char *conf_name = blobmsg_get_string(attr);
|
||||
|
||||
/* Now check if the config file is intended file */
|
||||
struct apply_handler_node *node = NULL;
|
||||
|
||||
list_for_each_entry(node, &config->apply_handlers, list) {
|
||||
if (DM_STRCMP(node->file_path, conf_name) != 0)
|
||||
continue;
|
||||
|
||||
BBF_INFO("Scheduling UCI sync operation for changes performed by %s", proto);
|
||||
memset(&bbfdm_ctx->sync_timer, 0, sizeof(struct uloop_timeout));
|
||||
bbfdm_ctx->sync_timer.cb = perform_uci_sync_op;
|
||||
uloop_timeout_set(&bbfdm_ctx->sync_timer, 10);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void register_bbfdm_apply_event(struct bbfdm_context *bbfdm_ctx)
|
||||
{
|
||||
if (bbfdm_ctx == NULL)
|
||||
return;
|
||||
|
||||
memset(&bbfdm_ctx->apply_event, 0, sizeof(struct ubus_event_handler));
|
||||
bbfdm_ctx->apply_event.cb = bbfdm_apply_event_cb;
|
||||
|
||||
ubus_register_event_handler(&bbfdm_ctx->ubus_ctx, &bbfdm_ctx->apply_event, "bbfdm.apply");
|
||||
}
|
||||
|
||||
int bbfdm_ubus_regiter_init(struct bbfdm_context *bbfdm_ctx)
|
||||
{
|
||||
int err = 0, cur_log_mask=0;
|
||||
|
|
@ -800,11 +996,15 @@ int bbfdm_ubus_regiter_init(struct bbfdm_context *bbfdm_ctx)
|
|||
return -1;
|
||||
}
|
||||
|
||||
register_bbfdm_apply_event(bbfdm_ctx);
|
||||
|
||||
return register_events_to_ubus(&bbfdm_ctx->ubus_ctx, &bbfdm_ctx->event_handlers);
|
||||
}
|
||||
|
||||
int bbfdm_ubus_regiter_free(struct bbfdm_context *bbfdm_ctx)
|
||||
{
|
||||
free_apply_handlers(&bbfdm_ctx->config);
|
||||
ubus_unregister_event_handler(&bbfdm_ctx->ubus_ctx, &bbfdm_ctx->apply_event);
|
||||
free_ubus_event_handler(&bbfdm_ctx->ubus_ctx, &bbfdm_ctx->event_handlers);
|
||||
bbfdm_ctx_cleanup(bbfdm_ctx);
|
||||
uloop_done();
|
||||
|
|
|
|||
|
|
@ -16,7 +16,13 @@ struct bbfdm_async_req {
|
|||
void *result;
|
||||
};
|
||||
|
||||
struct apply_handler_node {
|
||||
char *file_path;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
typedef struct bbfdm_config {
|
||||
struct list_head apply_handlers;
|
||||
char service_name[32]; // Service name for micro-service identification
|
||||
char in_name[128]; // Service plugin path
|
||||
char in_plugin_dir[128]; // Service extra/internal plugin directory path
|
||||
|
|
@ -25,8 +31,10 @@ typedef struct bbfdm_config {
|
|||
|
||||
struct bbfdm_context {
|
||||
bbfdm_config_t config;
|
||||
struct ubus_event_handler apply_event;
|
||||
struct ubus_context ubus_ctx;
|
||||
struct list_head event_handlers;
|
||||
struct uloop_timeout sync_timer;
|
||||
};
|
||||
|
||||
typedef struct bbfdm_data {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ OBJS = src/ubus/bbf_config.o src/ubus/utils.o
|
|||
|
||||
PROG_CFLAGS = $(CFLAGS) -Wall -Werror
|
||||
PROG_LDFLAGS = $(LDFLAGS)
|
||||
PROG_LIBS += -luci -lubus -lubox -lblobmsg_json
|
||||
PROG_LIBS += -luci -lubus -lubox -lblobmsg_json -ljson-c
|
||||
|
||||
INSTALL_DIR = /usr/sbin
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Script: bbf_default_reload.sh
|
||||
# Description:
|
||||
# This script reloads UCI Configs based on input args.
|
||||
# Input args should be space separated uci file names
|
||||
#
|
||||
# Usage:
|
||||
# sh bbf_default_reload.sh network firewall
|
||||
#
|
||||
# Actions:
|
||||
# - performs "ubus call uci commit '{"config":"<uci name>"}' for
|
||||
# each uci file received in argument list
|
||||
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
log() {
|
||||
echo "${@}"|logger -t bbf.config.default.reload -p info
|
||||
}
|
||||
|
||||
input="$@"
|
||||
|
||||
# Validate input
|
||||
if [ -z "$input" ]; then
|
||||
log "Error: No input provided"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for uci in ${input}; do
|
||||
log "Reloading ${uci} config"
|
||||
|
||||
json_init
|
||||
json_add_string "config" "${uci}"
|
||||
json_compact
|
||||
|
||||
json_data=$(json_dump)
|
||||
ubus -t 5 call uci commit "${json_data}"
|
||||
|
||||
json_cleanup
|
||||
done
|
||||
|
||||
exit 0
|
||||
|
|
@ -14,6 +14,8 @@
|
|||
#include <libubox/blobmsg_json.h>
|
||||
#include <libubox/uloop.h>
|
||||
#include <libubus.h>
|
||||
#include <json-c/json.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
|
@ -26,6 +28,7 @@
|
|||
|
||||
#define BBF_CONFIG_DAEMON_NAME "bbf_configd"
|
||||
#define CRITICAL_DEF_JSON "/etc/bbfdm/critical_services.json"
|
||||
#define BBFDM_MICROSERVICE_INPUT_PATH "/etc/bbfdm/services"
|
||||
|
||||
// Structure to represent an instance of a service
|
||||
struct instance {
|
||||
|
|
@ -48,14 +51,17 @@ struct config_package {
|
|||
};
|
||||
|
||||
struct bbf_config_async_req {
|
||||
int idx;
|
||||
struct ubus_context *ctx;
|
||||
struct ubus_request_data req;
|
||||
struct uloop_timeout timeout;
|
||||
struct blob_attr *services;
|
||||
struct config_package package[MAX_PACKAGE_NUM];
|
||||
struct list_head changed_uci_list;
|
||||
};
|
||||
|
||||
static struct blob_buf g_critical_bb;
|
||||
static struct list_head g_apply_handlers;
|
||||
|
||||
#ifdef BBF_CONFIG_DEBUG
|
||||
static void log_instance(struct instance *inst)
|
||||
|
|
@ -475,6 +481,48 @@ static void send_bbf_config_change_event()
|
|||
ubus_free(ctx);
|
||||
}
|
||||
|
||||
static void send_bbf_apply_event(int idx, struct list_head *changed_uci_list)
|
||||
{
|
||||
if (changed_uci_list == NULL || list_empty(changed_uci_list))
|
||||
return;
|
||||
|
||||
struct ubus_context *ctx;
|
||||
struct blob_buf bb = {0};
|
||||
struct modi_uci_node *node = NULL, *tmp = NULL;
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
blobmsg_add_string(&bb, "proto", get_proto_name_by_idx(idx));
|
||||
void *array = blobmsg_open_array(&bb, "uci_changed");
|
||||
list_for_each_entry_safe(node, tmp, changed_uci_list, list) {
|
||||
if (node->uci == NULL) {
|
||||
list_del(&node->list);
|
||||
FREE(node);
|
||||
continue;
|
||||
}
|
||||
|
||||
blobmsg_add_string(&bb, NULL, node->uci);
|
||||
list_del(&node->list);
|
||||
FREE(node->uci);
|
||||
FREE(node);
|
||||
}
|
||||
blobmsg_close_array(&bb, array);
|
||||
|
||||
ctx = ubus_connect(NULL);
|
||||
if (ctx == NULL) {
|
||||
ULOG_ERR("Can't create UBUS context for 'bbfdm.apply' event");
|
||||
blob_buf_free(&bb);
|
||||
return;
|
||||
}
|
||||
|
||||
ULOG_INFO("Sending bbfdm.apply event");
|
||||
|
||||
ubus_send_event(ctx, "bbfdm.apply", bb.head);
|
||||
blob_buf_free(&bb);
|
||||
ubus_free(ctx);
|
||||
}
|
||||
|
||||
static void send_reply(struct ubus_context *ctx, struct ubus_request_data *req, const char *message, const char *description)
|
||||
{
|
||||
struct blob_buf bb = {0};
|
||||
|
|
@ -498,13 +546,14 @@ static void complete_deferred_request(struct bbf_config_async_req *async_req)
|
|||
// Complete the deferred request and send the response
|
||||
ubus_complete_deferred_request(async_req->ctx, &async_req->req, 0);
|
||||
|
||||
// Send 'bbf.config.change' event to run refresh instances
|
||||
send_bbf_config_change_event();
|
||||
send_bbf_apply_event(async_req->idx, &async_req->changed_uci_list);
|
||||
|
||||
// Free the allocated memory
|
||||
FREE(async_req->services);
|
||||
FREE(async_req);
|
||||
|
||||
// Send 'bbf.config.change' event to run refresh instances
|
||||
send_bbf_config_change_event();
|
||||
|
||||
// Set internal commit to false
|
||||
g_internal_commit = false;
|
||||
|
||||
|
|
@ -607,9 +656,11 @@ static int bbf_config_commit_handler(struct ubus_context *ctx, struct ubus_objec
|
|||
struct blob_attr *tb[__MAX];
|
||||
bool monitor = false, reload = true;
|
||||
unsigned char idx = 0;
|
||||
uint32_t wifi_config_flags = 0;
|
||||
struct list_head action_list;
|
||||
struct list_head *changed_uci;
|
||||
|
||||
ULOG_INFO("Commit handler called");
|
||||
INIT_LIST_HEAD(&action_list);
|
||||
|
||||
if (blobmsg_parse(bbf_config_policy, __MAX, tb, blob_data(msg), blob_len(msg))) {
|
||||
send_reply(ctx, req, "error", "Failed to parse blob");
|
||||
|
|
@ -622,6 +673,9 @@ static int bbf_config_commit_handler(struct ubus_context *ctx, struct ubus_objec
|
|||
return -1;
|
||||
}
|
||||
|
||||
changed_uci = &async_req->changed_uci_list;
|
||||
INIT_LIST_HEAD(changed_uci);
|
||||
|
||||
// Set internal commit to true
|
||||
g_internal_commit = true;
|
||||
|
||||
|
|
@ -669,21 +723,42 @@ static int bbf_config_commit_handler(struct ubus_context *ctx, struct ubus_objec
|
|||
}
|
||||
|
||||
ULOG_INFO("Committing changes for specified services and reloading");
|
||||
reload_specified_services(ctx, idx, async_req->services, true, reload, &wifi_config_flags);
|
||||
reload_specified_services(ctx, idx, async_req->services, true, reload, &action_list,
|
||||
&g_apply_handlers, changed_uci);
|
||||
} else {
|
||||
ULOG_INFO("Applying changes to dmmap UCI config");
|
||||
uci_apply_changes(DMMAP_CONFDIR, idx, true); // commit dmmap changes
|
||||
uci_apply_changes_dmmap(idx, true, &action_list, &g_apply_handlers);
|
||||
ULOG_INFO("Committing changes for all services and reloading");
|
||||
reload_all_services(ctx, idx, true, reload, &wifi_config_flags);
|
||||
reload_all_services(ctx, idx, true, reload, &action_list, &g_apply_handlers, changed_uci);
|
||||
}
|
||||
|
||||
if (wifi_config_flags) {
|
||||
ULOG_ERR("Reloading changes for wifi services");
|
||||
wifi_reload_handler_script(wifi_config_flags);
|
||||
struct action_node *node = NULL, *tmp = NULL;
|
||||
list_for_each_entry_safe(node, tmp, &action_list, list) {
|
||||
char cmd[4096] = {0};
|
||||
unsigned pos = 0;
|
||||
|
||||
ULOG_INFO("Reloading changes");
|
||||
|
||||
if (!file_exists(node->action)) {
|
||||
list_del(&node->list);
|
||||
FREE(node);
|
||||
continue;
|
||||
}
|
||||
|
||||
pos += snprintf(cmd, sizeof(cmd), "sh %s", node->action);
|
||||
|
||||
for (int i = 0; i < node->idx; i++) {
|
||||
pos += snprintf(&cmd[pos], sizeof(cmd) - pos, " %s", node->arg[i]);
|
||||
}
|
||||
|
||||
exec_apply_handler_script(cmd);
|
||||
list_del(&node->list);
|
||||
FREE(node);
|
||||
}
|
||||
|
||||
if (monitor) {
|
||||
ULOG_INFO("Deferring request and setting up async completion");
|
||||
async_req->idx = idx;
|
||||
ubus_defer_request(ctx, req, &async_req->req);
|
||||
async_req->timeout.cb = complete_request_callback;
|
||||
uloop_timeout_set(&async_req->timeout, 2000);
|
||||
|
|
@ -691,13 +766,14 @@ static int bbf_config_commit_handler(struct ubus_context *ctx, struct ubus_objec
|
|||
ULOG_INFO("Sending immediate success response");
|
||||
send_reply(ctx, req, "status", "ok");
|
||||
|
||||
// Send 'bbf.config.change' event to run refresh instances
|
||||
send_bbf_config_change_event();
|
||||
send_bbf_apply_event(idx, changed_uci);
|
||||
|
||||
// Free the allocated memory
|
||||
FREE(async_req->services);
|
||||
FREE(async_req);
|
||||
|
||||
// Send 'bbf.config.change' event to run refresh instances
|
||||
send_bbf_config_change_event();
|
||||
|
||||
// Set internal commit to false
|
||||
g_internal_commit = false;
|
||||
|
||||
|
|
@ -733,12 +809,12 @@ static int bbf_config_revert_handler(struct ubus_context *ctx, struct ubus_objec
|
|||
|
||||
if (arr_len) {
|
||||
ULOG_INFO("Reverting specified services");
|
||||
reload_specified_services(ctx, idx, services, false, false, NULL);
|
||||
reload_specified_services(ctx, idx, services, false, false, NULL, NULL, NULL);
|
||||
} else {
|
||||
ULOG_INFO("Applying changes to dmmap UCI config");
|
||||
uci_apply_changes(DMMAP_CONFDIR, idx, false); // revert dmmap changes
|
||||
ULOG_INFO("Reverting changes to dmmap UCI config");
|
||||
uci_apply_changes_dmmap(idx, false, NULL, NULL); // revert dmmap changes
|
||||
ULOG_INFO("Reverting all services");
|
||||
reload_all_services(ctx, idx, false, false, NULL);
|
||||
reload_all_services(ctx, idx, false, false, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
ULOG_INFO("Sending success response");
|
||||
|
|
@ -796,6 +872,164 @@ static void load_critical_services()
|
|||
blobmsg_add_json_from_file(&g_critical_bb, CRITICAL_DEF_JSON);
|
||||
}
|
||||
|
||||
static int filter(const struct dirent *entry)
|
||||
{
|
||||
return entry->d_name[0] != '.';
|
||||
}
|
||||
|
||||
static int compare(const struct dirent **a, const struct dirent **b)
|
||||
{
|
||||
size_t len_a = strlen((*a)->d_name);
|
||||
size_t len_b = strlen((*b)->d_name);
|
||||
|
||||
if (len_a < len_b) // Sort by length (shorter first)
|
||||
return -1;
|
||||
|
||||
if (len_a > len_b)
|
||||
return 1;
|
||||
|
||||
return strcasecmp((*a)->d_name, (*b)->d_name); // If lengths are equal, sort alphabetically
|
||||
}
|
||||
|
||||
static void free_apply_handlers()
|
||||
{
|
||||
struct applier_node *node = NULL, *tmp = NULL;
|
||||
|
||||
list_for_each_entry_safe(node, tmp, &g_apply_handlers, list) {
|
||||
list_del(&node->list);
|
||||
FREE(node->file_path);
|
||||
FREE(node->action);
|
||||
FREE(node);
|
||||
}
|
||||
}
|
||||
|
||||
static void __load_handlers(const char *file)
|
||||
{
|
||||
if (file == NULL || strlen(file) == 0)
|
||||
return;
|
||||
|
||||
json_object *json_root = json_object_from_file(file);
|
||||
if (!json_root) {
|
||||
ULOG_INFO("Failed to read json file %s", file);
|
||||
return;
|
||||
}
|
||||
|
||||
json_object *daemon_config = NULL;
|
||||
json_object_object_get_ex(json_root, "daemon", &daemon_config);
|
||||
if (!daemon_config) {
|
||||
ULOG_INFO("Failed to find daemon object");
|
||||
json_object_put(json_root);
|
||||
return;
|
||||
}
|
||||
|
||||
json_object *apply_handler = NULL;
|
||||
json_object_object_get_ex(daemon_config, "apply_handler", &apply_handler);
|
||||
if (!apply_handler) {
|
||||
json_object_put(json_root);
|
||||
return;
|
||||
}
|
||||
|
||||
char type[2][8] = { "dmmap", "uci" };
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
json_object *array = NULL;
|
||||
|
||||
if (!json_object_object_get_ex(apply_handler, type[i], &array) ||
|
||||
json_object_get_type(array) != json_type_array) {
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t count = json_object_array_length(array);
|
||||
for (size_t j = 0; j < count; j++) {
|
||||
json_object *hndl_obj = json_object_array_get_idx(array, j);
|
||||
json_object *files = NULL, *handler = NULL;
|
||||
|
||||
json_object_object_get_ex(hndl_obj, "external_handler", &handler);
|
||||
if (!handler) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char *action = json_object_get_string(handler);
|
||||
if (strlen(action) == 0 || !file_exists(action)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
json_object_object_get_ex(hndl_obj, "file", &files);
|
||||
if (!files || json_object_get_type(files) != json_type_array) {
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t f_count = json_object_array_length(files);
|
||||
for (size_t k = 0; k < f_count; k++) {
|
||||
char path[1024] = {0};
|
||||
|
||||
json_object *f_inst = json_object_array_get_idx(files, k);
|
||||
snprintf(path, sizeof(path), "/etc/%s/%s",
|
||||
(strcmp(type[i], "uci") == 0) ? "config" : "bbfdm/dmmap", json_object_get_string(f_inst));
|
||||
|
||||
|
||||
// check if already present
|
||||
bool exist = false;
|
||||
struct applier_node *node = NULL;
|
||||
list_for_each_entry(node, &g_apply_handlers, list) {
|
||||
if (strcmp(node->file_path, path) == 0 && strcmp(node->action, action) == 0) {
|
||||
exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (exist == true)
|
||||
continue;
|
||||
|
||||
node = (struct applier_node *)calloc(1, sizeof(struct applier_node));
|
||||
if (node == NULL) {
|
||||
ULOG_INFO("Failed to allocate memory for apply handlers");
|
||||
json_object_put(json_root);
|
||||
return;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&node->list);
|
||||
list_add_tail(&node->list, &g_apply_handlers);
|
||||
|
||||
node->file_path = strdup(path);
|
||||
node->action = strdup(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json_object_put(json_root);
|
||||
return;
|
||||
}
|
||||
|
||||
static void load_apply_handlers()
|
||||
{
|
||||
struct dirent **namelist;
|
||||
|
||||
INIT_LIST_HEAD(&g_apply_handlers);
|
||||
|
||||
int num_files = scandir(BBFDM_MICROSERVICE_INPUT_PATH, &namelist, filter, compare);
|
||||
|
||||
for (int i = 0; i < num_files; i++) {
|
||||
char file_path[512] = {0};
|
||||
|
||||
snprintf(file_path, sizeof(file_path), "%s/%s", BBFDM_MICROSERVICE_INPUT_PATH, namelist[i]->d_name);
|
||||
|
||||
if (!file_exists(file_path) || !regular_file(file_path)) {
|
||||
free(namelist[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
__load_handlers(file_path);
|
||||
|
||||
free(namelist[i]);
|
||||
}
|
||||
|
||||
if (namelist)
|
||||
free(namelist);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct ubus_event_handler ev = {
|
||||
|
|
@ -835,6 +1069,7 @@ int main(int argc, char **argv)
|
|||
ubus_add_uloop(uctx);
|
||||
|
||||
load_critical_services();
|
||||
load_apply_handlers();
|
||||
|
||||
if (ubus_add_object(uctx, &bbf_config_object)) {
|
||||
ULOG_ERR("Failed to add 'bbf.config' ubus object");
|
||||
|
|
@ -849,6 +1084,7 @@ int main(int argc, char **argv)
|
|||
uloop_run();
|
||||
|
||||
exit:
|
||||
free_apply_handlers();
|
||||
blob_buf_free(&g_critical_bb);
|
||||
uloop_done();
|
||||
ubus_free(uctx);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <libubus.h>
|
||||
#include <uci.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
|
|
@ -35,6 +36,136 @@ static struct proto_args supported_protocols[] = {
|
|||
},
|
||||
};
|
||||
|
||||
static void add_external_action_list(struct list_head *action_list, struct list_head *ext_handler, const char *file_path)
|
||||
{
|
||||
if (file_path == NULL || strlen(file_path) == 0 || action_list == NULL)
|
||||
return;
|
||||
|
||||
struct applier_node *app_node = NULL;
|
||||
bool ext_exist = false;
|
||||
|
||||
char *config = strrchr(file_path, '/');
|
||||
if (config) {
|
||||
config = config + 1;
|
||||
}
|
||||
|
||||
list_for_each_entry(app_node, ext_handler, list) {
|
||||
if (strcmp(app_node->file_path, file_path) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ext_exist = true;
|
||||
|
||||
bool node_exist = false;
|
||||
bool arg_exist = false;
|
||||
struct action_node *act_node = NULL;
|
||||
|
||||
list_for_each_entry(act_node, action_list, list) {
|
||||
if (strcmp(app_node->action, act_node->action) == 0) {
|
||||
node_exist = true;
|
||||
for (int i = 0; i < act_node->idx; i++) {
|
||||
if (strcmp(act_node->arg[i], config) == 0) {
|
||||
arg_exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (node_exist == false) {
|
||||
act_node = (struct action_node *)calloc(1, sizeof(struct action_node));
|
||||
if (act_node == NULL) {
|
||||
ULOG_INFO("Failed to allocate memory for action list");
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(act_node->action, sizeof(act_node->action), "%s", app_node->action);
|
||||
INIT_LIST_HEAD(&act_node->list);
|
||||
list_add_tail(&act_node->list, action_list);
|
||||
}
|
||||
|
||||
if (arg_exist == false && act_node->idx < ARG_COUNT) {
|
||||
snprintf(act_node->arg[act_node->idx], ARG_LEN, "%s", config);
|
||||
act_node->idx = act_node->idx + 1;
|
||||
ULOG_DEBUG("Added %s handler for %s config", act_node->action, config);
|
||||
}
|
||||
}
|
||||
|
||||
if (ext_exist == true || strncmp(file_path, DMMAP_CONFDIR, strlen(DMMAP_CONFDIR)) == 0) {
|
||||
/* external handler exist, so already added in list or
|
||||
* the file is a dmmap file so it has no default handler
|
||||
* to add in the action list */
|
||||
return;
|
||||
}
|
||||
|
||||
/* external handler not exist, add default handler */
|
||||
struct action_node *act_node = NULL;
|
||||
bool node_exist = false;
|
||||
bool arg_exist = false;
|
||||
|
||||
list_for_each_entry(act_node, action_list, list) {
|
||||
if (strcmp(app_node->action, DEFAULT_HANDLER_ACT) == 0) {
|
||||
node_exist = true;
|
||||
for (int i = 0; i < act_node->idx; i++) {
|
||||
if (strcmp(act_node->arg[i], config) == 0) {
|
||||
arg_exist = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (node_exist == false) {
|
||||
act_node = (struct action_node *)calloc(1, sizeof(struct action_node));
|
||||
if (act_node == NULL) {
|
||||
ULOG_INFO("Failed to allocate memory for action list");
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(act_node->action, sizeof(act_node->action), "%s", DEFAULT_HANDLER_ACT);
|
||||
INIT_LIST_HEAD(&act_node->list);
|
||||
list_add_tail(&act_node->list, action_list);
|
||||
}
|
||||
|
||||
if (arg_exist == false && act_node->idx < ARG_COUNT) {
|
||||
snprintf(act_node->arg[act_node->idx], ARG_LEN, "%s", config);
|
||||
act_node->idx = act_node->idx + 1;
|
||||
ULOG_DEBUG("Added default handler for %s config", config);
|
||||
}
|
||||
}
|
||||
|
||||
static void add_changed_uci_list(struct list_head *changed_uci, const char *file_path)
|
||||
{
|
||||
if (changed_uci == NULL || file_path == NULL || strlen(file_path) == 0)
|
||||
return;
|
||||
|
||||
struct modi_uci_node *node = NULL;
|
||||
bool exist = false;
|
||||
|
||||
list_for_each_entry(node, changed_uci, list) {
|
||||
if (!node->uci || strcmp(node->uci, file_path) != 0)
|
||||
continue;
|
||||
|
||||
exist = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (exist)
|
||||
return;
|
||||
|
||||
node = (struct modi_uci_node *)calloc(1, sizeof(struct modi_uci_node));
|
||||
if (!node) {
|
||||
ULOG_INFO("Failed to allocate memory for changed uci list");
|
||||
return;
|
||||
}
|
||||
|
||||
node->uci = strdup(file_path);
|
||||
INIT_LIST_HEAD(&node->list);
|
||||
list_add_tail(&node->list, changed_uci);
|
||||
}
|
||||
|
||||
unsigned char get_idx_by_proto(const char *proto)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_SIZE(supported_protocols); i++) {
|
||||
|
|
@ -93,24 +224,6 @@ bool file_exists(const char *path)
|
|||
return stat(path, &buffer) == 0;
|
||||
}
|
||||
|
||||
static bool is_wifi_configs(const char *config_name, uint32_t *wifi_config_flags)
|
||||
{
|
||||
if (!config_name && !wifi_config_flags)
|
||||
return false;
|
||||
|
||||
if (strcmp(config_name, "wireless") == 0) {
|
||||
*wifi_config_flags |= WIRELESS_CONFIG;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp(config_name, "mapcontroller") == 0) {
|
||||
*wifi_config_flags |= MAPCONTROLLER_CONFIG;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int bbf_config_call(struct ubus_context *ctx, const char *object, const char *method, struct blob_buf *data, ubus_data_handler_t callback, void *arg)
|
||||
{
|
||||
int fault = 0;
|
||||
|
|
@ -136,34 +249,9 @@ int bbf_config_call(struct ubus_context *ctx, const char *object, const char *me
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void reload_service(struct ubus_context *ctx, const char *config_name, bool is_commit)
|
||||
{
|
||||
struct blob_buf bb = {0};
|
||||
|
||||
if (!ctx || !config_name) {
|
||||
ULOG_ERR("Failed to reload service: 'ctx' or 'config_name' is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(&bb, 0, sizeof(struct blob_buf));
|
||||
|
||||
blob_buf_init(&bb, 0);
|
||||
|
||||
blobmsg_add_string(&bb, "config", config_name);
|
||||
|
||||
int result = bbf_config_call(ctx, "uci", (is_commit) ? "commit" : "revert", &bb, NULL, NULL);
|
||||
if (result != 0) {
|
||||
ULOG_ERR("Failed to %s configuration '%s'", (is_commit ? "commit" : "revert"), config_name);
|
||||
} else {
|
||||
ULOG_DEBUG("Successfully executed %s on configuration '%s'.", (is_commit ? "commit" : "revert"), config_name);
|
||||
}
|
||||
|
||||
blob_buf_free(&bb);
|
||||
}
|
||||
|
||||
|
||||
void reload_specified_services(struct ubus_context *ctx, int idx, struct blob_attr *services,
|
||||
bool is_commit, bool reload, uint32_t *wifi_config_flags)
|
||||
bool is_commit, bool reload, struct list_head *action_list,
|
||||
struct list_head *handler_list, struct list_head *changed_uci)
|
||||
{
|
||||
struct uci_context *uci_ctx = NULL;
|
||||
struct blob_attr *service = NULL;
|
||||
|
|
@ -210,6 +298,9 @@ void reload_specified_services(struct ubus_context *ctx, int idx, struct blob_at
|
|||
|
||||
ULOG_DEBUG("Looking up UCI configuration for service '%s'", config_name);
|
||||
|
||||
char file_path[1024] = {0};
|
||||
snprintf(file_path, sizeof(file_path), "%s%s", conf_dir, package);
|
||||
|
||||
if (uci_lookup_ptr(uci_ctx, &ptr, package, true) != UCI_OK) {
|
||||
ULOG_ERR("Failed to lookup UCI pointer for service '%s'. Skipping", config_name);
|
||||
continue;
|
||||
|
|
@ -221,6 +312,10 @@ void reload_specified_services(struct ubus_context *ctx, int idx, struct blob_at
|
|||
ULOG_ERR("Failed to commit UCI changes for service '%s'", config_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_dmmap) {
|
||||
add_changed_uci_list(changed_uci, file_path);
|
||||
}
|
||||
} else {
|
||||
ULOG_DEBUG("Reverting UCI changes for service '%s'", config_name);
|
||||
if (uci_revert(uci_ctx, &ptr) != UCI_OK) {
|
||||
|
|
@ -229,12 +324,12 @@ void reload_specified_services(struct ubus_context *ctx, int idx, struct blob_at
|
|||
}
|
||||
}
|
||||
|
||||
if (reload && !is_dmmap) {
|
||||
if (is_wifi_configs(package, wifi_config_flags))
|
||||
continue;
|
||||
if (is_commit && is_dmmap) {
|
||||
add_external_action_list(action_list, handler_list, file_path);
|
||||
}
|
||||
|
||||
ULOG_INFO("Reloading service '%s'", package);
|
||||
reload_service(ctx, package, is_commit);
|
||||
if (reload && !is_dmmap) {
|
||||
add_external_action_list(action_list, handler_list, file_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -243,7 +338,8 @@ void reload_specified_services(struct ubus_context *ctx, int idx, struct blob_at
|
|||
}
|
||||
|
||||
void reload_all_services(struct ubus_context *ctx, int idx, bool is_commit,
|
||||
bool reload, uint32_t *wifi_config_flags)
|
||||
bool reload, struct list_head *action_list,
|
||||
struct list_head *handler_list, struct list_head *changed_uci)
|
||||
{
|
||||
struct uci_context *uci_ctx = NULL;
|
||||
char **configs = NULL, **p = NULL;
|
||||
|
|
@ -271,6 +367,8 @@ void reload_all_services(struct ubus_context *ctx, int idx, bool is_commit,
|
|||
struct uci_ptr ptr = {0};
|
||||
|
||||
ULOG_DEBUG("Looking up UCI configuration for '%s'", *p);
|
||||
char file_path[1024] = {0};
|
||||
snprintf(file_path, sizeof(file_path), "%s%s", CONFIG_CONFDIR, *p);
|
||||
|
||||
if (uci_lookup_ptr(uci_ctx, &ptr, *p, true) != UCI_OK) {
|
||||
ULOG_ERR("Failed to lookup UCI pointer for config '%s'. Skipping", *p);
|
||||
|
|
@ -288,6 +386,8 @@ void reload_all_services(struct ubus_context *ctx, int idx, bool is_commit,
|
|||
ULOG_ERR("Failed to commit changes for config '%s'", *p);
|
||||
continue;
|
||||
}
|
||||
|
||||
add_changed_uci_list(changed_uci, file_path);
|
||||
} else {
|
||||
ULOG_DEBUG("Reverting UCI changes for config '%s'", *p);
|
||||
if (uci_revert(uci_ctx, &ptr) != UCI_OK) {
|
||||
|
|
@ -297,11 +397,7 @@ void reload_all_services(struct ubus_context *ctx, int idx, bool is_commit,
|
|||
}
|
||||
|
||||
if (reload) {
|
||||
if (is_wifi_configs(*p, wifi_config_flags))
|
||||
continue;
|
||||
|
||||
ULOG_INFO("Reloading service for config '%s'", *p);
|
||||
reload_service(ctx, *p, is_commit);
|
||||
add_external_action_list(action_list, handler_list, file_path);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -311,26 +407,15 @@ exit:
|
|||
uci_free_context(uci_ctx);
|
||||
}
|
||||
|
||||
void wifi_reload_handler_script(uint32_t wifi_config_flags)
|
||||
void exec_apply_handler_script(const char *cmd)
|
||||
{
|
||||
#define WIFI_CONFIG_RELOAD_SCRIPT "/etc/wifidmd/bbf_config_reload.sh"
|
||||
char cmd[512] = {0};
|
||||
|
||||
if (!file_exists(WIFI_CONFIG_RELOAD_SCRIPT))
|
||||
return;
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "sh %s '{\"wireless\":\"%d\",\"mapcontroller\":\"%d\"}'",
|
||||
WIFI_CONFIG_RELOAD_SCRIPT,
|
||||
wifi_config_flags & WIRELESS_CONFIG ? 1 : 0,
|
||||
wifi_config_flags & MAPCONTROLLER_CONFIG ? 1 : 0);
|
||||
|
||||
FILE *pp = popen(cmd, "r"); // flawfinder: ignore
|
||||
if (pp) {
|
||||
pclose(pp);
|
||||
}
|
||||
}
|
||||
|
||||
void uci_apply_changes(const char *conf_dir, int idx, bool is_commit)
|
||||
void uci_apply_changes_dmmap(int idx, bool is_commit, struct list_head *action_list, struct list_head *ext_handler)
|
||||
{
|
||||
struct uci_context *uci_ctx = NULL;
|
||||
char **configs = NULL, **p = NULL;
|
||||
|
|
@ -342,16 +427,9 @@ void uci_apply_changes(const char *conf_dir, int idx, bool is_commit)
|
|||
return;
|
||||
}
|
||||
|
||||
if (conf_dir) {
|
||||
ULOG_DEBUG("Setting UCI configuration directory to '%s'", conf_dir);
|
||||
uci_set_confdir(uci_ctx, conf_dir);
|
||||
|
||||
if (strcmp(conf_dir, DMMAP_CONFDIR) == 0) {
|
||||
snprintf(save_dir, sizeof(save_dir), "%s", get_proto_dmmap_savedir_by_idx(idx));
|
||||
} else if(strcmp(conf_dir, CONFIG_CONFDIR) == 0) {
|
||||
snprintf(save_dir, sizeof(save_dir), "%s", get_proto_conf_savedir_by_idx(idx));
|
||||
}
|
||||
}
|
||||
ULOG_DEBUG("Setting UCI configuration directory to '%s'", DMMAP_CONFDIR);
|
||||
uci_set_confdir(uci_ctx, DMMAP_CONFDIR);
|
||||
snprintf(save_dir, sizeof(save_dir), "%s", get_proto_dmmap_savedir_by_idx(idx));
|
||||
|
||||
ULOG_DEBUG("Setting UCI save directory to '%s'", save_dir);
|
||||
uci_set_savedir(uci_ctx, save_dir);
|
||||
|
|
@ -378,6 +456,10 @@ void uci_apply_changes(const char *conf_dir, int idx, bool is_commit)
|
|||
ULOG_ERR("Failed to commit changes for config '%s'", *p);
|
||||
continue;
|
||||
}
|
||||
|
||||
char file_path[1024] = {0};
|
||||
snprintf(file_path, sizeof(file_path), "%s%s", DMMAP_CONFDIR, *p);
|
||||
add_external_action_list(action_list, ext_handler, file_path);
|
||||
} else {
|
||||
ULOG_DEBUG("Reverting changes for config '%s'", *p);
|
||||
if (uci_revert(uci_ctx, &ptr) != UCI_OK) {
|
||||
|
|
@ -392,3 +474,13 @@ void uci_apply_changes(const char *conf_dir, int idx, bool is_commit)
|
|||
exit:
|
||||
uci_free_context(uci_ctx);
|
||||
}
|
||||
|
||||
bool regular_file(const char *path)
|
||||
{
|
||||
struct stat buffer;
|
||||
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
return stat(path, &buffer) == 0 && S_ISREG(buffer.st_mode);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,29 +27,56 @@
|
|||
|
||||
#define CONFIG_CONFDIR "/etc/config/"
|
||||
#define DMMAP_CONFDIR "/etc/bbfdm/dmmap/"
|
||||
#define DEFAULT_HANDLER_ACT "/etc/bbfdm/bbf_default_reload.sh"
|
||||
#define ARG_LEN 64
|
||||
#define ARG_COUNT 40
|
||||
#define ACTION_LEN 512
|
||||
|
||||
enum wifi_config_flags_enum {
|
||||
WIRELESS_CONFIG = 1,
|
||||
MAPCONTROLLER_CONFIG = 1<<1,
|
||||
};
|
||||
|
||||
struct applier_node {
|
||||
char *file_path;
|
||||
char *action;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct action_node {
|
||||
struct list_head list;
|
||||
char action[ACTION_LEN];
|
||||
char arg[ARG_COUNT][ARG_LEN];
|
||||
int idx;
|
||||
};
|
||||
|
||||
struct modi_uci_node {
|
||||
char *uci;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
void strncpyt(char *dst, const char *src, size_t n);
|
||||
|
||||
int bbf_config_call(struct ubus_context *ctx, const char *object, const char *method, struct blob_buf *data, ubus_data_handler_t callback, void *arg);
|
||||
|
||||
void reload_specified_services(struct ubus_context *ctx, int idx, struct blob_attr *services,
|
||||
bool is_commit, bool reload, uint32_t *wifi_config_flags);
|
||||
bool is_commit, bool reload, struct list_head *action_list,
|
||||
struct list_head *handler_list, struct list_head *changed_uci);
|
||||
|
||||
void reload_all_services(struct ubus_context *ctx, int idx, bool is_commit,
|
||||
bool reload, uint32_t *wifi_config_flags);
|
||||
bool reload, struct list_head *action_list,
|
||||
struct list_head *handler_list, struct list_head *changed_uci);
|
||||
|
||||
void wifi_reload_handler_script(uint32_t wifi_config_flags);
|
||||
void exec_apply_handler_script(const char *cmd);
|
||||
|
||||
void uci_apply_changes(const char *conf_dir, int idx, bool is_commit);
|
||||
void uci_apply_changes_dmmap(int idx, bool is_commit, struct list_head *action_list,
|
||||
struct list_head *handler_list);
|
||||
|
||||
unsigned char get_idx_by_proto(const char *proto);
|
||||
const char *get_proto_conf_savedir_by_idx(int idx);
|
||||
const char *get_proto_dmmap_savedir_by_idx(int idx);
|
||||
const char *get_proto_name_by_idx(int idx);
|
||||
bool file_exists(const char *path);
|
||||
bool regular_file(const char *path);
|
||||
|
||||
#endif //__UTILS_H__
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue