From 82fa17ae5621849790eb39ed046d58333ede347c Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Thu, 21 Apr 2011 11:37:26 +0200 Subject: step: begun to create a "load" interface in rsconf --- runtime/rsconf.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- runtime/rsconf.h | 10 ++++- tools/syslogd.c | 42 ++++++++++-------- 3 files changed, 160 insertions(+), 21 deletions(-) diff --git a/runtime/rsconf.c b/runtime/rsconf.c index d68420bf..1f7a46c3 100644 --- a/runtime/rsconf.c +++ b/runtime/rsconf.c @@ -28,20 +28,29 @@ #include #include #include +#include #include "rsyslog.h" #include "obj.h" #include "srUtils.h" #include "ruleset.h" #include "modules.h" +#include "conf.h" #include "rsconf.h" #include "cfsysline.h" +#include "errmsg.h" +#include "unicode-helper.h" /* static data */ DEFobjStaticHelpers DEFobjCurrIf(ruleset) DEFobjCurrIf(module) +DEFobjCurrIf(conf) +DEFobjCurrIf(errmsg) +/* exported static data */ +rsconf_t *runConf = NULL;/* the currently running config */ +rsconf_t *loadConf = NULL;/* the config currently being loaded (no concurrent config load supported!) */ /* Standard-Constructor */ @@ -61,7 +70,6 @@ ENDobjConstruct(rsconf) /* ConstructionFinalizer - * rgerhards, 2008-01-09 */ rsRetVal rsconfConstructFinalize(rsconf_t __attribute__((unused)) *pThis) { @@ -104,6 +112,119 @@ CODESTARTobjDebugPrint(rsconf) ENDobjDebugPrint(rsconf) +/* Activate an already-loaded configuration. The configuration will become + * the new running conf (if successful). Note that in theory this method may + * be called when there already is a running conf. In practice, the current + * version of rsyslog does not support this. Future versions probably will. + * Begun 2011-04-20, rgerhards + */ +rsRetVal +activate(rsconf_t *cnf) +{ + DEFiRet; + runConf = cnf; + dbgprintf("configuration %p activated\n", cnf); + RETiRet; +} + + +/* intialize the legacy config system */ +static inline rsRetVal +initLegacyConf(void) +{ + DEFiRet; + ruleset_t *pRuleset; + + /* construct the default ruleset */ + ruleset.Construct(&pRuleset); + ruleset.SetName(loadConf, pRuleset, UCHAR_CONSTANT("RSYSLOG_DefaultRuleset")); + ruleset.ConstructFinalize(loadConf, pRuleset); + + RETiRet; +} + + +/* Load a configuration. This will do all necessary steps to create + * the in-memory representation of the configuration, including support + * for multiple configuration languages. + * Note that to support the legacy language we must provide some global + * object that holds the currently-being-loaded config ptr. + * Begun 2011-04-20, rgerhards + */ +rsRetVal +load(rsconf_t **cnf, uchar *confFile) +{ + rsRetVal localRet; + int iNbrActions; + int bHadConfigErr = 0; + char cbuf[BUFSIZ]; + DEFiRet; + + CHKiRet(rsconfConstruct(&loadConf)); +ourConf = loadConf; // TODO: remove, once ourConf is gone! + + CHKiRet(initLegacyConf()); + +#if 0 +dbgprintf("XXXX: 2, conf=%p\n", conf.processConfFile); + /* open the configuration file */ + localRet = conf.processConfFile(loadConf, confFile); + CHKiRet(conf.GetNbrActActions(loadConf, &iNbrActions)); + +dbgprintf("XXXX: 4\n"); + if(localRet != RS_RET_OK) { + errmsg.LogError(0, localRet, "CONFIG ERROR: could not interpret master config file '%s'.", confFile); + bHadConfigErr = 1; + } else if(iNbrActions == 0) { + errmsg.LogError(0, RS_RET_NO_ACTIONS, "CONFIG ERROR: there are no active actions configured. Inputs will " + "run, but no output whatsoever is created."); + bHadConfigErr = 1; + } + +dbgprintf("XXXX: 10\n"); + if((localRet != RS_RET_OK && localRet != RS_RET_NONFATAL_CONFIG_ERR) || iNbrActions == 0) { + +dbgprintf("XXXX: 20\n"); + /* rgerhards: this code is executed to set defaults when the + * config file could not be opened. We might think about + * abandoning the run in this case - but this, too, is not + * very clever... So we stick with what we have. + * We ignore any errors while doing this - we would be lost anyhow... + */ + errmsg.LogError(0, NO_ERRCODE, "EMERGENCY CONFIGURATION ACTIVATED - fix rsyslog config file!"); + + /* note: we previously used _POSIY_TTY_NAME_MAX+1, but this turned out to be + * too low on linux... :-S -- rgerhards, 2008-07-28 + */ + char szTTYNameBuf[128]; + rule_t *pRule = NULL; /* initialization to NULL is *vitally* important! */ + conf.cfline(loadConf, UCHAR_CONSTANT("*.ERR\t" _PATH_CONSOLE), &pRule); + conf.cfline(loadConf, UCHAR_CONSTANT("syslog.*\t" _PATH_CONSOLE), &pRule); + conf.cfline(loadConf, UCHAR_CONSTANT("*.PANIC\t*"), &pRule); + conf.cfline(loadConf, UCHAR_CONSTANT("syslog.*\troot"), &pRule); + if(ttyname_r(0, szTTYNameBuf, sizeof(szTTYNameBuf)) == 0) { + snprintf(cbuf,sizeof(cbuf), "*.*\t%s", szTTYNameBuf); + conf.cfline(loadConf, (uchar*)cbuf, &pRule); + } else { + DBGPRINTF("error %d obtaining controlling terminal, not using that emergency rule\n", errno); + } + ruleset.AddRule(loadConf, ruleset.GetCurrent(loadConf), &pRule); + } + +#endif + + + /* all OK, pass loaded conf to caller */ + *cnf = loadConf; + loadConf = NULL; + + dbgprintf("rsyslog finished loading initial config %p\n", loadConf); +// rsconfDebugPrint(loadConf); + +finalize_it: + RETiRet; +} + /* queryInterface function */ @@ -122,6 +243,8 @@ CODESTARTobjQueryInterface(rsconf) pIf->ConstructFinalize = rsconfConstructFinalize; pIf->Destruct = rsconfDestruct; pIf->DebugPrint = rsconfDebugPrint; + pIf->Load = load; + pIf->Activate = activate; finalize_it: ENDobjQueryInterface(rsconf) @@ -133,6 +256,8 @@ BEGINObjClassInit(rsconf, 1, OBJ_IS_CORE_MODULE) /* class, version */ /* request objects we use */ CHKiRet(objUse(ruleset, CORE_COMPONENT)); CHKiRet(objUse(module, CORE_COMPONENT)); + CHKiRet(objUse(conf, CORE_COMPONENT)); + CHKiRet(objUse(errmsg, CORE_COMPONENT)); /* now set our own handlers */ OBJSetMethodHandler(objMethod_DEBUGPRINT, rsconfDebugPrint); @@ -145,6 +270,8 @@ ENDObjClassInit(rsconf) BEGINObjClassExit(rsconf, OBJ_IS_CORE_MODULE) /* class, version */ objRelease(ruleset, CORE_COMPONENT); objRelease(module, CORE_COMPONENT); + objRelease(conf, CORE_COMPONENT); + objRelease(errmsg, CORE_COMPONENT); ENDObjClassExit(rsconf) /* vi:set ai: diff --git a/runtime/rsconf.h b/runtime/rsconf.h index 68325852..3302e990 100644 --- a/runtime/rsconf.h +++ b/runtime/rsconf.h @@ -99,13 +99,21 @@ BEGINinterface(rsconf) /* name must also be changed in ENDinterface macro! */ rsRetVal (*Construct)(rsconf_t **ppThis); rsRetVal (*ConstructFinalize)(rsconf_t __attribute__((unused)) *pThis); rsRetVal (*Destruct)(rsconf_t **ppThis); + rsRetVal (*Load)(rsconf_t **ppThis, uchar *confFile); + rsRetVal (*Activate)(rsconf_t *ppThis); ENDinterface(rsconf) -#define rsconfCURR_IF_VERSION 1 /* increment whenever you change the interface above! */ +// TODO: switch version to 1 for first "complete" version!!!! 2011-04-20 +#define rsconfCURR_IF_VERSION 0 /* increment whenever you change the interface above! */ /* prototypes */ PROTOTYPEObj(rsconf); +/* globally-visible external data */ +extern rsconf_t *runConf;/* the currently running config */ +extern rsconf_t *loadConf;/* the config currently being loaded (no concurrent config load supported!) */ + + /* some defaults (to be removed?) */ #define DFLT_bLogStatusMsgs 1 diff --git a/tools/syslogd.c b/tools/syslogd.c index e0e5868b..1cf0b894 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -563,7 +563,7 @@ logmsgInternal(int iErr, int pri, uchar *msg, int flags) * permits us to process unmodified config files which otherwise contain a * supressor statement. */ - if(((Debug == DEBUG_FULL || NoFork) && ourConf->globals.bErrMsgToStderr) || iConfigVerify) { + if(((Debug == DEBUG_FULL || NoFork) && runConf->globals.bErrMsgToStderr) || iConfigVerify) { if(LOG_PRI(pri) == LOG_ERR) fprintf(stderr, "rsyslogd: %s\n", msg); } @@ -809,7 +809,7 @@ DEFFUNC_llExecFunc(flushRptdMsgsActions) static void doFlushRptdMsgs(void) { - ruleset.IterateAllActions(ourConf, flushRptdMsgsActions, NULL); + ruleset.IterateAllActions(runConf, flushRptdMsgsActions, NULL); } @@ -1020,7 +1020,7 @@ freeAllDynMemForTermination(void) static inline void destructAllActions(void) { - ruleset.DestructAllActions(ourConf); + ruleset.DestructAllActions(runConf); bHaveMainQueue = 0; // flag that internal messages need to be temporarily stored } @@ -1058,7 +1058,8 @@ die(int sig) thrdTerminateAll(); /* and THEN send the termination log message (see long comment above) */ - if(sig && ourConf->globals.bLogStatusMsgs) { +dbgprintf("XXXX: runConf %p\n", runConf); + if(sig && runConf->globals.bLogStatusMsgs) { (void) snprintf(buf, sizeof(buf) / sizeof(char), " [origin software=\"rsyslogd\" " "swVersion=\"" VERSION \ "\" x-pid=\"%d\" x-info=\"http://www.rsyslog.com\"]" " exiting on signal %d.", @@ -1085,7 +1086,7 @@ die(int sig) * ourselfs, this makes finding memory leaks a lot * easier. */ - tplDeleteAll(ourConf); + tplDeleteAll(runConf); /* de-init some modules */ modExitIminternal(); @@ -1598,11 +1599,7 @@ init(void) DEFiRet; DBGPRINTF("rsyslog %s - called init()\n", VERSION); - - /* construct the default ruleset */ - ruleset.Construct(&pRuleset); - ruleset.SetName(ourConf, pRuleset, UCHAR_CONSTANT("RSYSLOG_DefaultRuleset")); - ruleset.ConstructFinalize(ourConf, pRuleset); +#if 1 /* open the configuration file */ localRet = conf.processConfFile(ourConf, ConfFile); @@ -1646,6 +1643,7 @@ init(void) } ruleset.AddRule(ourConf, ruleset.GetCurrent(ourConf), &pRule); } +#endif legacyOptsHook(); @@ -1721,6 +1719,7 @@ init(void) sigAct.sa_handler = sighup_handler; sigaction(SIGHUP, &sigAct, NULL); + CHKiRet(rsconf.Activate(ourConf)); DBGPRINTF(" started.\n"); /* we now generate the startup message. It now includes everything to @@ -2187,7 +2186,7 @@ static rsRetVal mainThread() CHKiRet(init()); if(Debug && debugging_on) { - DBGPRINTF("Debugging enabled, SIGUSR1 to turn off debugging.\n"); + dbgprintf("Debugging enabled, SIGUSR1 to turn off debugging.\n"); } /* Send a signal to the parent so it can terminate. @@ -2711,9 +2710,6 @@ int realMain(int argc, char **argv) for(p = LocalDomain ; *p ; p++) *p = (char)tolower((int)*p); - /* we need to init the config object first! */ - CHKiRet(rsconf.Construct(&ourConf)); - /* we now have our hostname and can set it inside the global vars. * TODO: think if all of this would better be a runtime function * rgerhards, 2008-04-17 @@ -2729,11 +2725,6 @@ int realMain(int argc, char **argv) exit(1); /* "good" exit, leaving at init for fatal error */ } - if((iRet = loadBuildInModules(ourConf)) != RS_RET_OK) { - fprintf(stderr, "fatal error: could not activate built-in modules. Error code %d.\n", - iRet); - exit(1); /* "good" exit, leaving at init for fatal error */ - } /* END core initializations - we now come back to carrying out command line options*/ @@ -2878,11 +2869,24 @@ int realMain(int argc, char **argv) if(iRet != RS_RET_END_OF_LINKEDLIST) FINALIZE; + CHKiRet(rsconf.Load(&ourConf, ConfFile)); + + + + /* begin config load */ + if((iRet = loadBuildInModules(ourConf)) != RS_RET_OK) { + fprintf(stderr, "fatal error: could not activate built-in modules. Error code %d.\n", + iRet); + exit(1); /* "good" exit, leaving at init for fatal error */ + } if(iConfigVerify) { fprintf(stderr, "rsyslogd: version %s, config validation run (level %d), master config %s\n", VERSION, iConfigVerify, ConfFile); } + + + if(bChDirRoot) { if(chdir("/") != 0) fprintf(stderr, "Can not do 'cd /' - still trying to run\n"); -- cgit