diff --git a/bbfdmd/src/add_delete.c b/bbfdmd/src/add_delete.c index 2af22532..03e721e2 100644 --- a/bbfdmd/src/add_delete.c +++ b/bbfdmd/src/add_delete.c @@ -35,7 +35,7 @@ static int bbfdm_add_object(bbfdm_data_t *data) void *array = blobmsg_open_array(&data->bb, "results"); - fault = bbf_entry_method(&data->bbf_ctx, BBF_ADD_OBJECT); + fault = bbfdm_cmd_exec(&data->bbf_ctx, BBF_ADD_OBJECT); if (fault) { fill_err_code_table(data, fault); } else { @@ -64,7 +64,7 @@ static int bbfdm_del_object(bbfdm_data_t *data) INFO("Req to delete object |%s|", data->bbf_ctx.in_param); - fault = bbf_entry_method(&data->bbf_ctx, BBF_DEL_OBJECT); + fault = bbfdm_cmd_exec(&data->bbf_ctx, BBF_DEL_OBJECT); if (fault) { fill_err_code_table(data, fault); } else { diff --git a/bbfdmd/src/bbfdmd.c b/bbfdmd/src/bbfdmd.c index 786484fa..c985e20b 100644 --- a/bbfdmd/src/bbfdmd.c +++ b/bbfdmd/src/bbfdmd.c @@ -64,6 +64,21 @@ static json_object *deamon_json_obj = NULL; char UBUS_METHOD_NAME[32] = "bbfdm"; bool enable_plugins = true; +static void sig_handler(int sig) +{ + if (sig == SIGSEGV) { + handle_pending_signal(sig); + } else if (sig == SIGUSR1) { + ERR("# Exception in PID[%ld]", getpid()); + } +} + +static void signal_init(void) +{ + signal(SIGSEGV, sig_handler); + signal(SIGUSR1, sig_handler); +} + static void usage(char *prog) { fprintf(stderr, "Usage: %s [options]\n", prog); @@ -215,6 +230,8 @@ static int bbfdm_start_deferred(bbfdm_data_t *data, void (*EXEC_CB)(bbfdm_data_t exit(EXIT_FAILURE); } + // child initialise signal to prevent segfaults + signal_init(); /* free fd's and memory inherited from parent */ ubus_shutdown(data->ctx); uloop_done(); @@ -1047,7 +1064,7 @@ static void update_instances_list(struct list_head *inst) bbf_init(&bbf_ctx); - if (0 == bbf_entry_method(&bbf_ctx, BBF_INSTANCES)) { + if (0 == bbfdm_cmd_exec(&bbf_ctx, BBF_INSTANCES)) { struct dm_parameter *nptr_dp; list_for_each_entry(nptr_dp, &bbf_ctx.list_parameter, list) { @@ -1117,6 +1134,8 @@ static int fork_instance_checker(struct bbfdm_context *u) child = fork(); if (child == 0) { prctl(PR_SET_NAME, (unsigned long) "bbfdm_instance"); + // child initialise signal to prevent segfaults + signal_init(); /* free fd's and memory inherited from parent */ ubus_shutdown(&u->ubus_ctx); uloop_done(); @@ -1310,6 +1329,8 @@ int main(int argc, char **argv) return -1; } + signal_init(); + err = register_events_to_ubus(&bbfdm_ctx.ubus_ctx, &bbfdm_ctx.event_handlers); if (err != 0) goto exit; diff --git a/bbfdmd/src/events.c b/bbfdmd/src/events.c index e62dfc5e..31ab855f 100644 --- a/bbfdmd/src/events.c +++ b/bbfdmd/src/events.c @@ -282,7 +282,7 @@ bool is_registered_event(char *name) bbf_init(&bbf_ctx); - if (0 == bbf_entry_method(&bbf_ctx, BBF_SCHEMA)) { + if (0 == bbfdm_cmd_exec(&bbf_ctx, BBF_SCHEMA)) { struct dm_parameter *param; list_for_each_entry(param, &bbf_ctx.list_parameter, list) { diff --git a/bbfdmd/src/get.c b/bbfdmd/src/get.c index df36339a..a2cf22bf 100644 --- a/bbfdmd/src/get.c +++ b/bbfdmd/src/get.c @@ -45,7 +45,7 @@ void bbfdm_get_value_async(bbfdm_data_t *data, void *output) data->bbf_ctx.in_param = pn->path; - fault = bbf_entry_method(&data->bbf_ctx, BBF_GET_VALUE); + fault = bbfdm_cmd_exec(&data->bbf_ctx, BBF_GET_VALUE); if (fault) { fill_err_code_table(data, fault); } else { @@ -106,7 +106,7 @@ void bbfdm_get_value(bbfdm_data_t *data) data->bbf_ctx.in_param = pn->path; - fault = bbf_entry_method(&data->bbf_ctx, BBF_GET_VALUE); + fault = bbfdm_cmd_exec(&data->bbf_ctx, BBF_GET_VALUE); if (fault) { fill_err_code_table(data, fault); } else { @@ -163,7 +163,7 @@ void bbfdm_get_names(bbfdm_data_t *data) data->bbf_ctx.in_param = pn->path; - fault = bbf_entry_method(&data->bbf_ctx, BBF_GET_NAME); + fault = bbfdm_cmd_exec(&data->bbf_ctx, BBF_GET_NAME); if (fault) { fill_err_code_table(data, fault); } else { @@ -205,7 +205,7 @@ void bbfdm_get_instances(bbfdm_data_t *data) data->bbf_ctx.in_param = pn->path; - fault = bbf_entry_method(&data->bbf_ctx, BBF_INSTANCES); + fault = bbfdm_cmd_exec(&data->bbf_ctx, BBF_INSTANCES); if (fault) { fill_err_code_table(data, fault); } else { @@ -334,7 +334,7 @@ int bbf_dm_get_supported_dm(bbfdm_data_t *data) data->bbf_ctx.in_param = pn->path; - fault = bbf_entry_method(&data->bbf_ctx, BBF_SCHEMA); + fault = bbfdm_cmd_exec(&data->bbf_ctx, BBF_SCHEMA); if (fault) { fill_err_code_table(data, fault); } else { diff --git a/bbfdmd/src/get_helper.c b/bbfdmd/src/get_helper.c index cc7d2592..9a12ba50 100644 --- a/bbfdmd/src/get_helper.c +++ b/bbfdmd/src/get_helper.c @@ -47,6 +47,42 @@ static struct { int timeout_ms; } g_current_trans = {.trans_id=0, .timeout_ms=10000}; +static jmp_buf gs_jump_location; +static bool gs_jump_called_by_bbf = false; + +void handle_pending_signal(int sig) +{ + if (gs_jump_called_by_bbf) { + siglongjmp(gs_jump_location, 1); + } + + ERR("Exception [%d] not cause by bbf dm, exit with error", sig); + exit(1); +} + +int bbfdm_cmd_exec(struct dmctx *bbf_ctx, int cmd) +{ + int fault = 0; + + if (bbf_ctx->in_param == NULL) + return USP_FAULT_INTERNAL_ERROR; + + if (sigsetjmp(gs_jump_location, 1) == 0) { + gs_jump_called_by_bbf = true; + fault = bbf_entry_method(bbf_ctx, cmd); + } else { + ERR("PID [%ld]::Exception on [%d => %s]", getpid(), cmd, bbf_ctx->in_param); + fault = USP_FAULT_INTERNAL_ERROR; + } + + gs_jump_called_by_bbf = false; + + if (fault) + WARNING("Fault [%d => %d => %s]", fault, cmd, bbf_ctx->in_param); + + return fault; +} + void bb_add_string(struct blob_buf *bb, const char *name, const char *value) { blobmsg_add_string(bb, name, value ? value : ""); diff --git a/bbfdmd/src/get_helper.h b/bbfdmd/src/get_helper.h index e46d1021..40affe1a 100644 --- a/bbfdmd/src/get_helper.h +++ b/bbfdmd/src/get_helper.h @@ -4,7 +4,6 @@ #include "bbfdmd.h" #include "common.h" #include "libbbfdm-api/dmbbf.h" -#include "libbbfdm-api/dmentry.h" #include @@ -20,6 +19,10 @@ struct pathNode { char path[MAX_DM_PATH]; }; +void handle_pending_signal(int sig); + +int bbfdm_cmd_exec(struct dmctx *bbf_ctx, int cmd); + void bbf_init(struct dmctx *dm_ctx); void bbf_cleanup(struct dmctx *dm_ctx); void bbf_sub_init(struct dmctx *dm_ctx); diff --git a/bbfdmd/src/operate.c b/bbfdmd/src/operate.c index 5b34292e..f147b93b 100644 --- a/bbfdmd/src/operate.c +++ b/bbfdmd/src/operate.c @@ -39,7 +39,7 @@ static int bbfdm_dm_operate(bbfdm_data_t *data) blobmsg_add_string(&data->bb, "path", data->bbf_ctx.in_param); blobmsg_add_string(&data->bb, "data", data->bbf_ctx.linker); - fault = bbf_entry_method(&data->bbf_ctx, BBF_OPERATE); + fault = bbfdm_cmd_exec(&data->bbf_ctx, BBF_OPERATE); if (fault == 0) { struct dm_parameter *n; diff --git a/bbfdmd/src/set.c b/bbfdmd/src/set.c index b5b8e79d..f9d87b3d 100644 --- a/bbfdmd/src/set.c +++ b/bbfdmd/src/set.c @@ -38,7 +38,7 @@ int bbfdm_set_value(bbfdm_data_t *data) data->bbf_ctx.in_param = pv->param; data->bbf_ctx.in_value = pv->val; - fault = bbf_entry_method(&data->bbf_ctx, BBF_SET_VALUE); + fault = bbfdm_cmd_exec(&data->bbf_ctx, BBF_SET_VALUE); if (fault) { fill_err_code_table(data, fault); } else {