diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | doc/rsyslog_conf_global.html | 9 | ||||
-rw-r--r-- | doc/v5compatibility.html | 1 | ||||
-rw-r--r-- | plugins/imuxsock/imuxsock.c | 15 | ||||
-rw-r--r-- | runtime/glbl.c | 88 | ||||
-rw-r--r-- | tools/syslogd.c | 170 |
6 files changed, 168 insertions, 120 deletions
@@ -126,6 +126,11 @@ Version 5.9.0 [V5-DEVEL] (rgerhards), 2011-06-08 affected directive was: $ActionExecOnlyWhenPreviousIsSuspended on closes: http://bugzilla.adiscon.com/show_bug.cgi?id=236 --------------------------------------------------------------------------- +Version 5.8.11 [V5-stable] 2012-04-?? +- bugfix: hostname was not requeried on HUP + Thanks to Per Jessen for reporting this bug and Marius Tomaschewski for + his help in testing the fix. +--------------------------------------------------------------------------- Version 5.8.10 [V5-stable] 2012-04-05 - bugfix: segfault on startup if $actionqueuefilename was missing for disk queue config diff --git a/doc/rsyslog_conf_global.html b/doc/rsyslog_conf_global.html index 8cfdd303..6c20f4c2 100644 --- a/doc/rsyslog_conf_global.html +++ b/doc/rsyslog_conf_global.html @@ -153,15 +153,6 @@ our paper on <a href="multi_ruleset.html">using multiple rule sets in rsyslog</a <li><a href="rsconf1_gssforwardservicename.html">$GssForwardServiceName</a></li> <li><a href="rsconf1_gsslistenservicename.html">$GssListenServiceName</a></li> <li><a href="rsconf1_gssmode.html">$GssMode</a></li> -<li>$HUPisRestart [on/<b>off</b>] - if set to on, a HUP is a full daemon restart. This means any queued messages are discarded (depending -on queue configuration, of course) all modules are unloaded and reloaded. This mode keeps compatible with sysklogd, but is -not recommended for use with rsyslog. To do a full restart, simply stop and start the daemon. The default (since 4.5.1) is "off". -If it is set to "off", a HUP will only close open files. This is a much quicker action and usually -the only one that is needed e.g. for log rotation. <b>Restart-type HUPs (value "on") are depricated</b> -and will go away in rsyslog v5. So it is a good idea to change anything that needs it, now. -Usually that should not be a big issue, as the restart-type HUP can easily be replaced by -something along the lines of "/etc/init.d/rsyslog restart". -</li> <li><a href="rsconf1_includeconfig.html">$IncludeConfig</a></li><li>MainMsgQueueCheckpointInterval <number></li> <li><b>$LocalHostName</b> [name] - this directive permits to overwrite the system hostname with the one specified in the directive. If the directive is given diff --git a/doc/v5compatibility.html b/doc/v5compatibility.html index cc875b7b..fc4289c5 100644 --- a/doc/v5compatibility.html +++ b/doc/v5compatibility.html @@ -16,6 +16,7 @@ available. This processing was redundant and had a lot a drawbacks. For details, please see the <a href="v4compatibility.html">rsyslog v4 compatibility notes</a> which elaborate on the reasons and the (few) things you may need to change. +<p>Please note that starting with 5.8.11 HUP will also requery the local hostname. <h2>Queue on-disk format</h2> <p>The queue information file format has been changed. When upgrading from v4 to v5, make sure that the queue is emptied and no on-disk structure present. We did diff --git a/plugins/imuxsock/imuxsock.c b/plugins/imuxsock/imuxsock.c index 7b122c50..ea54e79b 100644 --- a/plugins/imuxsock/imuxsock.c +++ b/plugins/imuxsock/imuxsock.c @@ -289,16 +289,16 @@ addLstnSocketName(void __attribute__((unused)) *pVal, uchar *pNewVal) } else { listeners[nfd].bParseHost = 0; } - CHKiRet(prop.Construct(&(listeners[nfd].hostName))); if(pLogHostName == NULL) { - CHKiRet(prop.SetString(listeners[nfd].hostName, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()))); + listeners[nfd].hostName = NULL; } else { + CHKiRet(prop.Construct(&(listeners[nfd].hostName))); CHKiRet(prop.SetString(listeners[nfd].hostName, pLogHostName, ustrlen(pLogHostName))); + CHKiRet(prop.ConstructFinalize(listeners[nfd].hostName)); /* reset hostname for next socket */ free(pLogHostName); pLogHostName = NULL; } - CHKiRet(prop.ConstructFinalize(listeners[nfd].hostName)); if(ratelimitInterval > 0) { if((listeners[nfd].ht = create_hashtable(100, hash_from_key_fn, key_equals_fn, NULL)) == NULL) { /* in this case, we simply turn of rate-limiting */ @@ -778,7 +778,7 @@ SubmitMsg(uchar *pRcv, int lenRcv, lstn_t *pLstn, struct ucred *cred, struct tim pMsg->msgFlags = pLstn->flags; } - MsgSetRcvFrom(pMsg, pLstn->hostName); + MsgSetRcvFrom(pMsg, pLstn->hostName == NULL ? glbl.GetLocalHostNameProp() : pLstn->hostName); CHKiRet(MsgSetRcvFromIP(pMsg, pLocalHostIP)); CHKiRet(submitMsg(pMsg)); @@ -1051,7 +1051,6 @@ CODESTARTafterRun if(pInputName != NULL) prop.Destruct(&pInputName); - ENDafterRun @@ -1147,9 +1146,9 @@ CODEmodInit_QueryRegCFSLineHdlr } /* now init listen socket zero, the local log socket */ - CHKiRet(prop.Construct(&(listeners[0].hostName))); - CHKiRet(prop.SetString(listeners[0].hostName, glbl.GetLocalHostName(), ustrlen(glbl.GetLocalHostName()))); - CHKiRet(prop.ConstructFinalize(listeners[0].hostName)); + CHKiRet(prop.Construct(&pLocalHostIP)); + CHKiRet(prop.SetString(pLocalHostIP, UCHAR_CONSTANT("127.0.0.1"), sizeof("127.0.0.1") - 1)); + CHKiRet(prop.ConstructFinalize(pLocalHostIP)); /* register config file handlers */ CHKiRet(omsdRegCFSLineHdlr((uchar *)"omitlocallogging", 0, eCmdHdlrBinary, diff --git a/runtime/glbl.c b/runtime/glbl.c index 4f2ee377..ff4358c4 100644 --- a/runtime/glbl.c +++ b/runtime/glbl.c @@ -70,10 +70,10 @@ static int option_DisallowWarning = 1; /* complain if message from disallowed se static int bDisableDNS = 0; /* don't look up IP addresses of remote messages */ static prop_t *propLocalIPIF = NULL;/* IP address to report for the local host (default is 127.0.0.1) */ static prop_t *propLocalHostName = NULL;/* our hostname as FQDN - read-only after startup */ -static uchar *LocalHostName = NULL;/* our hostname - read-only after startup */ +static uchar *LocalHostName = NULL;/* our hostname - read-only after startup, except HUP */ static uchar *LocalHostNameOverride = NULL;/* user-overridden hostname - read-only after startup */ -static uchar *LocalFQDNName = NULL;/* our hostname as FQDN - read-only after startup */ -static uchar *LocalDomain; /* our local domain name - read-only after startup */ +static uchar *LocalFQDNName = NULL;/* our hostname as FQDN - read-only after startup, except HUP */ +static uchar *LocalDomain = NULL;/* our local domain name - read-only after startup, except HUP */ static char **StripDomains = NULL;/* these domains may be stripped before writing logs - r/o after s.u., never touched by init */ static char **LocalHosts = NULL;/* these hosts are logged with their hostname - read-only after startup, never touched by init */ static uchar *pszDfltNetstrmDrvr = NULL; /* module name of default netstream driver */ @@ -116,15 +116,12 @@ SIMP_PROP(DefPFFamily, iDefPFFamily, int) /* note that in the future we may chec SIMP_PROP(DropMalPTRMsgs, bDropMalPTRMsgs, int) SIMP_PROP(Option_DisallowWarning, option_DisallowWarning, int) SIMP_PROP(DisableDNS, bDisableDNS, int) -SIMP_PROP(LocalDomain, LocalDomain, uchar*) SIMP_PROP(StripDomains, StripDomains, char**) SIMP_PROP(LocalHosts, LocalHosts, char**) #ifdef USE_UNLIMITED_SELECT SIMP_PROP(FdSetSize, iFdSetSize, int) #endif -SIMP_PROP_SET(LocalFQDNName, LocalFQDNName, uchar*) -SIMP_PROP_SET(LocalHostName, LocalHostName, uchar*) SIMP_PROP_SET(DfltNetstrmDrvr, pszDfltNetstrmDrvr, uchar*) /* TODO: use custom function which frees existing value */ SIMP_PROP_SET(DfltNetstrmDrvrCAF, pszDfltNetstrmDrvrCAF, uchar*) /* TODO: use custom function which frees existing value */ SIMP_PROP_SET(DfltNetstrmDrvrKeyFile, pszDfltNetstrmDrvrKeyFile, uchar*) /* TODO: use custom function which frees existing value */ @@ -273,6 +270,20 @@ GetLocalHostIP(void) return(propLocalIPIF); } + +/* set our local hostname. Free previous hostname, if it was already set. + * Note that we do now do this in a thread + * "once in a lifetime" action which can not be undone. -- gerhards, 2009-07-20 + */ +static rsRetVal +SetLocalHostName(uchar *newname) +{ + free(LocalHostName); + LocalHostName = newname; + return RS_RET_OK; +} + + /* return our local hostname. if it is not set, "[localhost]" is returned */ static uchar* @@ -298,6 +309,26 @@ done: } +/* set our local domain name. Free previous domain, if it was already set. + */ +static rsRetVal +SetLocalDomain(uchar *newname) +{ + free(LocalDomain); + LocalDomain = newname; + return RS_RET_OK; +} + + +/* return our local hostname. if it is not set, "[localhost]" is returned + */ +static uchar* +GetLocalDomain(void) +{ + return LocalDomain; +} + + /* generate the local hostname property. This must be done after the hostname info * has been set as well as PreserveFQDN. * rgerhards, 2009-06-30 @@ -342,6 +373,14 @@ GetLocalHostNameProp(void) } +static rsRetVal +SetLocalFQDNName(uchar *newname) +{ + free(LocalFQDNName); + LocalFQDNName = newname; + return RS_RET_OK; +} + /* return the current localhost name as FQDN (requires FQDN to be set) * TODO: we should set the FQDN ourselfs in here! */ @@ -445,30 +484,18 @@ ENDobjQueryInterface(glbl) */ static rsRetVal resetConfigVariables(uchar __attribute__((unused)) *pp, void __attribute__((unused)) *pVal) { - if(pszDfltNetstrmDrvr != NULL) { - free(pszDfltNetstrmDrvr); - pszDfltNetstrmDrvr = NULL; - } - if(pszDfltNetstrmDrvrCAF != NULL) { - free(pszDfltNetstrmDrvrCAF); - pszDfltNetstrmDrvrCAF = NULL; - } - if(pszDfltNetstrmDrvrKeyFile != NULL) { - free(pszDfltNetstrmDrvrKeyFile); - pszDfltNetstrmDrvrKeyFile = NULL; - } - if(pszDfltNetstrmDrvrCertFile != NULL) { - free(pszDfltNetstrmDrvrCertFile); - pszDfltNetstrmDrvrCertFile = NULL; - } - if(LocalHostNameOverride != NULL) { - free(LocalHostNameOverride); - LocalHostNameOverride = NULL; - } - if(pszWorkDir != NULL) { - free(pszWorkDir); - pszWorkDir = NULL; - } + free(pszDfltNetstrmDrvr); + pszDfltNetstrmDrvr = NULL; + free(pszDfltNetstrmDrvrCAF); + pszDfltNetstrmDrvrCAF = NULL; + free(pszDfltNetstrmDrvrKeyFile); + pszDfltNetstrmDrvrKeyFile = NULL; + free(pszDfltNetstrmDrvrCertFile); + pszDfltNetstrmDrvrCertFile = NULL; + free(LocalHostNameOverride); + LocalHostNameOverride = NULL; + free(pszWorkDir); + pszWorkDir = NULL; bDropMalPTRMsgs = 0; bOptimizeUniProc = 1; bPreserveFQDN = 0; @@ -515,6 +542,7 @@ BEGINObjClassExit(glbl, OBJ_IS_CORE_MODULE) /* class, version */ free(pszDfltNetstrmDrvrKeyFile); free(pszDfltNetstrmDrvrCertFile); free(pszWorkDir); + free(LocalDomain); free(LocalHostName); free(LocalHostNameOverride); free(LocalFQDNName); diff --git a/tools/syslogd.c b/tools/syslogd.c index cce1b616..7cb4d367 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -21,7 +21,7 @@ * For further information, please see http://www.rsyslog.com * * rsyslog - An Enhanced syslogd Replacement. - * Copyright 2003-2009 Rainer Gerhards and Adiscon GmbH. + * Copyright 2003-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of rsyslog. * @@ -154,6 +154,7 @@ DEFobjCurrIf(net) /* TODO: make go away! */ /* forward definitions */ static rsRetVal GlobalClassExit(void); +static rsRetVal queryLocalHostname(void); #ifndef _PATH_LOGCONF @@ -1909,6 +1910,11 @@ DEFFUNC_llExecFunc(doHUPActions) * is *NOT* the sighup handler. The signal is recorded by the handler, that record * detected inside the mainloop and then this function is called to do the * real work. -- rgerhards, 2008-10-22 + * Note: there is a VERY slim chance of a data race when the hostname is reset. + * We prefer to take this risk rather than sync all accesses, because to the best + * of my analysis it can not really hurt (the actual property is reference-counted) + * but the sync would require some extra CPU for *each* message processed. + * rgerhards, 2012-04-11 */ static inline void doHUP(void) @@ -1924,6 +1930,7 @@ doHUP(void) logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); } + queryLocalHostname(); /* re-read our name */ ruleset.IterateAllActions(doHUPActions, NULL); } @@ -2346,6 +2353,93 @@ GlobalClassExit(void) } +/* query our host and domain names - we need to do this early as we may emit + * rgerhards, 2012-04-11 + */ +static rsRetVal +queryLocalHostname(void) +{ + uchar *LocalHostName; + uchar *LocalDomain; + uchar *LocalFQDNName; + uchar *p; + struct hostent *hent; + DEFiRet; + + net.getLocalHostname(&LocalFQDNName); + CHKmalloc(LocalHostName = (uchar*) strdup((char*)LocalFQDNName)); + glbl.SetLocalFQDNName(LocalFQDNName); /* set the FQDN before we modify it */ + if((p = (uchar*)strchr((char*)LocalHostName, '.'))) { + *p++ = '\0'; + LocalDomain = p; + } else { + LocalDomain = (uchar*)""; + + /* It's not clearly defined whether gethostname() + * should return the simple hostname or the fqdn. A + * good piece of software should be aware of both and + * we want to distribute good software. Joey + * + * Good software also always checks its return values... + * If syslogd starts up before DNS is up & /etc/hosts + * doesn't have LocalHostName listed, gethostbyname will + * return NULL. + */ + /* TODO: gethostbyname() is not thread-safe, but replacing it is + * not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25 + */ + hent = gethostbyname((char*)LocalHostName); + if(hent) { + int i = 0; + + if(hent->h_aliases) { + size_t hnlen; + + hnlen = strlen((char *) LocalHostName); + + for (i = 0; hent->h_aliases[i]; i++) { + if (!strncmp(hent->h_aliases[i], (char *) LocalHostName, hnlen) + && hent->h_aliases[i][hnlen] == '.') { + /* found a matching hostname */ + break; + } + } + } + + free(LocalHostName); + if(hent->h_aliases && hent->h_aliases[i]) { + CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i])); + } else { + CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); + } + + if((p = (uchar*)strchr((char*)LocalHostName, '.'))) + { + *p++ = '\0'; + LocalDomain = p; + } + } + } + + /* LocalDomain is "" or part of LocalHostName, allocate a new string */ + CHKmalloc(LocalDomain = (uchar*)strdup((char*)LocalDomain)); + + /* Convert to lower case to recognize the correct domain laterly */ + for(p = LocalDomain ; *p ; p++) + *p = (char)tolower((int)*p); + + /* 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 + */ + glbl.SetLocalHostName(LocalHostName); + glbl.SetLocalDomain(LocalDomain); + glbl.GenerateLocalHostNameProperty(); /* must be redone after conf processing, FQDN setting may have changed */ +finalize_it: + RETiRet; +} + + /* some support for command line option parsing. Any non-trivial options must be * buffered until the complete command line has been parsed. This is necessary to * prevent dependencies between the options. That, in turn, means we need to have @@ -2547,9 +2641,7 @@ int realMain(int argc, char **argv) { DEFiRet; - register uchar *p; int ch; - struct hostent *hent; extern int optind; extern char *optarg; int bEOptionWasGiven = 0; @@ -2558,9 +2650,6 @@ int realMain(int argc, char **argv) int bChDirRoot = 1; /* change the current working directory to "/"? */ char *arg; /* for command line option processing */ uchar legacyConfLine[80]; - uchar *LocalHostName; - uchar *LocalDomain; - uchar *LocalFQDNName; char cwdbuf[128]; /* buffer to obtain/display current working directory */ /* first, parse the command line options. We do not carry out any actual work, just @@ -2668,78 +2757,13 @@ int realMain(int argc, char **argv) /* we need to create the inputName property (only once during our lifetime) */ CHKiRet(prop.Construct(&pInternalInputName)); - CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslgod") - 1)); + CHKiRet(prop.SetString(pInternalInputName, UCHAR_CONSTANT("rsyslogd"), sizeof("rsyslogd") - 1)); CHKiRet(prop.ConstructFinalize(pInternalInputName)); /* get our host and domain names - we need to do this early as we may emit * error log messages, which need the correct hostname. -- rgerhards, 2008-04-04 */ - net.getLocalHostname(&LocalFQDNName); - CHKmalloc(LocalHostName = (uchar*) strdup((char*)LocalFQDNName)); - glbl.SetLocalFQDNName(LocalFQDNName); /* set the FQDN before we modify it */ - if((p = (uchar*)strchr((char*)LocalHostName, '.'))) { - *p++ = '\0'; - LocalDomain = p; - } else { - LocalDomain = (uchar*)""; - - /* It's not clearly defined whether gethostname() - * should return the simple hostname or the fqdn. A - * good piece of software should be aware of both and - * we want to distribute good software. Joey - * - * Good software also always checks its return values... - * If syslogd starts up before DNS is up & /etc/hosts - * doesn't have LocalHostName listed, gethostbyname will - * return NULL. - */ - /* TODO: gethostbyname() is not thread-safe, but replacing it is - * not urgent as we do not run on multiple threads here. rgerhards, 2007-09-25 - */ - hent = gethostbyname((char*)LocalHostName); - if(hent) { - int i = 0; - - if(hent->h_aliases) { - size_t hnlen; - - hnlen = strlen((char *) LocalHostName); - - for (i = 0; hent->h_aliases[i]; i++) { - if (!strncmp(hent->h_aliases[i], (char *) LocalHostName, hnlen) - && hent->h_aliases[i][hnlen] == '.') { - /* found a matching hostname */ - break; - } - } - } - - free(LocalHostName); - if(hent->h_aliases && hent->h_aliases[i]) { - CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_aliases[i])); - } else { - CHKmalloc(LocalHostName = (uchar*)strdup(hent->h_name)); - } - - if((p = (uchar*)strchr((char*)LocalHostName, '.'))) - { - *p++ = '\0'; - LocalDomain = p; - } - } - } - - /* Convert to lower case to recognize the correct domain laterly */ - for(p = LocalDomain ; *p ; p++) - *p = (char)tolower((int)*p); - - /* 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 - */ - glbl.SetLocalHostName(LocalHostName); - glbl.SetLocalDomain(LocalDomain); - glbl.GenerateLocalHostNameProperty(); /* must be redone after conf processing, FQDN setting may have changed */ + queryLocalHostname(); /* initialize the objects */ if((iRet = modInitIminternal()) != RS_RET_OK) { |