syslogd has always bugged me with it's async startup at boot time.

For me, more often than not, the backgrounded syslogd daemon is not
yet ready to process log messages before other things (such as named)
want to log a heap of them.  It seems that it's the O_SYNC writes of
the stuff coming in from /dev/klog that's the slowdown.

Anyway, instead of using the libc daemon, roll a modified version.  This
one has a timeout.  The child will wait for either the timeout to expire
or the child process to signal it to let it know that it's "ready" and
the /dev/log socket is set up and active, so it's safe to continue the
boot.  It adds a small fraction of a second pause to the boot time, but on
the other hand the overall boot time is *quicker* since the disk is not
being thrashed while the log messages are getting written out synchronously
one by one while other daemons are loading in parallel.

The timeout is in case the child segfaults or something before becoming
fully operational.
This commit is contained in:
Peter Wemm 1996-10-05 15:20:51 +00:00
parent 7fa5f4263e
commit 4ed8e95bc0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=18710

View File

@ -39,7 +39,7 @@ static const char copyright[] =
static char sccsid[] = "@(#)syslogd.c 8.3 (Berkeley) 4/4/94";
*/
static const char rcsid[] =
"$Id: syslogd.c,v 1.8 1995/11/14 23:39:39 peter Exp $";
"$Id: syslogd.c,v 1.9 1996/07/22 16:35:50 pst Exp $";
#endif /* not lint */
/*
@ -212,6 +212,7 @@ void reapchild __P((int));
char *ttymsg __P((struct iovec *, int, char *, int));
void usage __P((void));
void wallmsg __P((struct filed *, struct iovec *));
int waitdaemon __P((int, int, int));
int
main(argc, argv)
@ -223,6 +224,8 @@ main(argc, argv)
struct sockaddr_in sin, frominet;
FILE *fp;
char *p, line[MSG_BSIZE + 1];
struct timeval tv, *tvp;
pid_t ppid;
while ((ch = getopt(argc, argv, "dsf:Im:p:")) != EOF)
switch(ch) {
@ -249,9 +252,11 @@ main(argc, argv)
if ((argc -= optind) != 0)
usage();
if (!Debug)
(void)daemon(0, 0);
else
if (!Debug) {
ppid = waitdaemon(0, 0, 30);
if (ppid < 0)
err(1, "could not become daemon");
} else
setlinebuf(stdout);
consfile.f_type = F_CONSOLE;
@ -333,14 +338,23 @@ main(argc, argv)
init(0);
(void)signal(SIGHUP, init);
tvp = &tv;
tv.tv_sec = tv.tv_usec = 0;
for (;;) {
int nfds, readfds = FDMASK(funix) | inetm | klogm;
dprintf("readfds = %#x\n", readfds);
nfds = select(20, (fd_set *)&readfds, (fd_set *)NULL,
(fd_set *)NULL, (struct timeval *)NULL);
if (nfds == 0)
(fd_set *)NULL, tvp);
if (nfds == 0) {
if (tvp) {
tvp = NULL;
if (ppid != 1)
kill(ppid, SIGALRM);
}
continue;
}
if (nfds < 0) {
if (errno != EINTR)
logerror("select");
@ -1212,3 +1226,54 @@ decode(name, codetab)
return (-1);
}
static char *exitmsg;
void
timeout(sig)
int sig __unused;
{
int left;
left = alarm(0);
signal(SIGALRM, SIG_DFL);
if (left == 0)
exitmsg = "timed out waiting for child";
return;
}
int
waitdaemon(nochdir, noclose, maxwait)
int nochdir, noclose, maxwait;
{
int fd;
switch (fork()) {
case -1:
return (-1);
case 0:
break;
default:
signal(SIGALRM, timeout);
alarm(maxwait);
pause();
if (exitmsg)
err(1, exitmsg);
else
exit(0);
}
if (setsid() == -1)
return (-1);
if (!nochdir)
(void)chdir("/");
if (!noclose && (fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
(void)dup2(fd, STDIN_FILENO);
(void)dup2(fd, STDOUT_FILENO);
(void)dup2(fd, STDERR_FILENO);
if (fd > 2)
(void)close (fd);
}
return (getppid());
}