diff --git a/utilities/src/ubus/bbf_config.c b/utilities/src/ubus/bbf_config.c index c7692a16..3455ea96 100644 --- a/utilities/src/ubus/bbf_config.c +++ b/utilities/src/ubus/bbf_config.c @@ -63,6 +63,7 @@ struct bbf_config_async_req { }; static struct blob_buf g_critical_bb; +static struct list_head g_commit_handlers; static struct list_head g_apply_handlers; static struct list_head g_revert_handlers; @@ -657,10 +658,12 @@ 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; + struct list_head commit_action_list; struct list_head action_list; struct list_head *changed_uci; ULOG_INFO("Commit handler called"); + INIT_LIST_HEAD(&commit_action_list); INIT_LIST_HEAD(&action_list); if (blobmsg_parse(bbf_config_policy, __MAX, tb, blob_data(msg), blob_len(msg))) { @@ -725,15 +728,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, &action_list, - &g_apply_handlers, changed_uci); + &g_apply_handlers, changed_uci, &commit_action_list, &g_commit_handlers); } else { ULOG_INFO("Applying changes to dmmap UCI config"); - uci_apply_changes_dmmap(idx, true, &action_list, &g_apply_handlers); + uci_apply_changes_dmmap(idx, true, &action_list, &g_apply_handlers, &commit_action_list, &g_commit_handlers); ULOG_INFO("Committing changes for all services and reloading"); - reload_all_services(ctx, idx, true, reload, &action_list, &g_apply_handlers, changed_uci); + reload_all_services(ctx, idx, true, reload, &action_list, &g_apply_handlers, changed_uci, + &commit_action_list, &g_commit_handlers); } struct action_node *node = NULL, *tmp = NULL; + + list_for_each_entry_safe(node, tmp, &commit_action_list, list) { + char cmd[4096] = {0}; + unsigned pos = 0; + + ULOG_INFO("Calling external commit handlers"); + + 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); + } + + node = NULL; + tmp = NULL; list_for_each_entry_safe(node, tmp, &action_list, list) { char cmd[4096] = {0}; unsigned pos = 0; @@ -811,12 +841,13 @@ 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, &action_list, &g_revert_handlers, NULL); + reload_specified_services(ctx, idx, services, false, false, &action_list, &g_revert_handlers, NULL, + NULL, NULL); } else { ULOG_INFO("Reverting changes to dmmap UCI config"); - uci_apply_changes_dmmap(idx, false, &action_list, &g_revert_handlers); // revert dmmap changes + uci_apply_changes_dmmap(idx, false, &action_list, &g_revert_handlers, NULL, NULL); // revert dmmap changes ULOG_INFO("Reverting all services"); - reload_all_services(ctx, idx, false, false, &action_list, &g_revert_handlers, NULL); + reload_all_services(ctx, idx, false, false, &action_list, &g_revert_handlers, NULL, NULL, NULL); } struct action_node *node = NULL, *tmp = NULL; @@ -958,6 +989,15 @@ static void free_apply_revert_handlers() { struct applier_node *node = NULL, *tmp = NULL; + list_for_each_entry_safe(node, tmp, &g_commit_handlers, list) { + list_del(&node->list); + FREE(node->file_path); + FREE(node->action); + FREE(node); + } + + node = NULL; + tmp = NULL; list_for_each_entry_safe(node, tmp, &g_apply_handlers, list) { list_del(&node->list); FREE(node->file_path); @@ -995,11 +1035,11 @@ static void __load_handlers(const char *file) } char type[2][8] = { "dmmap", "uci" }; - char method[2][15] = { "apply_handler", "revert_handler" }; - struct list_head *handler_list[2] = { &g_apply_handlers, &g_revert_handlers }; + char method[3][15] = { "commit_handler", "apply_handler", "revert_handler" }; + struct list_head *handler_list[3] = { &g_commit_handlers, &g_apply_handlers, &g_revert_handlers }; - // Load apply/revert handlers - for (int x = 0; x < 2; x++) { + // Load commit/apply/revert handlers + for (int x = 0; x < 3; x++) { json_object *m_handler = NULL; json_object_object_get_ex(daemon_config, method[x], &m_handler); if (!m_handler) { @@ -1081,6 +1121,7 @@ static void load_apply_revert_handlers() { struct dirent **namelist; + INIT_LIST_HEAD(&g_commit_handlers); INIT_LIST_HEAD(&g_apply_handlers); INIT_LIST_HEAD(&g_revert_handlers); diff --git a/utilities/src/ubus/utils.c b/utilities/src/ubus/utils.c index cd1b63f9..54e651d5 100644 --- a/utilities/src/ubus/utils.c +++ b/utilities/src/ubus/utils.c @@ -251,7 +251,8 @@ int bbf_config_call(struct ubus_context *ctx, const char *object, const char *me void reload_specified_services(struct ubus_context *ctx, int idx, struct blob_attr *services, bool is_commit, bool reload, struct list_head *action_list, - struct list_head *handler_list, struct list_head *changed_uci) + struct list_head *handler_list, struct list_head *changed_uci, + struct list_head *commit_action_list, struct list_head *commit_handler_list) { struct uci_context *uci_ctx = NULL; struct blob_attr *service = NULL; @@ -324,6 +325,10 @@ void reload_specified_services(struct ubus_context *ctx, int idx, struct blob_at } } + if (is_commit && commit_action_list && commit_handler_list) { + add_external_action_list(commit_action_list, commit_handler_list, file_path, false); + } + if (is_commit == false) { // If revert operation add_external_action_list(action_list, handler_list, file_path, false); } else { // If commit operation @@ -344,7 +349,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, struct list_head *action_list, - struct list_head *handler_list, struct list_head *changed_uci) + struct list_head *handler_list, struct list_head *changed_uci, + struct list_head *commit_action_list, struct list_head *commit_handler_list) { struct uci_context *uci_ctx = NULL; char **configs = NULL, **p = NULL; @@ -402,6 +408,10 @@ void reload_all_services(struct ubus_context *ctx, int idx, bool is_commit, add_external_action_list(action_list, handler_list, file_path, false); } + if (is_commit && commit_action_list && commit_handler_list) { + add_external_action_list(commit_action_list, commit_handler_list, file_path, false); + } + if (is_commit && reload) { add_external_action_list(action_list, handler_list, file_path, true); } @@ -421,7 +431,8 @@ void exec_apply_handler_script(const char *cmd) } } -void uci_apply_changes_dmmap(int idx, bool is_commit, struct list_head *action_list, struct list_head *ext_handler) +void uci_apply_changes_dmmap(int idx, bool is_commit, struct list_head *action_list, struct list_head *ext_handler, + struct list_head *commit_action_list, struct list_head *commit_handler_list) { struct uci_context *uci_ctx = NULL; char **configs = NULL, **p = NULL; @@ -466,6 +477,10 @@ void uci_apply_changes_dmmap(int idx, bool is_commit, struct list_head *action_l continue; } + if (commit_action_list && commit_handler_list) { + add_external_action_list(commit_action_list, commit_handler_list, file_path, false); + } + add_external_action_list(action_list, ext_handler, file_path, true); } else { ULOG_DEBUG("Reverting changes for config '%s'", *p); diff --git a/utilities/src/ubus/utils.h b/utilities/src/ubus/utils.h index e7db8e8f..cbbeb079 100644 --- a/utilities/src/ubus/utils.h +++ b/utilities/src/ubus/utils.h @@ -61,16 +61,19 @@ int bbf_config_call(struct ubus_context *ctx, const char *object, const char *me void reload_specified_services(struct ubus_context *ctx, int idx, struct blob_attr *services, bool is_commit, bool reload, struct list_head *action_list, - struct list_head *handler_list, struct list_head *changed_uci); + struct list_head *handler_list, struct list_head *changed_uci, + struct list_head *commit_action_list, struct list_head *commit_handler_list); void reload_all_services(struct ubus_context *ctx, int idx, bool is_commit, bool reload, struct list_head *action_list, - struct list_head *handler_list, struct list_head *changed_uci); + struct list_head *handler_list, struct list_head *changed_uci, + struct list_head *commit_action_list, struct list_head *commit_handler_list); void exec_apply_handler_script(const char *cmd); void uci_apply_changes_dmmap(int idx, bool is_commit, struct list_head *action_list, - struct list_head *handler_list); + struct list_head *handler_list, + struct list_head *commit_action_list, struct list_head *commit_handler_list); unsigned char get_idx_by_proto(const char *proto); const char *get_proto_conf_savedir_by_idx(int idx);