Added checks of changed handlers or blocked signal after plugin function calls
This commit is contained in:
parent
a242cf47bd
commit
764e9c628c
6 changed files with 263 additions and 1 deletions
|
|
@ -68,6 +68,7 @@ Developers may need to change their code
|
||||||
|
|
||||||
### Minor features
|
### Minor features
|
||||||
|
|
||||||
|
* Added checks of changed handlers or blocked signal after plugin function calls
|
||||||
* Added set/get pointer API to clixon_data:
|
* Added set/get pointer API to clixon_data:
|
||||||
* clicon_ptr_get(), clicon_ptr_set(),
|
* clicon_ptr_get(), clicon_ptr_set(),
|
||||||
* Restconf YANG PATCH according to RFC 8072
|
* Restconf YANG PATCH according to RFC 8072
|
||||||
|
|
|
||||||
|
|
@ -937,10 +937,16 @@ from_client_restart_one(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
/* Application may define extra xml in its reset function*/
|
/* Application may define extra xml in its reset function*/
|
||||||
if ((resetfn = clixon_plugin_api_get(cp)->ca_reset) != NULL){
|
if ((resetfn = clixon_plugin_api_get(cp)->ca_reset) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if ((retval = resetfn(h, db)) < 0) {
|
if ((retval = resetfn(h, db)) < 0) {
|
||||||
clicon_debug(1, "plugin_start() failed");
|
clicon_debug(1, "plugin_start() failed");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
/* 1. Start transaction */
|
/* 1. Start transaction */
|
||||||
if ((td = transaction_new()) == NULL)
|
if ((td = transaction_new()) == NULL)
|
||||||
|
|
|
||||||
|
|
@ -82,12 +82,18 @@ clixon_plugin_reset_one(clixon_plugin_t *cp,
|
||||||
plgreset_t *fn; /* callback */
|
plgreset_t *fn; /* callback */
|
||||||
|
|
||||||
if ((fn = clixon_plugin_api_get(cp)->ca_reset) != NULL){
|
if ((fn = clixon_plugin_api_get(cp)->ca_reset) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h, db) < 0) {
|
if (fn(h, db) < 0) {
|
||||||
if (clicon_errno < 0)
|
if (clicon_errno < 0)
|
||||||
clicon_log(LOG_WARNING, "%s: Internal error: Reset callback in plugin: %s returned -1 but did not make a clicon_err call",
|
clicon_log(LOG_WARNING, "%s: Internal error: Reset callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -133,6 +139,10 @@ clixon_plugin_pre_daemon_one(clixon_plugin_t *cp,
|
||||||
plgdaemon_t *fn; /* Daemonize plugin callback function */
|
plgdaemon_t *fn; /* Daemonize plugin callback function */
|
||||||
|
|
||||||
if ((fn = clixon_plugin_api_get(cp)->ca_pre_daemon) != NULL){
|
if ((fn = clixon_plugin_api_get(cp)->ca_pre_daemon) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h) < 0) {
|
if (fn(h) < 0) {
|
||||||
if (clicon_errno < 0)
|
if (clicon_errno < 0)
|
||||||
clicon_log(LOG_WARNING, "%s: Internal error: Pre-daemon callback in plugin:\
|
clicon_log(LOG_WARNING, "%s: Internal error: Pre-daemon callback in plugin:\
|
||||||
|
|
@ -140,6 +150,8 @@ clixon_plugin_pre_daemon_one(clixon_plugin_t *cp,
|
||||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -186,12 +198,18 @@ clixon_plugin_daemon_one(clixon_plugin_t *cp,
|
||||||
plgdaemon_t *fn; /* Daemonize plugin callback function */
|
plgdaemon_t *fn; /* Daemonize plugin callback function */
|
||||||
|
|
||||||
if ((fn = clixon_plugin_api_get(cp)->ca_daemon) != NULL){
|
if ((fn = clixon_plugin_api_get(cp)->ca_daemon) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h) < 0) {
|
if (fn(h) < 0) {
|
||||||
if (clicon_errno < 0)
|
if (clicon_errno < 0)
|
||||||
clicon_log(LOG_WARNING, "%s: Internal error: Daemon callback in plugin: %s returned -1 but did not make a clicon_err call",
|
clicon_log(LOG_WARNING, "%s: Internal error: Daemon callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -265,12 +283,18 @@ clixon_plugin_statedata_one(clixon_plugin_t *cp,
|
||||||
if ((fn = clixon_plugin_api_get(cp)->ca_statedata) != NULL){
|
if ((fn = clixon_plugin_api_get(cp)->ca_statedata) != NULL){
|
||||||
if ((x = xml_new(DATASTORE_TOP_SYMBOL, NULL, CX_ELMNT)) == NULL)
|
if ((x = xml_new(DATASTORE_TOP_SYMBOL, NULL, CX_ELMNT)) == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h, nsc, xpath, x) < 0){
|
if (fn(h, nsc, xpath, x) < 0){
|
||||||
if (clicon_errno < 0)
|
if (clicon_errno < 0)
|
||||||
clicon_log(LOG_WARNING, "%s: Internal error: State callback in plugin: %s returned -1 but did not make a clicon_err call",
|
clicon_log(LOG_WARNING, "%s: Internal error: State callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||||
goto fail; /* Dont quit here on user callbacks */
|
goto fail; /* Dont quit here on user callbacks */
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
if (xp && x)
|
if (xp && x)
|
||||||
*xp = x;
|
*xp = x;
|
||||||
|
|
@ -410,8 +434,14 @@ clixon_plugin_lockdb_one(clixon_plugin_t *cp,
|
||||||
plglockdb_t *fn; /* Plugin statedata fn */
|
plglockdb_t *fn; /* Plugin statedata fn */
|
||||||
|
|
||||||
if ((fn = clixon_plugin_api_get(cp)->ca_lockdb) != NULL){
|
if ((fn = clixon_plugin_api_get(cp)->ca_lockdb) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h, db, lock, id) < 0)
|
if (fn(h, db, lock, id) < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
if (plugin_context_check(&pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -579,12 +609,18 @@ plugin_transaction_begin_one(clixon_plugin_t *cp,
|
||||||
trans_cb_t *fn;
|
trans_cb_t *fn;
|
||||||
|
|
||||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_begin) != NULL){
|
if ((fn = clixon_plugin_api_get(cp)->ca_trans_begin) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h, (transaction_data)td) < 0){
|
if (fn(h, (transaction_data)td) < 0){
|
||||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -632,12 +668,18 @@ plugin_transaction_validate_one(clixon_plugin_t *cp,
|
||||||
trans_cb_t *fn;
|
trans_cb_t *fn;
|
||||||
|
|
||||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_validate) != NULL){
|
if ((fn = clixon_plugin_api_get(cp)->ca_trans_validate) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h, (transaction_data)td) < 0){
|
if (fn(h, (transaction_data)td) < 0){
|
||||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -683,12 +725,18 @@ plugin_transaction_complete_one(clixon_plugin_t *cp,
|
||||||
trans_cb_t *fn;
|
trans_cb_t *fn;
|
||||||
|
|
||||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_complete) != NULL){
|
if ((fn = clixon_plugin_api_get(cp)->ca_trans_complete) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h, (transaction_data)td) < 0){
|
if (fn(h, (transaction_data)td) < 0){
|
||||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -766,12 +814,18 @@ plugin_transaction_commit_one(clixon_plugin_t *cp,
|
||||||
trans_cb_t *fn;
|
trans_cb_t *fn;
|
||||||
|
|
||||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_commit) != NULL){
|
if ((fn = clixon_plugin_api_get(cp)->ca_trans_commit) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h, (transaction_data)td) < 0){
|
if (fn(h, (transaction_data)td) < 0){
|
||||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -825,12 +879,18 @@ plugin_transaction_commit_done_one(clixon_plugin_t *cp,
|
||||||
trans_cb_t *fn;
|
trans_cb_t *fn;
|
||||||
|
|
||||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_commit_done) != NULL){
|
if ((fn = clixon_plugin_api_get(cp)->ca_trans_commit_done) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h, (transaction_data)td) < 0){
|
if (fn(h, (transaction_data)td) < 0){
|
||||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -876,12 +936,18 @@ plugin_transaction_end_one(clixon_plugin_t *cp,
|
||||||
trans_cb_t *fn;
|
trans_cb_t *fn;
|
||||||
|
|
||||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_end) != NULL){
|
if ((fn = clixon_plugin_api_get(cp)->ca_trans_end) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h, (transaction_data)td) < 0){
|
if (fn(h, (transaction_data)td) < 0){
|
||||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -920,12 +986,18 @@ plugin_transaction_abort_one(clixon_plugin_t *cp,
|
||||||
trans_cb_t *fn;
|
trans_cb_t *fn;
|
||||||
|
|
||||||
if ((fn = clixon_plugin_api_get(cp)->ca_trans_abort) != NULL){
|
if ((fn = clixon_plugin_api_get(cp)->ca_trans_abort) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h, (transaction_data)td) < 0){
|
if (fn(h, (transaction_data)td) < 0){
|
||||||
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
if (!clicon_errno) /* sanity: log if clicon_err() is not called ! */
|
||||||
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
clicon_log(LOG_NOTICE, "%s: Plugin '%s' callback does not make clicon_err call on error",
|
||||||
__FUNCTION__, clixon_plugin_name_get(cp));
|
__FUNCTION__, clixon_plugin_name_get(cp));
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, clixon_plugin_name_get(cp), __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
|
||||||
|
|
@ -522,6 +522,47 @@ cli_handler_err(FILE *f)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Variant of eval for context checking
|
||||||
|
* @see cligen_eval
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
cligen_clixon_eval(cligen_handle h,
|
||||||
|
cg_obj *co,
|
||||||
|
cvec *cvv)
|
||||||
|
{
|
||||||
|
struct cg_callback *cc;
|
||||||
|
int retval = 0;
|
||||||
|
cvec *argv;
|
||||||
|
|
||||||
|
if (h)
|
||||||
|
cligen_co_match_set(h, co);
|
||||||
|
for (cc = co->co_callbacks; cc; cc=cc->cc_next){
|
||||||
|
/* Vector cvec argument to callback */
|
||||||
|
if (cc->cc_fn_vec){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
argv = cc->cc_cvec ? cvec_dup(cc->cc_cvec) : NULL;
|
||||||
|
cligen_fn_str_set(h, cc->cc_fn_str);
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
break;
|
||||||
|
if ((retval = (*cc->cc_fn_vec)(
|
||||||
|
cligen_userhandle(h)?cligen_userhandle(h):h,
|
||||||
|
cvv,
|
||||||
|
argv)) < 0){
|
||||||
|
if (argv != NULL)
|
||||||
|
cvec_free(argv);
|
||||||
|
cligen_fn_str_set(h, NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (plugin_context_check(&pc, "CLIgen", cc->cc_fn_str) < 0)
|
||||||
|
break;
|
||||||
|
if (argv != NULL)
|
||||||
|
cvec_free(argv);
|
||||||
|
cligen_fn_str_set(h, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Evaluate a matched command
|
/*! Evaluate a matched command
|
||||||
* @param[in] h Clicon handle
|
* @param[in] h Clicon handle
|
||||||
* @param[in] cmd The command string
|
* @param[in] cmd The command string
|
||||||
|
|
@ -541,7 +582,8 @@ clicon_eval(clicon_handle h,
|
||||||
cli_output_reset();
|
cli_output_reset();
|
||||||
if (!cligen_exiting(cli_cligen(h))) {
|
if (!cligen_exiting(cli_cligen(h))) {
|
||||||
clicon_err_reset();
|
clicon_err_reset();
|
||||||
if ((retval = cligen_eval(cli_cligen(h), match_obj, cvv)) < 0) {
|
|
||||||
|
if ((retval = cligen_clixon_eval(cli_cligen(h), match_obj, cvv)) < 0) {
|
||||||
#if 0 /* This is removed since we get two error messages on failure.
|
#if 0 /* This is removed since we get two error messages on failure.
|
||||||
But maybe only sometime?
|
But maybe only sometime?
|
||||||
Both a real log when clicon_err is called, and the here again.
|
Both a real log when clicon_err is called, and the here again.
|
||||||
|
|
|
||||||
|
|
@ -337,6 +337,17 @@ struct clixon_plugin_api{
|
||||||
#define ca_trans_abort u.cau_backend.cb_trans_abort
|
#define ca_trans_abort u.cau_backend.cb_trans_abort
|
||||||
#define ca_datastore_upgrade u.cau_backend.cb_datastore_upgrade
|
#define ca_datastore_upgrade u.cau_backend.cb_datastore_upgrade
|
||||||
|
|
||||||
|
/*! Structure for checking status before and after a plugin call
|
||||||
|
* Currently signal settings: blocked and handlers, could be extended to more
|
||||||
|
* @see plugin_context_check
|
||||||
|
*/
|
||||||
|
struct plugin_context {
|
||||||
|
sigset_t pc_sigset; /* See sigprocmask(2) */
|
||||||
|
struct sigaction pc_sigaction_vec[32]; /* See sigaction(2) */
|
||||||
|
int pc_status; /* 0: OK, -1: fail */
|
||||||
|
};
|
||||||
|
typedef struct plugin_context plugin_context_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macros
|
* Macros
|
||||||
*/
|
*/
|
||||||
|
|
@ -375,6 +386,9 @@ int clixon_plugins_load(clicon_handle h, const char *function, const char *dir,
|
||||||
|
|
||||||
int clixon_pseudo_plugin(clicon_handle h, const char *name, clixon_plugin_t **cpp);
|
int clixon_pseudo_plugin(clicon_handle h, const char *name, clixon_plugin_t **cpp);
|
||||||
|
|
||||||
|
int plugin_context_get(plugin_context_t *pc);
|
||||||
|
int plugin_context_check(plugin_context_t *pc, const char *name, const char *fn);
|
||||||
|
|
||||||
int clixon_plugin_start_one(clixon_plugin_t *cp, clicon_handle h);
|
int clixon_plugin_start_one(clixon_plugin_t *cp, clicon_handle h);
|
||||||
int clixon_plugin_start_all(clicon_handle h);
|
int clixon_plugin_start_all(clicon_handle h);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
@ -330,6 +331,7 @@ plugin_load_one(clicon_handle h,
|
||||||
clixon_plugin_t *cp = NULL;
|
clixon_plugin_t *cp = NULL;
|
||||||
char *name;
|
char *name;
|
||||||
char *p;
|
char *p;
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
clicon_debug(1, "%s file:%s function:%s", __FUNCTION__, file, function);
|
clicon_debug(1, "%s file:%s function:%s", __FUNCTION__, file, function);
|
||||||
dlerror(); /* Clear any existing error */
|
dlerror(); /* Clear any existing error */
|
||||||
|
|
@ -348,6 +350,11 @@ plugin_load_one(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
clicon_err_reset();
|
clicon_err_reset();
|
||||||
|
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
if ((api = initfn(h)) == NULL) {
|
if ((api = initfn(h)) == NULL) {
|
||||||
if (!clicon_errno){ /* if clicon_err() is not called then log and continue */
|
if (!clicon_errno){ /* if clicon_err() is not called then log and continue */
|
||||||
clicon_log(LOG_DEBUG, "Warning: failed to initiate %s", strrchr(file,'/')?strchr(file, '/'):file);
|
clicon_log(LOG_DEBUG, "Warning: failed to initiate %s", strrchr(file,'/')?strchr(file, '/'):file);
|
||||||
|
|
@ -359,6 +366,9 @@ plugin_load_one(clicon_handle h,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, file, __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
/* Note: sizeof clixon_plugin_api which is largest of clixon_plugin_api:s */
|
/* Note: sizeof clixon_plugin_api which is largest of clixon_plugin_api:s */
|
||||||
if ((cp = (clixon_plugin_t *)malloc(sizeof(struct clixon_plugin))) == NULL){
|
if ((cp = (clixon_plugin_t *)malloc(sizeof(struct clixon_plugin))) == NULL){
|
||||||
clicon_err(OE_UNIX, errno, "malloc");
|
clicon_err(OE_UNIX, errno, "malloc");
|
||||||
|
|
@ -483,6 +493,93 @@ done:
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! Get system context, eg signal procmask (for blocking) and sigactions
|
||||||
|
* Call this before a plugin
|
||||||
|
* @see plugin_context_check
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
plugin_context_get(plugin_context_t *pc)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (sigprocmask(0, NULL, &pc->pc_sigset) < 0){
|
||||||
|
clicon_err(OE_UNIX, errno, "sigprocmask");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
for (i=1; i<32; i++){
|
||||||
|
if (sigaction(i, NULL, &pc->pc_sigaction_vec[i]) < 0){
|
||||||
|
clicon_err(OE_UNIX, errno, "sigaction");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
/* Mask SA_RESTORER: Not intended for application use.
|
||||||
|
* Note that it may not be included in user space so may be hardcoded below
|
||||||
|
*/
|
||||||
|
#ifdef SA_RESTORER
|
||||||
|
pc->pc_sigaction_vec[i].sa_flags &= ~SA_RESTORER;
|
||||||
|
#else
|
||||||
|
pc->pc_sigaction_vec[i].sa_flags &= ~0x04000000;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Given an existing, old plugin context, check if anytjing has changed
|
||||||
|
* @param[in,out] oldpc Old plugin context, status will be returned inside oldpc
|
||||||
|
* @param[in] name Name of plugin for logging
|
||||||
|
* @param[in] fn Name of callback
|
||||||
|
* @retval -1 Error
|
||||||
|
* @retval 0 OK
|
||||||
|
* @see plugin_context_get
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
plugin_context_check(plugin_context_t *oldpc,
|
||||||
|
const char *name,
|
||||||
|
const char *fn)
|
||||||
|
{
|
||||||
|
int retval = -1;
|
||||||
|
int failed;
|
||||||
|
int i;
|
||||||
|
plugin_context_t newpc = {0, };
|
||||||
|
|
||||||
|
if (plugin_context_get(&newpc) < 0)
|
||||||
|
goto done;
|
||||||
|
for (i=1; i<32; i++){
|
||||||
|
failed = 0;
|
||||||
|
if (sigismember(&oldpc->pc_sigset, i) != sigismember(&newpc.pc_sigset, i)){
|
||||||
|
clicon_log(LOG_WARNING, "%s Plugin %s %s: Changed blocking of signal %s(%d) from %d to %d", __FUNCTION__,
|
||||||
|
name, fn, strsignal(i), i,
|
||||||
|
sigismember(&oldpc->pc_sigset, i),
|
||||||
|
sigismember(&newpc.pc_sigset, i)
|
||||||
|
);
|
||||||
|
failed++;
|
||||||
|
}
|
||||||
|
if (oldpc->pc_sigaction_vec[i].sa_flags != newpc.pc_sigaction_vec[i].sa_flags){
|
||||||
|
clicon_log(LOG_WARNING, "%s Plugin %s %s: Changed flags of signal %s(%d) from 0x%x to 0x%x", __FUNCTION__,
|
||||||
|
name, fn, strsignal(i), i,
|
||||||
|
oldpc->pc_sigaction_vec[i].sa_flags,
|
||||||
|
newpc.pc_sigaction_vec[i].sa_flags);;
|
||||||
|
failed++;
|
||||||
|
}
|
||||||
|
if (oldpc->pc_sigaction_vec[i].sa_sigaction != newpc.pc_sigaction_vec[i].sa_sigaction){
|
||||||
|
clicon_log(LOG_WARNING, "%s Plugin %s %s: Changed action of signal %s(%d) from %p to %p", __FUNCTION__,
|
||||||
|
name, fn, strsignal(i), i,
|
||||||
|
oldpc->pc_sigaction_vec[i].sa_sigaction,
|
||||||
|
newpc.pc_sigaction_vec[i].sa_sigaction);
|
||||||
|
failed++;
|
||||||
|
}
|
||||||
|
if (failed){
|
||||||
|
oldpc->pc_status = -1;
|
||||||
|
}
|
||||||
|
/* assert(oldpc->pc_status == 0); */
|
||||||
|
}
|
||||||
|
retval = 0;
|
||||||
|
done:
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/*! Call single plugin start callback
|
/*! Call single plugin start callback
|
||||||
* @param[in] cp Plugin handle
|
* @param[in] cp Plugin handle
|
||||||
* @param[in] h Clixon handle
|
* @param[in] h Clixon handle
|
||||||
|
|
@ -497,12 +594,18 @@ clixon_plugin_start_one(clixon_plugin_t *cp,
|
||||||
plgstart_t *fn; /* Plugin start */
|
plgstart_t *fn; /* Plugin start */
|
||||||
|
|
||||||
if ((fn = cp->cp_api.ca_start) != NULL){
|
if ((fn = cp->cp_api.ca_start) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h) < 0) {
|
if (fn(h) < 0) {
|
||||||
if (clicon_errno < 0)
|
if (clicon_errno < 0)
|
||||||
clicon_log(LOG_WARNING, "%s: Internal error: Start callback in plugin: %s returned -1 but did not make a clicon_err call",
|
clicon_log(LOG_WARNING, "%s: Internal error: Start callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||||
__FUNCTION__, cp->cp_name);
|
__FUNCTION__, cp->cp_name);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, cp->cp_name, __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -545,12 +648,18 @@ clixon_plugin_exit_one(clixon_plugin_t *cp,
|
||||||
plgexit_t *fn;
|
plgexit_t *fn;
|
||||||
|
|
||||||
if ((fn = cp->cp_api.ca_exit) != NULL){
|
if ((fn = cp->cp_api.ca_exit) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h) < 0) {
|
if (fn(h) < 0) {
|
||||||
if (clicon_errno < 0)
|
if (clicon_errno < 0)
|
||||||
clicon_log(LOG_WARNING, "%s: Internal error: Exit callback in plugin: %s returned -1 but did not make a clicon_err call",
|
clicon_log(LOG_WARNING, "%s: Internal error: Exit callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||||
__FUNCTION__, cp->cp_name);
|
__FUNCTION__, cp->cp_name);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, cp->cp_name, __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
if (dlclose(cp->cp_handle) != 0) {
|
if (dlclose(cp->cp_handle) != 0) {
|
||||||
error = (char*)dlerror();
|
error = (char*)dlerror();
|
||||||
clicon_err(OE_PLUGIN, errno, "dlclose: %s", error ? error : "Unknown error");
|
clicon_err(OE_PLUGIN, errno, "dlclose: %s", error ? error : "Unknown error");
|
||||||
|
|
@ -611,12 +720,18 @@ clixon_plugin_auth_one(clixon_plugin_t *cp,
|
||||||
|
|
||||||
clicon_debug(1, "%s", __FUNCTION__);
|
clicon_debug(1, "%s", __FUNCTION__);
|
||||||
if ((fn = cp->cp_api.ca_auth) != NULL){
|
if ((fn = cp->cp_api.ca_auth) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if ((retval = fn(h, req, auth_type, authp)) < 0) {
|
if ((retval = fn(h, req, auth_type, authp)) < 0) {
|
||||||
if (clicon_errno < 0)
|
if (clicon_errno < 0)
|
||||||
clicon_log(LOG_WARNING, "%s: Internal error: Auth callback in plugin: %s returned -1 but did not make a clicon_err call",
|
clicon_log(LOG_WARNING, "%s: Internal error: Auth callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||||
__FUNCTION__, cp->cp_name);
|
__FUNCTION__, cp->cp_name);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, cp->cp_name, __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
retval = 0; /* Ignored / no callback */
|
retval = 0; /* Ignored / no callback */
|
||||||
|
|
@ -688,12 +803,18 @@ clixon_plugin_extension_one(clixon_plugin_t *cp,
|
||||||
plgextension_t *fn; /* Plugin extension fn */
|
plgextension_t *fn; /* Plugin extension fn */
|
||||||
|
|
||||||
if ((fn = cp->cp_api.ca_extension) != NULL){
|
if ((fn = cp->cp_api.ca_extension) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h, yext, ys) < 0) {
|
if (fn(h, yext, ys) < 0) {
|
||||||
if (clicon_errno < 0)
|
if (clicon_errno < 0)
|
||||||
clicon_log(LOG_WARNING, "%s: Internal error: Extension callback in plugin: %s returned -1 but did not make a clicon_err call",
|
clicon_log(LOG_WARNING, "%s: Internal error: Extension callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||||
__FUNCTION__, cp->cp_name);
|
__FUNCTION__, cp->cp_name);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, cp->cp_name, __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
@ -752,12 +873,18 @@ clixon_plugin_datastore_upgrade_one(clixon_plugin_t *cp,
|
||||||
datastore_upgrade_t *fn;
|
datastore_upgrade_t *fn;
|
||||||
|
|
||||||
if ((fn = cp->cp_api.ca_datastore_upgrade) != NULL){
|
if ((fn = cp->cp_api.ca_datastore_upgrade) != NULL){
|
||||||
|
plugin_context_t pc = {0,};
|
||||||
|
|
||||||
|
if (plugin_context_get(&pc) < 0)
|
||||||
|
goto done;
|
||||||
if (fn(h, db, xt, msd) < 0) {
|
if (fn(h, db, xt, msd) < 0) {
|
||||||
if (clicon_errno < 0)
|
if (clicon_errno < 0)
|
||||||
clicon_log(LOG_WARNING, "%s: Internal error: Datastore upgrade callback in plugin: %s returned -1 but did not make a clicon_err call",
|
clicon_log(LOG_WARNING, "%s: Internal error: Datastore upgrade callback in plugin: %s returned -1 but did not make a clicon_err call",
|
||||||
__FUNCTION__, cp->cp_name);
|
__FUNCTION__, cp->cp_name);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
if (plugin_context_check(&pc, cp->cp_name, __FUNCTION__) < 0)
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
retval = 0;
|
retval = 0;
|
||||||
done:
|
done:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue