diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | doc/rsyslog_conf_global.html | 9 | ||||
-rw-r--r-- | doc/v5compatibility.html | 1 | ||||
-rw-r--r-- | runtime/glbl.c | 107 | ||||
-rw-r--r-- | tools/syslogd.c | 165 |
5 files changed, 161 insertions, 125 deletions
@@ -1,4 +1,8 @@ --------------------------------------------------------------------------- +Version 5.8.11 [V5-stable] 2012-04-?? +- bugfix: hostname was not requeried on HUP + Thanks to Marius Tomaschewski for reporting this bug. +--------------------------------------------------------------------------- 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 21786a7f..83eb876b 100644 --- a/doc/rsyslog_conf_global.html +++ b/doc/rsyslog_conf_global.html @@ -152,15 +152,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/runtime/glbl.c b/runtime/glbl.c index dea5a17b..b6dc7286 100644 --- a/runtime/glbl.c +++ b/runtime/glbl.c @@ -69,10 +69,10 @@ static int bDropMalPTRMsgs = 0;/* Drop messages which have malicious PTR records static int option_DisallowWarning = 1; /* complain if message from disallowed sender is received */ static int bDisableDNS = 0; /* don't look up IP addresses of remote messages */ 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 */ @@ -115,15 +115,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 */ @@ -202,6 +199,19 @@ finalize_it: RETiRet; } +/* 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* @@ -227,6 +237,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 @@ -271,6 +301,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! */ @@ -373,30 +411,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; @@ -437,21 +463,14 @@ ENDObjClassInit(glbl) * rgerhards, 2008-04-17 */ BEGINObjClassExit(glbl, OBJ_IS_CORE_MODULE) /* class, version */ - if(pszDfltNetstrmDrvr != NULL) - free(pszDfltNetstrmDrvr); - if(pszDfltNetstrmDrvrCAF != NULL) - free(pszDfltNetstrmDrvrCAF); - if(pszDfltNetstrmDrvrKeyFile != NULL) - free(pszDfltNetstrmDrvrKeyFile); - if(pszDfltNetstrmDrvrCertFile != NULL) - free(pszDfltNetstrmDrvrCertFile); - if(pszWorkDir != NULL) - free(pszWorkDir); - if(LocalHostName != NULL) - free(LocalHostName); + free(pszDfltNetstrmDrvr); + free(pszDfltNetstrmDrvrCAF); + free(pszDfltNetstrmDrvrKeyFile); + free(pszDfltNetstrmDrvrCertFile); + free(pszWorkDir); + free(LocalHostName); free(LocalHostNameOverride); - if(LocalFQDNName != NULL) - free(LocalFQDNName); + free(LocalFQDNName); objRelease(prop, CORE_COMPONENT); DESTROY_ATOMIC_HELPER_MUT(mutTerminateInputs); ENDObjClassExit(glbl) diff --git a/tools/syslogd.c b/tools/syslogd.c index 0b7bbc96..183decb1 100644 --- a/tools/syslogd.c +++ b/tools/syslogd.c @@ -154,6 +154,7 @@ DEFobjCurrIf(net) /* TODO: make go away! */ /* forward definitions */ static rsRetVal GlobalClassExit(void); +static rsRetVal queryLocalHostname(void); #ifndef _PATH_LOGCONF @@ -1897,6 +1898,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) @@ -1912,6 +1918,7 @@ doHUP(void) logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0); } + queryLocalHostname(); /* re-read our name */ ruleset.IterateAllActions(doHUPActions, NULL); } @@ -2329,6 +2336,90 @@ 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; + } + } + } + + /* 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 @@ -2530,9 +2621,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; @@ -2541,9 +2630,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 @@ -2651,7 +2737,7 @@ 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)); CHKiRet(prop.Construct(&pLocalHostIP)); @@ -2661,72 +2747,7 @@ int realMain(int argc, char **argv) /* 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) { |