Hide plugin check handler struct with a handler

This commit is contained in:
Olof hagsand 2021-10-19 17:28:13 +02:00
parent 764e9c628c
commit c93348d8d5
5 changed files with 163 additions and 125 deletions

View file

@ -70,6 +70,15 @@
/*
* Private types
*/
/*! 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 */
};
/* Internal plugin structure with dlopen() handle and plugin_api
* This is an internal type, not exposed in the API
@ -328,10 +337,10 @@ plugin_load_one(clicon_handle h,
void *handle = NULL;
plginit2_t *initfn;
clixon_plugin_api *api = NULL;
clixon_plugin_t *cp = NULL;
clixon_plugin_t *cp = NULL;
char *name;
char *p;
plugin_context_t pc = {0,};
plugin_context_t *pc = NULL;
clicon_debug(1, "%s file:%s function:%s", __FUNCTION__, file, function);
dlerror(); /* Clear any existing error */
@ -350,9 +359,7 @@ plugin_load_one(clicon_handle h,
goto done;
}
clicon_err_reset();
if (plugin_context_get(&pc) < 0)
if ((pc = plugin_context_get()) < 0)
goto done;
if ((api = initfn(h)) == NULL) {
@ -366,7 +373,7 @@ plugin_load_one(clicon_handle h,
goto done;
}
}
if (plugin_context_check(&pc, file, __FUNCTION__) < 0)
if (plugin_context_check(pc, file, __FUNCTION__) < 0)
goto done;
/* Note: sizeof clixon_plugin_api which is largest of clixon_plugin_api:s */
@ -392,6 +399,8 @@ plugin_load_one(clicon_handle h,
retval = 1;
done:
clicon_debug(1, "%s retval:%d", __FUNCTION__, retval);
if (pc)
free(pc);
if (retval != 1 && handle)
dlclose(handle);
if (cp)
@ -495,14 +504,20 @@ done:
/*! Get system context, eg signal procmask (for blocking) and sigactions
* Call this before a plugin
* @retval pc Plugin context structure, use free() to deallocate
* @retval NULL Error
* @see plugin_context_check
*/
int
plugin_context_get(plugin_context_t *pc)
* */
plugin_context_t *
plugin_context_get(void)
{
int retval = -1;
int i;
int i;
struct plugin_context *pc = NULL;
if ((pc = malloc(sizeof *pc)) == NULL){
clicon_err(OE_UNIX, errno, "malloc");
goto done;
}
if (sigprocmask(0, NULL, &pc->pc_sigset) < 0){
clicon_err(OE_UNIX, errno, "sigprocmask");
goto done;
@ -521,9 +536,11 @@ plugin_context_get(plugin_context_t *pc)
pc->pc_sigaction_vec[i].sa_flags &= ~0x04000000;
#endif
}
retval = 0;
return pc;
done:
return retval;
if (pc)
free(pc);
return NULL;
}
/*! Given an existing, old plugin context, check if anytjing has changed
@ -535,39 +552,40 @@ plugin_context_get(plugin_context_t *pc)
* @see plugin_context_get
*/
int
plugin_context_check(plugin_context_t *oldpc,
plugin_context_check(plugin_context_t *oldpc0,
const char *name,
const char *fn)
{
int retval = -1;
int failed;
int i;
plugin_context_t newpc = {0, };
int retval = -1;
int failed;
int i;
struct plugin_context *oldpc = oldpc0;
struct plugin_context *newpc = NULL;
if (plugin_context_get(&newpc) < 0)
if ((newpc = plugin_context_get()) == NULL)
goto done;
for (i=1; i<32; i++){
failed = 0;
if (sigismember(&oldpc->pc_sigset, i) != sigismember(&newpc.pc_sigset, i)){
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)
sigismember(&newpc->pc_sigset, i)
);
failed++;
}
if (oldpc->pc_sigaction_vec[i].sa_flags != newpc.pc_sigaction_vec[i].sa_flags){
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);;
newpc->pc_sigaction_vec[i].sa_flags);;
failed++;
}
if (oldpc->pc_sigaction_vec[i].sa_sigaction != newpc.pc_sigaction_vec[i].sa_sigaction){
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);
newpc->pc_sigaction_vec[i].sa_sigaction);
failed++;
}
if (failed){
@ -577,6 +595,8 @@ plugin_context_check(plugin_context_t *oldpc,
}
retval = 0;
done:
if (newpc)
free(newpc);
return retval;
}
@ -590,13 +610,12 @@ int
clixon_plugin_start_one(clixon_plugin_t *cp,
clicon_handle h)
{
int retval = -1;
plgstart_t *fn; /* Plugin start */
int retval = -1;
plgstart_t *fn; /* Plugin start */
plugin_context_t *pc = NULL;
if ((fn = cp->cp_api.ca_start) != NULL){
plugin_context_t pc = {0,};
if (plugin_context_get(&pc) < 0)
if ((pc = plugin_context_get()) == NULL)
goto done;
if (fn(h) < 0) {
if (clicon_errno < 0)
@ -604,11 +623,13 @@ clixon_plugin_start_one(clixon_plugin_t *cp,
__FUNCTION__, cp->cp_name);
goto done;
}
if (plugin_context_check(&pc, cp->cp_name, __FUNCTION__) < 0)
if (plugin_context_check(pc, cp->cp_name, __FUNCTION__) < 0)
goto done;
}
retval = 0;
done:
if (pc)
free(pc);
return retval;
}
@ -643,14 +664,13 @@ static int
clixon_plugin_exit_one(clixon_plugin_t *cp,
clicon_handle h)
{
int retval = -1;
char *error;
plgexit_t *fn;
int retval = -1;
char *error;
plgexit_t *fn;
plugin_context_t *pc = NULL;
if ((fn = cp->cp_api.ca_exit) != NULL){
plugin_context_t pc = {0,};
if (plugin_context_get(&pc) < 0)
if ((pc = plugin_context_get()) == NULL)
goto done;
if (fn(h) < 0) {
if (clicon_errno < 0)
@ -658,7 +678,7 @@ clixon_plugin_exit_one(clixon_plugin_t *cp,
__FUNCTION__, cp->cp_name);
goto done;
}
if (plugin_context_check(&pc, cp->cp_name, __FUNCTION__) < 0)
if (plugin_context_check(pc, cp->cp_name, __FUNCTION__) < 0)
goto done;
if (dlclose(cp->cp_handle) != 0) {
error = (char*)dlerror();
@ -667,6 +687,8 @@ clixon_plugin_exit_one(clixon_plugin_t *cp,
}
retval = 0;
done:
if (pc)
free(pc);
return retval;
}
@ -715,14 +737,13 @@ clixon_plugin_auth_one(clixon_plugin_t *cp,
clixon_auth_type_t auth_type,
char **authp)
{
int retval = -1;
plgauth_t *fn; /* Plugin auth */
int retval = -1;
plgauth_t *fn; /* Plugin auth */
plugin_context_t *pc = NULL;
clicon_debug(1, "%s", __FUNCTION__);
if ((fn = cp->cp_api.ca_auth) != NULL){
plugin_context_t pc = {0,};
if (plugin_context_get(&pc) < 0)
if ((pc = plugin_context_get()) == NULL)
goto done;
if ((retval = fn(h, req, auth_type, authp)) < 0) {
if (clicon_errno < 0)
@ -730,12 +751,14 @@ clixon_plugin_auth_one(clixon_plugin_t *cp,
__FUNCTION__, cp->cp_name);
goto done;
}
if (plugin_context_check(&pc, cp->cp_name, __FUNCTION__) < 0)
if (plugin_context_check(pc, cp->cp_name, __FUNCTION__) < 0)
goto done;
}
else
retval = 0; /* Ignored / no callback */
done:
if (pc)
free(pc);
clicon_debug(1, "%s retval:%d auth:%s", __FUNCTION__, retval, *authp);
return retval;
}
@ -799,13 +822,12 @@ clixon_plugin_extension_one(clixon_plugin_t *cp,
yang_stmt *yext,
yang_stmt *ys)
{
int retval = 1;
plgextension_t *fn; /* Plugin extension fn */
int retval = 1;
plgextension_t *fn; /* Plugin extension fn */
plugin_context_t *pc = NULL;
if ((fn = cp->cp_api.ca_extension) != NULL){
plugin_context_t pc = {0,};
if (plugin_context_get(&pc) < 0)
if ((pc = plugin_context_get()) == NULL)
goto done;
if (fn(h, yext, ys) < 0) {
if (clicon_errno < 0)
@ -813,11 +835,13 @@ clixon_plugin_extension_one(clixon_plugin_t *cp,
__FUNCTION__, cp->cp_name);
goto done;
}
if (plugin_context_check(&pc, cp->cp_name, __FUNCTION__) < 0)
if (plugin_context_check(pc, cp->cp_name, __FUNCTION__) < 0)
goto done;
}
retval = 0;
done:
if (pc)
free(pc);
return retval;
}
@ -871,11 +895,10 @@ clixon_plugin_datastore_upgrade_one(clixon_plugin_t *cp,
{
int retval = -1;
datastore_upgrade_t *fn;
plugin_context_t *pc = NULL;
if ((fn = cp->cp_api.ca_datastore_upgrade) != NULL){
plugin_context_t pc = {0,};
if (plugin_context_get(&pc) < 0)
if ((pc = plugin_context_get()) == NULL)
goto done;
if (fn(h, db, xt, msd) < 0) {
if (clicon_errno < 0)
@ -883,11 +906,13 @@ clixon_plugin_datastore_upgrade_one(clixon_plugin_t *cp,
__FUNCTION__, cp->cp_name);
goto done;
}
if (plugin_context_check(&pc, cp->cp_name, __FUNCTION__) < 0)
if (plugin_context_check(pc, cp->cp_name, __FUNCTION__) < 0)
goto done;
}
retval = 0;
done:
if (pc)
free(pc);
return retval;
}