Browse Source

add a new -s option, that tells ntpd to set the time using settimeofday()

once at startup. ntpd delays daemonizing until it has done the intial
time setting (or ran into the timeout) in this mode to make sure stuff started
later in rc is not subject to time jumps.
this eleminates the need to run rdate -n beforehands.
with some input from & ok ryan and bob, march music from mickey
OPENBSD_3_7
henning 20 years ago
parent
commit
80548b0292
5 changed files with 109 additions and 25 deletions
  1. +4
    -2
      src/usr.sbin/ntpd/client.c
  2. +23
    -4
      src/usr.sbin/ntpd/ntp.c
  3. +10
    -2
      src/usr.sbin/ntpd/ntpd.8
  4. +66
    -14
      src/usr.sbin/ntpd/ntpd.c
  5. +6
    -3
      src/usr.sbin/ntpd/ntpd.h

+ 4
- 2
src/usr.sbin/ntpd/client.c View File

@ -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 <henning@openbsd.org> * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -154,7 +154,7 @@ client_query(struct ntp_peer *p)
} }
int int
client_dispatch(struct ntp_peer *p)
client_dispatch(struct ntp_peer *p, u_int8_t settime)
{ {
struct sockaddr_storage fsa; struct sockaddr_storage fsa;
socklen_t fsa_len; socklen_t fsa_len;
@ -251,6 +251,8 @@ client_dispatch(struct ntp_peer *p)
} }
client_update(p); client_update(p);
if (settime)
ntp_settime(p->reply[p->shift].offset);
log_debug("reply from %s: offset %f delay %f, " log_debug("reply from %s: offset %f delay %f, "
"next query %ds", log_sockaddr((struct sockaddr *)&fsa), "next query %ds", log_sockaddr((struct sockaddr *)&fsa),


+ 23
- 4
src/usr.sbin/ntpd/ntp.c View File

@ -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 <henning@openbsd.org> * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -19,6 +19,8 @@
#include <sys/param.h> #include <sys/param.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <poll.h> #include <poll.h>
#include <pwd.h> #include <pwd.h>
#include <signal.h> #include <signal.h>
@ -56,7 +58,7 @@ ntp_sighdlr(int sig)
pid_t pid_t
ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf) 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 pfd_elms = 0, idx2peer_elms = 0;
u_int listener_cnt, new_cnt; u_int listener_cnt, new_cnt;
pid_t pid; pid_t pid;
@ -84,11 +86,21 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf)
if ((pw = getpwnam(NTPD_USER)) == NULL) if ((pw = getpwnam(NTPD_USER)) == NULL)
fatal(NULL); fatal(NULL);
if ((nullfd = open(_PATH_DEVNULL, O_RDWR, 0)) == -1)
fatal(NULL);
if (chroot(pw->pw_dir) == -1) if (chroot(pw->pw_dir) == -1)
fatal("chroot"); fatal("chroot");
if (chdir("/") == -1) if (chdir("/") == -1)
fatal("chdir(\"/\")"); fatal("chdir(\"/\")");
if (!nconf->debug) {
dup2(nullfd, STDIN_FILENO);
dup2(nullfd, STDOUT_FILENO);
dup2(nullfd, STDERR_FILENO);
}
close(nullfd);
setproctitle("ntp engine"); setproctitle("ntp engine");
conf = nconf; conf = nconf;
@ -228,8 +240,8 @@ ntp_main(int pipe_prnt[2], struct ntpd_conf *nconf)
for (; nfds > 0 && j < i; j++) for (; nfds > 0 && j < i; j++)
if (pfd[j].revents & POLLIN) { if (pfd[j].revents & POLLIN) {
nfds--; nfds--;
if (client_dispatch(idx2peer[j - idx_peers]) ==
-1)
if (client_dispatch(idx2peer[j - idx_peers],
conf->settime) == -1)
ntp_quit = 1; ntp_quit = 1;
} }
} }
@ -361,6 +373,13 @@ ntp_adjtime(void)
p->update.good = 0; p->update.good = 0;
} }
void
ntp_settime(double offset)
{
imsg_compose(ibuf_main, IMSG_SETTIME, 0, 0, &offset, sizeof(offset));
conf->settime = 0;
}
void void
ntp_host_dns(char *name, u_int32_t peerid) ntp_host_dns(char *name, u_int32_t peerid)
{ {


+ 10
- 2
src/usr.sbin/ntpd/ntpd.8 View File

@ -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 <henning@openbsd.org> .\" Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
.\" .\"
@ -23,7 +23,7 @@
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm ntpd .Nm ntpd
.Bk -words .Bk -words
.Op Fl d
.Op Fl ds
.Op Fl f Ar file .Op Fl f Ar file
.Ek .Ek
.Sh DESCRIPTION .Sh DESCRIPTION
@ -38,6 +38,10 @@ and the Network Time Protocol version 3,
as described in RFC 1305. as described in RFC 1305.
.Pp .Pp
.Nm .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 is usually started at boot time, and can be enabled by
setting the following in setting the following in
.Pa /etc/rc.conf.local : .Pa /etc/rc.conf.local :
@ -71,6 +75,10 @@ Use
as the configuration file, as the configuration file,
instead of the default instead of the default
.Pa /etc/ntpd.conf . .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 .El
.Sh FILES .Sh FILES
.Bl -tag -width "/etc/ntpd.confXXX" -compact .Bl -tag -width "/etc/ntpd.confXXX" -compact


+ 66
- 14
src/usr.sbin/ntpd/ntpd.c View File

@ -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 <henning@openbsd.org> * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -37,8 +37,9 @@ void sighdlr(int);
void usage(void); void usage(void);
int main(int, char *[]); int main(int, char *[]);
int check_child(pid_t, const char *); int check_child(pid_t, const char *);
int dispatch_imsg(void);
int dispatch_imsg(struct ntpd_conf *);
void ntpd_adjtime(double); void ntpd_adjtime(double);
void ntpd_settime(double);
volatile sig_atomic_t quit = 0; volatile sig_atomic_t quit = 0;
volatile sig_atomic_t reconfig = 0; volatile sig_atomic_t reconfig = 0;
@ -67,7 +68,7 @@ usage(void)
{ {
extern char *__progname; extern char *__progname;
fprintf(stderr, "usage: %s [-d] [-f file]\n", __progname);
fprintf(stderr, "usage: %s [-d] [-f file] [-s]\n", __progname);
exit(1); exit(1);
} }
@ -81,8 +82,7 @@ main(int argc, char *argv[])
struct pollfd pfd[POLL_MAX]; struct pollfd pfd[POLL_MAX];
pid_t chld_pid = 0, pid; pid_t chld_pid = 0, pid;
char *conffile; char *conffile;
int debug = 0;
int ch, nfds;
int ch, nfds, timeout = INFTIM;
int pipe_chld[2]; int pipe_chld[2];
conffile = CONFFILE; conffile = CONFFILE;
@ -91,14 +91,17 @@ main(int argc, char *argv[])
log_init(1); /* log to stderr until daemonized */ 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) { switch (ch) {
case 'd': case 'd':
debug = 1;
conf.debug = 1;
break; break;
case 'f': case 'f':
conffile = optarg; conffile = optarg;
break; break;
case 's':
conf.settime = 1;
break;
default: default:
usage(); usage();
/* NOTREACHED */ /* NOTREACHED */
@ -119,10 +122,12 @@ main(int argc, char *argv[])
} }
endpwent(); 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) if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_chld) == -1)
fatal("socketpair"); fatal("socketpair");
@ -149,12 +154,22 @@ main(int argc, char *argv[])
if (ibuf->w.queued) if (ibuf->w.queued)
pfd[PFD_PIPE].events |= POLLOUT; pfd[PFD_PIPE].events |= POLLOUT;
if ((nfds = poll(pfd, 1, INFTIM)) == -1)
if ((nfds = poll(pfd, 1, timeout)) == -1)
if (errno != EINTR) { if (errno != EINTR) {
log_warn("poll error"); log_warn("poll error");
quit = 1; 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 (nfds > 0 && (pfd[PFD_PIPE].revents & POLLOUT))
if (msgbuf_write(&ibuf->w) < 0) { if (msgbuf_write(&ibuf->w) < 0) {
log_warn("pipe write error (to child"); log_warn("pipe write error (to child");
@ -163,7 +178,7 @@ main(int argc, char *argv[])
if (nfds > 0 && pfd[PFD_PIPE].revents & POLLIN) { if (nfds > 0 && pfd[PFD_PIPE].revents & POLLIN) {
nfds--; nfds--;
if (dispatch_imsg() == -1)
if (dispatch_imsg(&conf) == -1)
quit = 1; quit = 1;
} }
@ -213,7 +228,7 @@ check_child(pid_t pid, const char *pname)
} }
int int
dispatch_imsg(void)
dispatch_imsg(struct ntpd_conf *conf)
{ {
struct imsg imsg; struct imsg imsg;
int n, cnt; int n, cnt;
@ -244,6 +259,19 @@ dispatch_imsg(void)
memcpy(&d, imsg.data, sizeof(d)); memcpy(&d, imsg.data, sizeof(d));
ntpd_adjtime(d); ntpd_adjtime(d);
break; 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: case IMSG_HOST_DNS:
name = imsg.data; name = imsg.data;
if (imsg.hdr.len != strlen(name) + 1 + IMSG_HEADER_SIZE) if (imsg.hdr.len != strlen(name) + 1 + IMSG_HEADER_SIZE)
@ -278,3 +306,27 @@ ntpd_adjtime(double d)
if (adjtime(&tv, NULL) == -1) if (adjtime(&tv, NULL) == -1)
log_warn("adjtime failed"); 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);
}

+ 6
- 3
src/usr.sbin/ntpd/ntpd.h View File

@ -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 <henning@openbsd.org> * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -109,8 +109,9 @@ struct ntp_peer {
struct ntpd_conf { struct ntpd_conf {
TAILQ_HEAD(listen_addrs, listen_addr) listen_addrs; TAILQ_HEAD(listen_addrs, listen_addr) listen_addrs;
TAILQ_HEAD(ntp_peers, ntp_peer) ntp_peers; TAILQ_HEAD(ntp_peers, ntp_peer) ntp_peers;
u_int8_t opts;
u_int8_t listen_all; u_int8_t listen_all;
u_int8_t settime;
u_int8_t debug;
struct ntp_status status; struct ntp_status status;
}; };
@ -149,6 +150,7 @@ struct imsgbuf {
enum imsg_type { enum imsg_type {
IMSG_NONE, IMSG_NONE,
IMSG_ADJTIME, IMSG_ADJTIME,
IMSG_SETTIME,
IMSG_HOST_DNS IMSG_HOST_DNS
}; };
@ -200,6 +202,7 @@ void imsg_free(struct imsg *);
/* ntp.c */ /* ntp.c */
pid_t ntp_main(int[2], struct ntpd_conf *); pid_t ntp_main(int[2], struct ntpd_conf *);
void ntp_adjtime(void); void ntp_adjtime(void);
void ntp_settime(double);
void ntp_host_dns(char *, u_int32_t); void ntp_host_dns(char *, u_int32_t);
/* parse.y */ /* parse.y */
@ -224,7 +227,7 @@ int client_peer_init(struct ntp_peer *);
int client_addr_init(struct ntp_peer *); int client_addr_init(struct ntp_peer *);
int client_nextaddr(struct ntp_peer *); int client_nextaddr(struct ntp_peer *);
int client_query(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 */ /* util.c */
double gettime(void); double gettime(void);


Loading…
Cancel
Save