summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-10-05 15:20:51 +0000
committerpeter <peter@FreeBSD.org>1996-10-05 15:20:51 +0000
commit57a32f2a60b272fa2e9d7f5b29d4b08661928797 (patch)
treef98e3f04a4c4989f9d38bb667b0dfef899243711
parenta35caa54e5bf2a7af0ac49bb44838dc1144ceabc (diff)
downloadFreeBSD-src-57a32f2a60b272fa2e9d7f5b29d4b08661928797.zip
FreeBSD-src-57a32f2a60b272fa2e9d7f5b29d4b08661928797.tar.gz
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.
-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 5979a92..8bff619 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());
+}
OpenPOWER on IntegriCloud