syslogd: Integrate new timer API

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson 2019-12-06 18:13:15 +01:00
parent 5ac6c39687
commit 6e6c0ddfaa
4 changed files with 85 additions and 69 deletions

View File

@ -39,11 +39,10 @@
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "queue.h"
#include "socket.h"
#include "syslogd.h"
struct sock {

View File

@ -31,9 +31,12 @@
#ifndef SYSKLOGD_SOCKET_H_
#define SYSKLOGD_SOCKET_H_
#include <netdb.h>
#include <stdarg.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
int socket_register(int sd, struct addrinfo *ai, void (*cb)(int, void *), void *arg);
int socket_create (struct addrinfo *ai, void (*cb)(int, void *), void *arg);

View File

@ -91,6 +91,7 @@ static char sccsid[] __attribute__((unused)) =
#define SYSLOG_NAMES
#include "syslogd.h"
#include "socket.h"
#include "timer.h"
#include "compat.h"
char *ConfFile = _PATH_LOGCONF;
@ -128,7 +129,6 @@ static int MarkInterval = 20 * 60; /* interval between marks in seconds */
static int family = PF_UNSPEC; /* protocol family (IPv4, IPv6 or both) */
static int mask_C1 = 1; /* mask characters from 0x80 - 0x9F */
static int send_to_all; /* send message to all IPv4/IPv6 addresses */
static int MarkSeq = 0; /* mark sequence number */
static int SecureMode; /* when true, receive only unix domain socks */
static int RemoteAddDate; /* Always set the date on remote messages */
@ -165,7 +165,8 @@ void wallmsg(struct filed *f, struct iovec *iov, int iovcnt);
void reapchild();
const char *cvtaddr(struct sockaddr_storage *f, int len);
const char *cvthname(struct sockaddr *f, socklen_t len);
void domark();
void domark(void *arg);
void doflush(void *arg);
void debug_switch();
void die(int sig);
void doexit(int sig);
@ -422,15 +423,23 @@ int main(int argc, char *argv[])
(void)signal(SIGINT, Debug ? die : SIG_IGN);
(void)signal(SIGQUIT, Debug ? die : SIG_IGN);
(void)signal(SIGCHLD, reapchild);
(void)signal(SIGALRM, domark);
(void)signal(SIGUSR1, Debug ? debug_switch : SIG_IGN);
(void)signal(SIGXFSZ, SIG_IGN);
(void)signal(SIGHUP, sighup_handler);
alarm(TIMERINTVL);
logit("Starting.\n");
init();
/*
* Set up timer callbacks for -- MARK -- et al
*/
if (MarkInterval > 0)
timer_add(TIMERINTVL, domark, NULL);
timer_add(FLUSHINTVL, doflush, NULL);
/* Start 'em */
timer_start();
if (Debug) {
logit("Debugging disabled, SIGUSR1 to turn on debugging.\n");
debugging_on = 0;
@ -464,16 +473,8 @@ int main(int argc, char *argv[])
continue;
}
if (rc == 0) {
logit("No select activity.\n");
continue;
}
if (rc < 0) {
if (errno != EINTR)
ERR("select()");
continue;
}
if (rc < 0 && errno != EINTR)
ERR("select()");
}
}
@ -989,7 +990,7 @@ parsemsg_rfc3164(const char *from, int pri, char *msg)
* This loop can only run for at most three
* iterations before terminating.
*/
t_now = time(NULL);
t_now = timer_now();
localtime_r(&t_now, &tm_now);
for (year = tm_now.tm_year + 1;; --year) {
assert(year >= tm_now.tm_year - 1);
@ -1089,6 +1090,11 @@ parsemsg(const char *from, char *msg)
if ((pri & LOG_FACMASK) == LOG_KERN && !KeepKernFac)
pri = LOG_MAKEPRI(LOG_USER, LOG_PRI(pri));
/*
* Message looks OK, update current time and log it
*/
timer_update();
/* Parse VERSION. */
msg += i + 1;
if (msg[0] == '1' && msg[1] == ' ')
@ -1156,7 +1162,22 @@ char *textpri(int pri)
return res;
}
time_t now;
static void check_timestamp(struct buf_msg *buffer)
{
struct logtime zero = { 0 };
struct logtime now;
struct timeval tv;
if (memcmp(&buffer->timestamp, &zero, sizeof(zero)))
return;
if (gettimeofday(&tv, NULL) == -1)
return;
localtime_r(&tv.tv_sec, &now.tm);
now.usec = tv.tv_usec;
buffer->timestamp = now;
}
/*
* Logs a message to the appropriate log files, users, etc. based on the
@ -1166,9 +1187,6 @@ time_t now;
*/
static void logmsg(struct buf_msg *buffer)
{
struct logtime timestamp_now;
struct logtime zero = { 0 };
struct timeval tv;
struct filed *f;
sigset_t mask;
size_t savedlen;
@ -1179,13 +1197,8 @@ static void logmsg(struct buf_msg *buffer)
textpri(buffer->pri), buffer->flags, buffer->hostname, buffer->app_name,
buffer->proc_id, buffer->msgid, buffer->sd, buffer->msg);
(void)gettimeofday(&tv, NULL);
now = tv.tv_sec;
if (!memcmp(&buffer->timestamp, &zero, sizeof(zero))) {
localtime_r(&now, &timestamp_now.tm);
timestamp_now.usec = tv.tv_usec;
buffer->timestamp = timestamp_now;
}
/* Messages generated by syslogd itself may not have a timestamp */
check_timestamp(buffer);
/* extract facility and priority level */
if (buffer->flags & MARK)
@ -1245,8 +1258,19 @@ static void logmsg(struct buf_msg *buffer)
continue;
/* don't output marks to recently written files */
if ((buffer->flags & MARK) && (now - f->f_time) < MarkInterval / 2)
continue;
if (buffer->flags & MARK) {
time_t t_now = timer_now();
fprintf(stderr, "1) f_time: %zd + MarkInterval: %d => %ld, t_now: %zd\n",
f->f_time, MarkInterval, f->f_time + MarkInterval, t_now);
if (f->f_time + MarkInterval > t_now)
continue;
fprintf(stderr, "2) t_now: %zd - f_time: %zd => %ld < MarkInterval/2 : %d\n",
t_now, f->f_time, t_now - f->f_time, MarkInterval / 2);
if (t_now - f->f_time < MarkInterval / 2)
continue;
fprintf(stderr, "3) f_time: %zd, MarkInterval: %d, t_now: %zd\n", f->f_time, MarkInterval, t_now);
}
/*
* suppress duplicate lines to this file
@ -1256,7 +1280,7 @@ static void logmsg(struct buf_msg *buffer)
f->f_lasttime = buffer->timestamp;
f->f_prevcount++;
logit("msg repeated %d times, %ld sec of %d.\n",
f->f_prevcount, now - f->f_time,
f->f_prevcount, timer_now() - f->f_time,
repeatinterval[f->f_repeatcount]);
/*
@ -1265,7 +1289,7 @@ static void logmsg(struct buf_msg *buffer)
* but back off so we'll flush less often
* in the future.
*/
if (now > REPEATTIME(f)) {
if (timer_now() > REPEATTIME(f)) {
fprintlog_successive(f, buffer->flags);
BACKOFF(f);
}
@ -1366,12 +1390,12 @@ void fprintlog_write(struct filed *f, struct iovec *iov, int iovcnt, int flags)
switch (f->f_type) {
case F_UNUSED:
f->f_time = now;
f->f_time = timer_now();
logit("\n");
break;
case F_FORW_SUSP:
fwd_suspend = time(NULL) - f->f_time;
fwd_suspend = timer_now() - f->f_time;
if (fwd_suspend >= INET_SUSPEND_TIME) {
logit("\nForwarding suspension over, retrying FORW ");
f->f_type = F_FORW;
@ -1390,7 +1414,7 @@ void fprintlog_write(struct filed *f, struct iovec *iov, int iovcnt, int flags)
case F_FORW:
f_forw:
logit(" %s:%s\n", f->f_un.f_forw.f_hname, f->f_un.f_forw.f_serv);
f->f_time = now;
f->f_time = timer_now();
memset(&msg, 0, sizeof(msg));
msg.msg_iov = iov;
@ -1444,7 +1468,7 @@ void fprintlog_write(struct filed *f, struct iovec *iov, int iovcnt, int flags)
break;
case F_CONSOLE:
f->f_time = now;
f->f_time = timer_now();
if (flags & IGN_CONS) {
logit(" (ignored).\n");
break;
@ -1454,7 +1478,7 @@ void fprintlog_write(struct filed *f, struct iovec *iov, int iovcnt, int flags)
case F_TTY:
case F_FILE:
case F_PIPE:
f->f_time = now;
f->f_time = timer_now();
logit(" %s\n", f->f_un.f_fname);
if (f->f_type == F_TTY || f->f_type == F_CONSOLE) {
pushiov(iov, iovcnt, "\r\n");
@ -1514,7 +1538,7 @@ void fprintlog_write(struct filed *f, struct iovec *iov, int iovcnt, int flags)
case F_USERS:
case F_WALL:
f->f_time = now;
f->f_time = timer_now();
logit("\n");
pushiov(iov, iovcnt, "\r\n");
wallmsg(f, &iov[1], iovcnt - 1);
@ -1619,25 +1643,15 @@ static int fmt5424(struct buf_msg *buffer, char *fmt, struct iovec *iov, size_t
static void fprintlog_first(struct filed *f, struct buf_msg *buffer)
{
struct logtime zero = { 0 };
struct iovec iov[20];
int iovcnt;
logit("Called fprintlog_first(), ");
if (!memcmp(&buffer->timestamp, &zero, sizeof(zero))) {
struct logtime timestamp_now;
struct timeval tv;
/* Messages generated by syslogd itself may not have a timestamp */
check_timestamp(buffer);
(void)gettimeofday(&tv, NULL);
now = tv.tv_sec;
localtime_r(&now, &timestamp_now.tm);
timestamp_now.usec = tv.tv_usec;
buffer->timestamp = timestamp_now;
}
f->f_time = now;
f->f_time = timer_now();
f->f_prevcount = 0;
if (f->f_flags & RFC5424)
@ -1706,12 +1720,14 @@ void wallmsg(struct filed *f, struct iovec *iov, int iovcnt)
* and doing notty().
*/
if (fork() == 0) {
time_t t_now = timer_now();
(void)signal(SIGTERM, SIG_DFL);
(void)alarm(0);
(void)snprintf(greetings, sizeof(greetings),
"\r\n\7Message from syslogd@%s at %.24s ...\r\n",
(char *)iov[3].iov_base, ctime(&now));
(char *)iov[3].iov_base, ctime(&t_now));
len = strlen(greetings);
/* scan the user login file */
@ -1893,7 +1909,7 @@ static void forw_lookup(struct filed *f)
/* Called from cfline() for initial lookup? */
init = f->f_type == F_UNUSED ? 1 : 0;
diff = now - f->f_time;
diff = timer_now() - f->f_time;
if (!init && diff < INET_SUSPEND_TIME) {
logit("Forwarding suspension not over, time left: %d\n",
(int)(INET_SUSPEND_TIME - diff));
@ -1907,7 +1923,7 @@ static void forw_lookup(struct filed *f)
if (err) {
WARN("Failed resolving '%s:%s': %s", host, serv, gai_strerror(err));
f->f_type = F_FORW_UNKN;
f->f_time = now;
f->f_time = timer_now();
return;
}
@ -1919,27 +1935,22 @@ static void forw_lookup(struct filed *f)
f->f_prevcount = 0;
}
void domark(int signo)
void domark(void *arg)
{
flog(INTERNAL_MARK | LOG_INFO, "-- MARK --");
}
void doflush(void *arg)
{
struct filed *f;
now = time(NULL);
if (MarkInterval > 0) {
MarkSeq += TIMERINTVL;
if (MarkSeq >= MarkInterval) {
flog(INTERNAL_MARK | LOG_INFO, "-- MARK --");
MarkSeq = 0;
}
}
SIMPLEQ_FOREACH(f, &fhead, f_link) {
if (f->f_type == F_FORW_UNKN) {
forw_lookup(f);
continue;
}
if (f->f_prevcount && now >= REPEATTIME(f)) {
if (f->f_prevcount && timer_now() >= REPEATTIME(f)) {
logit("flush %s: repeated %d times, %d sec.\n",
TypeNames[f->f_type], f->f_prevcount,
repeatinterval[f->f_repeatcount]);
@ -1947,8 +1958,6 @@ void domark(int signo)
BACKOFF(f);
}
}
(void)alarm(TIMERINTVL);
}
void debug_switch(int signo)
@ -2059,6 +2068,10 @@ void init(void)
char *p;
int i;
/* Set up timer framework */
if (timer_init())
err(1, "Failed initializing internal timers");
/* Get hostname */
(void)gethostname(LocalHostName, sizeof(LocalHostName));
LocalDomain = emptystring;

View File

@ -43,7 +43,8 @@
#define MAXSVLINE MAXLINE /* maximum saved line length */
#define DEFUPRI (LOG_USER | LOG_NOTICE)
#define DEFSPRI (LOG_KERN | LOG_CRIT)
#define TIMERINTVL 15 /* interval for checking flush, mark */
#define TIMERINTVL 30 /* interval for checking flush, mark */
#define FLUSHINTVL 10 /* interval for checking flush, mark */
#define RCVBUF_MINSIZE (80 * MAXLINE) /* minimum size of dgram rcv buffer */
/*