From 0434294dd0df17f45bfcbb5925ff6d6d623c684a Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Wed, 2 Apr 2008 12:26:03 +0000 Subject: added more meaningful error messages to rsyslogd (when some errors happens during startup) --- ChangeLog | 2 ++ conf.c | 2 +- modules.c | 10 +++++----- rsyslog.h | 5 +++++ syslogd.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 53 insertions(+), 8 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4f259084..3c20f16b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,8 @@ Version 3.15.1 (rgerhards), 2008-04-?? possible way - added librelp check via PKG_CHECK thanks to Michael Biebl's patch - file relputil.c deleted, is not actually needed +- added more meaningful error messages to rsyslogd (when some errors + happens during startup) --------------------------------------------------------------------------- Version 3.15.0 (rgerhards), 2008-04-01 - major new feature: imrelp/omrelp support reliable delivery of syslog diff --git a/conf.c b/conf.c index f3f10ba3..14e73f0e 100644 --- a/conf.c +++ b/conf.c @@ -1199,7 +1199,7 @@ BEGINAbstractObjClassInit(conf, 1, OBJ_IS_CORE_MODULE) /* class, version - CHANG CHKiRet(objUse(ctok, CORE_COMPONENT)); CHKiRet(objUse(module, CORE_COMPONENT)); CHKiRet(objUse(errmsg, CORE_COMPONENT)); - CHKiRet(objUse(net, LM_NET_FILENAME)); + CHKiRet(objUse(net, LM_NET_FILENAME)); /* TODO: make this dependcy go away! */ ENDObjClassInit(conf) /* vi:set ai: diff --git a/modules.c b/modules.c index b6164f91..86ee64a5 100644 --- a/modules.c +++ b/modules.c @@ -594,7 +594,7 @@ Load(uchar *pModName) } else { errmsg.LogError(NO_ERRCODE, "could not load module '%s', path too long\n", pModName); free(pModNameDup); - ABORT_FINALIZE(RS_RET_ERR); + ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_PATHLEN); } } } @@ -619,24 +619,24 @@ Load(uchar *pModName) if(iPathLen + strlen((char*) pModName) >= sizeof(szPath)) { errmsg.LogError(NO_ERRCODE, "could not load module '%s', path too long\n", pModName); - ABORT_FINALIZE(RS_RET_ERR); + ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_PATHLEN); } /* complete load path constructed, so ... GO! */ dbgprintf("loading module '%s'\n", szPath); if(!(pModHdlr = dlopen((char *) szPath, RTLD_NOW))) { errmsg.LogError(NO_ERRCODE, "could not load module '%s', dlopen: %s\n", szPath, dlerror()); - ABORT_FINALIZE(RS_RET_ERR); + ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_DLOPEN); } if(!(pModInit = dlsym(pModHdlr, "modInit"))) { errmsg.LogError(NO_ERRCODE, "could not load module '%s', dlsym: %s\n", szPath, dlerror()); dlclose(pModHdlr); - ABORT_FINALIZE(RS_RET_ERR); + ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_NO_INIT); } if((iRet = doModInit(pModInit, (uchar*) pModName, pModHdlr)) != RS_RET_OK) { errmsg.LogError(NO_ERRCODE, "could not load module '%s', rsyslog error %d\n", szPath, iRet); dlclose(pModHdlr); - ABORT_FINALIZE(RS_RET_ERR); + ABORT_FINALIZE(RS_RET_MODULE_LOAD_ERR_INIT_FAILED); } finalize_it: diff --git a/rsyslog.h b/rsyslog.h index 01329aaf..9fe162d5 100644 --- a/rsyslog.h +++ b/rsyslog.h @@ -162,6 +162,11 @@ enum rsRetVal_ /** return value. All methods return this if not specified oth RS_RET_OBJ_ALREADY_REGISTERED = -2061, /**< object (name) is already registered */ RS_RET_OBJ_REGISTRY_OUT_OF_SPACE = -2062, /**< the object registry has run out of space */ RS_RET_HOST_NOT_PERMITTED = -2063, /**< a host is not permitted to perform an action it requested */ + RS_RET_MODULE_LOAD_ERR = -2064, /**< module could not be loaded */ + RS_RET_MODULE_LOAD_ERR_PATHLEN = -2065, /**< module could not be loaded - path to long */ + RS_RET_MODULE_LOAD_ERR_DLOPEN = -2066, /**< module could not be loaded - problem in dlopen() */ + RS_RET_MODULE_LOAD_ERR_NO_INIT = -2067, /**< module could not be loaded - init() missing */ + RS_RET_MODULE_LOAD_ERR_INIT_FAILED = -2068, /**< module could not be loaded - init() failed */ /* RainerScript error messages (range 1000.. 1999) */ RS_RET_SYSVAR_NOT_FOUND = 1001, /**< system variable could not be found (maybe misspelled) */ diff --git a/syslogd.c b/syslogd.c index 1c31fb61..8c71f57d 100644 --- a/syslogd.c +++ b/syslogd.c @@ -2828,11 +2828,15 @@ static rsRetVal InitGlobalClasses(void) { DEFiRet; + char *pErrObj; /* tells us which object failed if that happens (useful for troubleshooting!) */ + pErrObj = "obj"; CHKiRet(objClassInit(NULL)); /* *THIS* *MUST* always be the first class initilizer being called! */ CHKiRet(objGetObjInterface(&obj)); /* this provides the root pointer for all other queries */ /* the following classes were intialized by objClassInit() */ + pErrObj = "errmsg"; CHKiRet(objUse(errmsg, CORE_COMPONENT)); + pErrObj = "module"; CHKiRet(objUse(module, CORE_COMPONENT)); /* initialize and use classes. We must be very careful with the order of events. Some @@ -2843,35 +2847,61 @@ InitGlobalClasses(void) * class immediately after it is initialized. And, of course, we load those classes * first that we use ourselfs... -- rgerhards, 2008-03-07 */ + pErrObj = "datetime"; CHKiRet(datetimeClassInit(NULL)); CHKiRet(objUse(datetime, CORE_COMPONENT)); + pErrObj = "msg"; CHKiRet(msgClassInit(NULL)); + pErrObj = "str,"; CHKiRet(strmClassInit(NULL)); + pErrObj = "wti"; CHKiRet(wtiClassInit(NULL)); + pErrObj = "wtp"; CHKiRet(wtpClassInit(NULL)); + pErrObj = "queue"; CHKiRet(queueClassInit(NULL)); + pErrObj = "vmstk"; CHKiRet(vmstkClassInit(NULL)); + pErrObj = "sysvar"; CHKiRet(sysvarClassInit(NULL)); + pErrObj = "vm"; CHKiRet(vmClassInit(NULL)); CHKiRet(objUse(vm, CORE_COMPONENT)); + pErrObj = "vmop"; CHKiRet(vmopClassInit(NULL)); + pErrObj = "vmprg"; CHKiRet(vmprgClassInit(NULL)); + pErrObj = "ctok_token"; CHKiRet(ctok_tokenClassInit(NULL)); + pErrObj = "ctok"; CHKiRet(ctokClassInit(NULL)); + pErrObj = "expr"; CHKiRet(exprClassInit(NULL)); CHKiRet(objUse(expr, CORE_COMPONENT)); + pErrObj = "conf"; CHKiRet(confClassInit(NULL)); CHKiRet(objUse(conf, CORE_COMPONENT)); /* dummy "classes" */ + pErrObj = "action"; CHKiRet(actionClassInit()); + pErrObj = "template"; CHKiRet(templateInit()); + pErrObj = "str"; CHKiRet(strInit()); /* TODO: the dependency on net shall go away! -- rgerhards, 2008-03-07 */ + pErrObj = "net"; CHKiRet(objUse(net, LM_NET_FILENAME)); finalize_it: + if(iRet != RS_RET_OK) { + /* we know we are inside the init sequence, so we can safely emit + * messages to stderr. -- rgerhards, 2008-04-02 + */ + fprintf(stderr, "Error during class init for object '%s' - failing...\n", pErrObj); + } + RETiRet; } @@ -2957,7 +2987,14 @@ int realMain(int argc, char **argv) int bImUxSockLoaded = 0; /* already generated a $ModLoad imuxsock? */ uchar legacyConfLine[80]; - CHKiRet(InitGlobalClasses()); + + CHKiRet_Hdlr(InitGlobalClasses()) { + fprintf(stderr, "rsyslogd initializiation failed - global classes could not be initialized.\n" + "Did you do a \"make install\"?\n" + "Suggested action: run rsyslogd with -d -n options to see what exactly " + "fails.\n"); + FINALIZE; + } /* doing some core initializations */ if((iRet = modInitIminternal()) != RS_RET_OK) { @@ -3298,7 +3335,8 @@ int realMain(int argc, char **argv) finalize_it: if(iRet != RS_RET_OK) - fprintf(stderr, "rsyslogd run failed with error %d.\n", iRet); + fprintf(stderr, "rsyslogd run failed with error %d\n(see rsyslog.h " + "or http://www.rsyslog.com/errcode to learn what that number means)\n", iRet); ENDfunc return 0; -- cgit