diff --git a/src/usr.sbin/ntpd/client.c b/src/usr.sbin/ntpd/client.c index 10a95fed..816f72f9 100644 --- a/src/usr.sbin/ntpd/client.c +++ b/src/usr.sbin/ntpd/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.33 2004/09/14 22:01:28 henning Exp $ */ +/* $OpenBSD: client.c,v 1.34 2004/09/18 20:01:38 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -154,7 +154,7 @@ client_query(struct ntp_peer *p) } int -client_dispatch(struct ntp_peer *p) +client_dispatch(struct ntp_peer *p, u_int8_t settime) { struct sockaddr_storage fsa; socklen_t fsa_len; @@ -251,6 +251,8 @@ client_dispatch(struct ntp_peer *p) } client_update(p); + if (settime) + ntp_settime(p->reply[p->shift].offset); log_debug("reply from %s: offset %f delay %f, " "next query %ds", log_sockaddr((struct sockaddr *)&fsa), diff --git a/src/usr.sbin/ntpd/ntp.c b/src/usr.sbin/ntpd/ntp.c index 568178b2..1f955e2b 100644 --- a/src/usr.sbin/ntpd/ntp.c +++ b/src/usr.sbin/ntpd/ntp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntp.c,v 1.32 2004/09/18 07:33:14 henning Exp $ */ +/* $OpenBSD: ntp.c,v 1.33 2004/09/18 20:01:38 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -56,7 +58,7 @@ ntp_sighdlr(int sig) pid_t ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf) { - int nfds, i, j, idx_peers, timeout; + int nfds, i, j, idx_peers, timeout, nullfd; u_int pfd_elms = 0, idx2peer_elms = 0; u_int listener_cnt, new_cnt; pid_t pid; @@ -84,11 +86,21 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf) if ((pw = getpwnam(NTPD_USER)) == NULL) fatal(NULL); + if ((nullfd = open(_PATH_DEVNULL, O_RDWR, 0)) == -1) + fatal(NULL); + if (chroot(pw->pw_dir) == -1) fatal("chroot"); if (chdir("/") == -1) fatal("chdir(\"/\")"); + if (!nconf->debug) { + dup2(nullfd, STDIN_FILENO); + dup2(nullfd, STDOUT_FILENO); + dup2(nullfd, STDERR_FILENO); + } + close(nullfd); + setproctitle("ntp engine"); conf = nconf; @@ -228,8 +240,8 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf) for (; nfds > 0 && j < i; j++) if (pfd[j].revents & POLLIN) { nfds--; - if (client_dispatch(idx2peer[j - idx_peers]) == - -1) + if (client_dispatch(idx2peer[j - idx_peers], + conf->settime) == -1) ntp_quit = 1; } } @@ -361,6 +373,13 @@ ntp_adjtime(void) p->update.good = 0; } +void +ntp_settime(double offset) +{ + imsg_compose(ibuf_main, IMSG_SETTIME, 0, 0, &offset, sizeof(offset)); + conf->settime = 0; +} + void ntp_host_dns(char *name, u_int32_t peerid) { diff --git a/src/usr.sbin/ntpd/ntpd.8 b/src/usr.sbin/ntpd/ntpd.8 index 4717842e..4a93b4d9 100644 --- a/src/usr.sbin/ntpd/ntpd.8 +++ b/src/usr.sbin/ntpd/ntpd.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ntpd.8,v 1.5 2004/07/13 19:51:38 jmc Exp $ +.\" $OpenBSD: ntpd.8,v 1.6 2004/09/18 20:01:38 henning Exp $ .\" .\" Copyright (c) 2003, 2004 Henning Brauer .\" @@ -23,7 +23,7 @@ .Sh SYNOPSIS .Nm ntpd .Bk -words -.Op Fl d +.Op Fl ds .Op Fl f Ar file .Ek .Sh DESCRIPTION @@ -38,6 +38,10 @@ and the Network Time Protocol version 3, as described in RFC 1305. .Pp .Nm +uses the +.Xr adjtime 2 , +system call to correct the local system time without causing time jumps. +.Nm is usually started at boot time, and can be enabled by setting the following in .Pa /etc/rc.conf.local : @@ -71,6 +75,10 @@ Use as the configuration file, instead of the default .Pa /etc/ntpd.conf . +.It Fl s +Set the time immediately once at startup to allow for a large time correction, +eleminating the need to run rdate before starting +.Nm . .El .Sh FILES .Bl -tag -width "/etc/ntpd.confXXX" -compact diff --git a/src/usr.sbin/ntpd/ntpd.c b/src/usr.sbin/ntpd/ntpd.c index c69c19c5..f4955903 100644 --- a/src/usr.sbin/ntpd/ntpd.c +++ b/src/usr.sbin/ntpd/ntpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntpd.c,v 1.17 2004/09/15 19:21:25 henning Exp $ */ +/* $OpenBSD: ntpd.c,v 1.18 2004/09/18 20:01:38 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -37,8 +37,9 @@ void sighdlr(int); void usage(void); int main(int, char *[]); int check_child(pid_t, const char *); -int dispatch_imsg(void); +int dispatch_imsg(struct ntpd_conf *); void ntpd_adjtime(double); +void ntpd_settime(double); volatile sig_atomic_t quit = 0; volatile sig_atomic_t reconfig = 0; @@ -67,7 +68,7 @@ usage(void) { extern char *__progname; - fprintf(stderr, "usage: %s [-d] [-f file]\n", __progname); + fprintf(stderr, "usage: %s [-d] [-f file] [-s]\n", __progname); exit(1); } @@ -81,8 +82,7 @@ main(int argc, char *argv[]) struct pollfd pfd[POLL_MAX]; pid_t chld_pid = 0, pid; char *conffile; - int debug = 0; - int ch, nfds; + int ch, nfds, timeout = INFTIM; int pipe_chld[2]; conffile = CONFFILE; @@ -91,14 +91,17 @@ main(int argc, char *argv[]) log_init(1); /* log to stderr until daemonized */ - while ((ch = getopt(argc, argv, "df:")) != -1) { + while ((ch = getopt(argc, argv, "df:s")) != -1) { switch (ch) { case 'd': - debug = 1; + conf.debug = 1; break; case 'f': conffile = optarg; break; + case 's': + conf.settime = 1; + break; default: usage(); /* NOTREACHED */ @@ -119,10 +122,12 @@ main(int argc, char *argv[]) } endpwent(); - log_init(debug); - - if (!debug) - daemon(1, 0); + if (!conf.settime) { + log_init(conf.debug); + if (!conf.debug) + daemon(1, 0); + } else + timeout = 15 * 1000; if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_chld) == -1) fatal("socketpair"); @@ -149,12 +154,22 @@ main(int argc, char *argv[]) if (ibuf->w.queued) pfd[PFD_PIPE].events |= POLLOUT; - if ((nfds = poll(pfd, 1, INFTIM)) == -1) + if ((nfds = poll(pfd, 1, timeout)) == -1) if (errno != EINTR) { log_warn("poll error"); quit = 1; } + if (nfds == 0 && conf.settime) { + log_debug("no reply received, skipping initial time" + "setting"); + conf.settime = 0; + timeout = INFTIM; + log_init(conf.debug); + if (!conf.debug) + daemon(1, 0); + } + if (nfds > 0 && (pfd[PFD_PIPE].revents & POLLOUT)) if (msgbuf_write(&ibuf->w) < 0) { log_warn("pipe write error (to child"); @@ -163,7 +178,7 @@ main(int argc, char *argv[]) if (nfds > 0 && pfd[PFD_PIPE].revents & POLLIN) { nfds--; - if (dispatch_imsg() == -1) + if (dispatch_imsg(&conf) == -1) quit = 1; } @@ -213,7 +228,7 @@ check_child(pid_t pid, const char *pname) } int -dispatch_imsg(void) +dispatch_imsg(struct ntpd_conf *conf) { struct imsg imsg; int n, cnt; @@ -244,6 +259,19 @@ dispatch_imsg(void) memcpy(&d, imsg.data, sizeof(d)); ntpd_adjtime(d); break; + case IMSG_SETTIME: + if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d)) + fatal("invalid IMSG_SETTIME received"); + if (!conf->settime) + break; + memcpy(&d, imsg.data, sizeof(d)); + ntpd_settime(d); + /* daemonize now */ + log_init(conf->debug); + if (!conf->debug) + daemon(1, 0); + conf->settime = 0; + break; case IMSG_HOST_DNS: name = imsg.data; if (imsg.hdr.len != strlen(name) + 1 + IMSG_HEADER_SIZE) @@ -278,3 +306,27 @@ ntpd_adjtime(double d) if (adjtime(&tv, NULL) == -1) log_warn("adjtime failed"); } + +void +ntpd_settime(double d) +{ + struct timeval tv, curtime; + char buf[80]; + time_t tval; + + d_to_tv(d, &tv); + if (gettimeofday(&curtime, NULL) == -1) + log_warn("gettimeofday"); + curtime.tv_sec += tv.tv_sec; + curtime.tv_usec += tv.tv_usec; + if (curtime.tv_usec > 1000000) { + curtime.tv_sec++; + curtime.tv_usec -= 1000000; + } + if (settimeofday(&curtime, NULL) == -1) + log_warn("settimeofday"); + tval = curtime.tv_sec; + strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y", + localtime(&tval)); + log_info("set local clock to %s (offset %fs)", buf, d); +} diff --git a/src/usr.sbin/ntpd/ntpd.h b/src/usr.sbin/ntpd/ntpd.h index d571ba9f..19705d8a 100644 --- a/src/usr.sbin/ntpd/ntpd.h +++ b/src/usr.sbin/ntpd/ntpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ntpd.h,v 1.37 2004/09/18 07:33:14 henning Exp $ */ +/* $OpenBSD: ntpd.h,v 1.38 2004/09/18 20:01:38 henning Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -109,8 +109,9 @@ struct ntp_peer { struct ntpd_conf { TAILQ_HEAD(listen_addrs, listen_addr) listen_addrs; TAILQ_HEAD(ntp_peers, ntp_peer) ntp_peers; - u_int8_t opts; u_int8_t listen_all; + u_int8_t settime; + u_int8_t debug; struct ntp_status status; }; @@ -149,6 +150,7 @@ struct imsgbuf { enum imsg_type { IMSG_NONE, IMSG_ADJTIME, + IMSG_SETTIME, IMSG_HOST_DNS }; @@ -200,6 +202,7 @@ void imsg_free(struct imsg *); /* ntp.c */ pid_t ntp_main(int[2], struct ntpd_conf *); void ntp_adjtime(void); +void ntp_settime(double); void ntp_host_dns(char *, u_int32_t); /* parse.y */ @@ -224,7 +227,7 @@ int client_peer_init(struct ntp_peer *); int client_addr_init(struct ntp_peer *); int client_nextaddr(struct ntp_peer *); int client_query(struct ntp_peer *); -int client_dispatch(struct ntp_peer *); +int client_dispatch(struct ntp_peer *, u_int8_t); /* util.c */ double gettime(void);