On 2021-05-05 19:38:27 +0200, Michael Biebl wrote:
> Am 05.05.2021 um 19:27 schrieb Vincent Lefevre:
> > On 2021-05-05 19:12:24 +0200, Michael Biebl wrote:
> > > Am 05.05.2021 um 18:39 schrieb Vincent Lefevre:
> > > > This issue needs to be fixed anyway. If logrotate doesn't provide such
> > > > a facility, the fix could be done in rsyslog via a locking mechanism
> > > > to avoid the race (the /usr/lib/rsyslog/rsyslog-rotate script would
> > > > hold the lock until it knows that the SIGHUP has been processed).
> > > 
> > > Signals are asynchronous, I don't see how such a script could be 
> > > implemented
> > > robustly.
> > 
> > rsyslogd gives information when it has received a SIGHUP, e.g.
> > 
> > May 05 18:34:05 zira rsyslogd[1700043]: [origin software="rsyslogd" 
> > swVersion="8.2102.0" x-pid="1700043" x-info="https://www.rsyslog.com";] 
> > rsyslogd was HUPed
> > 
> 
> I'm not sure what you are trying to suggest here. Can you elaborate? Or even
> better send a patch?

The idea is the following:

/usr/lib/rsyslog/rsyslog-rotate puts a lock, and once the lock is
acquired, it sends the SIGHUP. When it sees that the SIGHUP has
been processed[*], it releases the lock.

[*] Currently one can see in the logs that rsyslogd processed the
signal. This is done in tools/rsyslogd.c:

/* This function processes a HUP after one has been detected. Note that this
 * 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 void
doHUP(void)
{
        char buf[512];

        if(ourConf->globals.bLogStatusMsgs) {
                snprintf(buf, sizeof(buf),
                         "[origin software=\"rsyslogd\" " "swVersion=\"" VERSION
                         "\" x-pid=\"%d\" x-info=\"https://www.rsyslog.com\";] 
rsyslogd was HUPed",
                         (int) glblGetOurPid());
                        errno = 0;
                logmsgInternal(NO_ERRCODE, LOG_SYSLOG|LOG_INFO, (uchar*)buf, 0);
        }

        queryLocalHostname(); /* re-read our name */
        ruleset.IterateAllActions(ourConf, doHUPActions, NULL);
        modDoHUP();
        lookupDoHUP();
        errmsgDoHUP();
}

As said, this is not done in the signal handler, but after, so that
a second SIGHUP sent later should not be lost.

However, getting information in the log is not practical. Since the
rsyslogd daemon and the /usr/lib/rsyslog/rsyslog-rotate script come
from the same package, something better could be done.

For instance, the lock could be a file "/run/rsyslogd-hup.lock",
created with length 0. When the daemon has processed a SIGHUP, it
could write to this lock file (if existing). Once the rsyslog-rotate
script notices that the length is not 0, it removes the lock and
quits.

-- 
Vincent Lefèvre <vinc...@vinc17.net> - Web: <https://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <https://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)

Reply via email to