diff options
-rw-r--r-- | lib/libc/sys/adjtime.2 | 7 | ||||
-rw-r--r-- | sys/kern/kern_time.c | 40 |
2 files changed, 32 insertions, 15 deletions
diff --git a/lib/libc/sys/adjtime.2 b/lib/libc/sys/adjtime.2 index ec1196129af..ed0fc358745 100644 --- a/lib/libc/sys/adjtime.2 +++ b/lib/libc/sys/adjtime.2 @@ -1,4 +1,4 @@ -.\" $OpenBSD: adjtime.2,v 1.17 2007/05/31 19:19:32 jmc Exp $ +.\" $OpenBSD: adjtime.2,v 1.18 2009/06/05 15:17:02 ckuethe Exp $ .\" $NetBSD: adjtime.2,v 1.5 1995/10/12 15:40:44 jtc Exp $ .\" .\" Copyright (c) 1980, 1991, 1993 @@ -30,7 +30,7 @@ .\" .\" @(#)adjtime.2 8.1 (Berkeley) 6/4/93 .\" -.Dd $Mdocdate: May 31 2007 $ +.Dd $Mdocdate: June 5 2009 $ .Dt ADJTIME 2 .Os .Sh NAME @@ -67,6 +67,9 @@ If .Fa olddelta is non-null, the structure pointed to will contain, upon return, the number of microseconds still to be corrected from the earlier call. +Setting the time with +.Xr settimeofday 2 +will cancel any in-progress time adjustment. .Pp This call may be used by time servers that synchronize the clocks of computers in a local area network. diff --git a/sys/kern/kern_time.c b/sys/kern/kern_time.c index 2f407187375..cbf0c4e27f5 100644 --- a/sys/kern/kern_time.c +++ b/sys/kern/kern_time.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_time.c,v 1.65 2008/09/19 23:36:24 djm Exp $ */ +/* $OpenBSD: kern_time.c,v 1.66 2009/06/05 15:17:02 ckuethe Exp $ */ /* $NetBSD: kern_time.c,v 1.20 1996/02/18 11:57:06 fvdl Exp $ */ /* @@ -66,7 +66,7 @@ int settime(struct timespec *ts) { struct timespec now; - + /* * Don't allow the time to be set forward so far it will wrap @@ -319,6 +319,16 @@ sys_gettimeofday(struct proc *p, void *v, register_t *retval) return (error); } +#ifdef __HAVE_TIMECOUNTER +struct timeval adjtimedelta; /* unapplied time correction */ +#else +int tickdelta; /* current clock skew, us. per tick */ +long timedelta; /* unapplied time correction, us. */ +long bigadj = 1000000; /* use 10x skew above bigadj us. */ +int64_t ntp_tick_permanent; +int64_t ntp_tick_acc; +#endif + /* ARGSUSED */ int sys_settimeofday(struct proc *p, void *v, register_t *retval) @@ -343,6 +353,20 @@ sys_settimeofday(struct proc *p, void *v, register_t *retval) if (SCARG(uap, tv)) { struct timespec ts; + /* + * Adjtime in progress is meaningless or harmful after + * setting the clock. Cancel adjtime and then set new time. + */ +#ifdef __HAVE_TIMECOUNTER + adjtimedelta.tv_usec = 0; + adjtimedelta.tv_sec = 0; +#else + int s = splclock(); + tickdelta = 0; + timedelta = 0; + splx(s); +#endif + TIMEVAL_TO_TIMESPEC(&atv, &ts); if ((error = settime(&ts)) != 0) return (error); @@ -352,16 +376,6 @@ sys_settimeofday(struct proc *p, void *v, register_t *retval) return (0); } -#ifdef __HAVE_TIMECOUNTER -struct timeval adjtimedelta; /* unapplied time correction */ -#else -int tickdelta; /* current clock skew, us. per tick */ -long timedelta; /* unapplied time correction, us. */ -long bigadj = 1000000; /* use 10x skew above bigadj us. */ -int64_t ntp_tick_permanent; -int64_t ntp_tick_acc; -#endif - /* ARGSUSED */ int sys_adjfreq(struct proc *p, void *v, register_t *retval) @@ -478,7 +492,7 @@ sys_adjtime(struct proc *p, void *v, register_t *retval) odelta = ndelta; ndelta += atv.tv_usec; if (atv.tv_usec > 0 && ndelta <= odelta) - ndelta = LONG_MAX; + ndelta = LONG_MAX; else if (atv.tv_usec < 0 && ndelta >= odelta) ndelta = LONG_MIN; } |