From 5c5e45d10acce28e6828271f080ea232e7cd82a5 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Sat, 31 Oct 2020 17:08:59 +0100 Subject: [PATCH] Added new backend plugin: ca_pre-demon called if backend is daemonized just prior to forking. --- CHANGELOG.md | 1 + apps/backend/backend_main.c | 10 ++++-- apps/backend/backend_plugin.c | 60 ++++++++++++++++++++++++++++++++++- apps/backend/backend_plugin.h | 2 +- lib/clixon/clixon_plugin.h | 9 ++++-- 5 files changed, 74 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d69ffcd8..47611218 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ ### Minor changes +* Added new backend plugin: ca_pre-demon called if backend is daemonized just prior to forking. * Added XPATH functions `position` ### Corrected Bugs diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index 0bc7524f..eefb1887 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -912,15 +912,19 @@ main(int argc, demonized errors OK. Before this stage, errors are logged on stderr also */ if (foreground==0){ - clicon_log_init(__PROGRAM__, dbg?LOG_DEBUG:LOG_INFO, + /* Call plugin callbacks just before fork/daemonization */ + if (clixon_plugin_pre_daemon_all(h) < 0) + goto done; + clicon_log_init(__PROGRAM__, dbg?LOG_DEBUG:LOG_INFO, logdst==CLICON_LOG_FILE?CLICON_LOG_FILE:CLICON_LOG_SYSLOG); if (daemon(0, 0) < 0){ fprintf(stderr, "config: daemon"); exit(-1); } - } - /* Call plugin callbacks when in background and before dropped privileges */ + /* Call plugin callbacks when in background and before dropped privileges + * Possibly this should be within the foreground==0 clause after daemon? + */ if (clixon_plugin_daemon_all(h) < 0) goto done; diff --git a/apps/backend/backend_plugin.c b/apps/backend/backend_plugin.c index 68433597..d085a6e2 100644 --- a/apps/backend/backend_plugin.c +++ b/apps/backend/backend_plugin.c @@ -118,13 +118,65 @@ clixon_plugin_reset_all(clicon_handle h, return retval; } +/*! Call single plugin "pre-" daemonize callback + * @param[in] cp Plugin handle + * @param[in] h Clixon handle + * @retval 0 OK + * @retval -1 Error + */ +static int +clixon_plugin_pre_daemon_one(clixon_plugin *cp, + clicon_handle h) +{ + int retval = -1; + plgdaemon_t *fn; /* Daemonize plugin callback function */ + + if ((fn = cp->cp_api.ca_pre_daemon) != NULL){ + if (fn(h) < 0) { + if (clicon_errno < 0) + clicon_log(LOG_WARNING, "%s: Internal error: Pre-daemon callback in plugin:\ + %s returned -1 but did not make a clicon_err call", + __FUNCTION__, cp->cp_name); + goto done; + } + } + retval = 0; + done: + return retval; +} + +/*! Call all plugins "pre-" daemonize callbacks + * + * This point in time is after "start" and before + * before daemonization/fork, + * It is not called if backend is started in daemon mode. + * @param[in] h Clicon handle + * @retval 0 OK + * @retval -1 Error + */ +int +clixon_plugin_pre_daemon_all(clicon_handle h) +{ + int retval = -1; + clixon_plugin *cp = NULL; + + /* Loop through all plugins, call callbacks in each */ + while ((cp = clixon_plugin_each(h, cp)) != NULL) { + if (clixon_plugin_pre_daemon_one(cp, h) < 0) + goto done; + } + retval = 0; + done: + return retval; +} + /*! Call single plugin "post-" daemonize callback * @param[in] cp Plugin handle * @param[in] h Clixon handle * @retval 0 OK * @retval -1 Error */ -int +static int clixon_plugin_daemon_one(clixon_plugin *cp, clicon_handle h) { @@ -145,9 +197,15 @@ clixon_plugin_daemon_one(clixon_plugin *cp, } /*! Call all plugins "post-" daemonize callbacks + * + * This point in time is after "start" and after "pre-daemon" and + * after daemonization/fork, ie when + * daemon is in the background but before dropped privileges. + * In case of foreground mode (-F) it is still called but no fork has occured. * @param[in] h Clicon handle * @retval 0 OK * @retval -1 Error + * @note Also called for non-background mode */ int clixon_plugin_daemon_all(clicon_handle h) diff --git a/apps/backend/backend_plugin.h b/apps/backend/backend_plugin.h index 5fedf223..60916637 100644 --- a/apps/backend/backend_plugin.h +++ b/apps/backend/backend_plugin.h @@ -72,7 +72,7 @@ typedef struct { int clixon_plugin_reset_one(clixon_plugin *cp, clicon_handle h, char *db); int clixon_plugin_reset_all(clicon_handle h, char *db); -int clixon_plugin_daemon_one(clixon_plugin *cp, clicon_handle h); +int clixon_plugin_pre_daemon_all(clicon_handle h); int clixon_plugin_daemon_all(clicon_handle h); int clixon_plugin_statedata_all(clicon_handle h, yang_stmt *yspec, cvec *nsc, char *xpath, cxobj **xtop); diff --git a/lib/clixon/clixon_plugin.h b/lib/clixon/clixon_plugin.h index e6bf37a6..dd03babc 100644 --- a/lib/clixon/clixon_plugin.h +++ b/lib/clixon/clixon_plugin.h @@ -107,11 +107,12 @@ typedef int (*clicon_upgrade_cb)( */ typedef int (plgstart_t)(clicon_handle); /* Plugin start */ -/* Called just after a server has "daemonized", ie put in background. +/* Called just before or after a server has "daemonized", ie put in background. * Backend: If daemon privileges are dropped this callback is called *before* privileges are dropped. - * If daemon is started in foreground (-F) it is still called. + * If daemon is started in foreground (-F): pre-daemon is not called, but post-daemon called */ -typedef int (plgdaemon_t)(clicon_handle); /* Plugin daemonized */ +typedef int (plgdaemon_t)(clicon_handle); /* Plugin pre/post daemonized */ + /* Called just before plugin unloaded. */ @@ -219,6 +220,7 @@ struct clixon_plugin_api{ struct { /* netconf-specific */ } cau_netconf; struct { /* backend-specific */ + plgdaemon_t *cb_pre_daemon; /* Plugin just before daemonization */ plgdaemon_t *cb_daemon; /* Plugin daemonized */ plgreset_t *cb_reset; /* Reset system status */ plgstatedata_t *cb_statedata; /* Get state data from plugin (backend only) */ @@ -239,6 +241,7 @@ struct clixon_plugin_api{ #define ca_suspend u.cau_cli.ci_suspend #define ca_interrupt u.cau_cli.ci_interrupt #define ca_auth u.cau_restconf.cr_auth +#define ca_pre_daemon u.cau_backend.cb_daemon #define ca_daemon u.cau_backend.cb_daemon #define ca_reset u.cau_backend.cb_reset #define ca_statedata u.cau_backend.cb_statedata