aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/syslogd
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>1996-10-05 15:20:51 +0000
committerPeter Wemm <peter@FreeBSD.org>1996-10-05 15:20:51 +0000
commit4ed8e95bc081536cf5a69c9896da5a2f82c4049f (patch)
treef98e3f04a4c4989f9d38bb667b0dfef899243711 /usr.sbin/syslogd
parent7fa5f4263e8c499a2d348734d1a994cace02a850 (diff)
downloadsrc-4ed8e95bc081536cf5a69c9896da5a2f82c4049f.tar.gz
src-4ed8e95bc081536cf5a69c9896da5a2f82c4049f.zip
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.
Notes
Notes: svn path=/head/; revision=18710
Diffstat (limited to 'usr.sbin/syslogd')
-rw-r--r--usr.sbin/syslogd/syslogd.c77
1 files changed, 71 insertions, 6 deletions
diff --git a/usr.sbin/syslogd/syslogd.c b/usr.sbin/syslogd/syslogd.c
index 5979a925fdc7..8bff619a0059 100644
--- a/usr.sbin/syslogd/syslogd.c
+++ b/usr.sbin/syslogd/syslogd.c
@@ -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());
+}