Date: Mon, 15 Mar 1999 23:57:10 -0500 (EST) From: Brian Haug <haug@hawaii.conterra.com> To: FreeBSD-gnats-submit@freebsd.org Subject: kern/10609: adjtime bug (tv_sec >2147 ) and enhancement (nil first arg) Message-ID: <199903160457.XAA05229@hawaii.conterra.com>
next in thread | raw e-mail | index | archive | help
>Number: 10609
>Category: kern
>Synopsis: adjtime bug (tv_sec > 2147) and enhancement (nil first arg)
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Mon Mar 15 21:00:00 PST 1999
>Closed-Date:
>Last-Modified:
>Originator: Brian Haug
>Release: FreeBSD 3.1-RELEASE i386 (?? send-pr from different system)
>Organization:
None
>Environment:
probably any system with adjtime system call
>Description:
1. Bug: adjtime can not handle adjustments whos absolute value exceeds
2148 (or stricly exceeds 2147)
2. Change request: adjtime does not accept a nil first argument to
allow the application to determine the current delta being
applied to the clock.
3. Documentation doesn't note the first issue (code fix attached).
>How-To-Repeat:
use "date -a 2148" (code in follow on report) or examine the code.
Note that 2147 seconds (expressed as microseconds) is real close
to MAXINT, and 2148 seconds would exceed this.
Call adjtime with the value NULL for the first argument, note that
the system call will fail.
>Fix:
Hopefully the code diffs are all correct. I've used BRH_ to diferentiate the
two fixes, and would actually suggest not using the ifdefs. The two problems
are somewhat intertwined, so I appologize for tying them together. The man
page only attempts to dealwith the NIL first argument issue since the other
problem is now fixed in the kernel.
*** /usr/src/sys/kern/kern_time.c.old Sun Oct 25 10:44:51 1998
--- /usr/src/sys/kern/kern_time.c Sun Mar 14 08:02:31 1999
***************
*** 322,328 ****
--- 322,332 ----
}
int tickdelta; /* current clock skew, us. per tick */
+ #ifdef BRH_ADJTIME_BIG
+ long long timedelta; /* unapplied time correction, us. */
+ #else
long timedelta; /* unapplied time correction, us. */
+ #endif
static long bigadj = 1000000; /* use 10x skew above bigadj us. */
#ifndef _SYS_SYSPROTO_H_
***************
*** 338,351 ****
--- 342,370 ----
register struct adjtime_args *uap;
{
struct timeval atv;
+ #ifdef BRH_ADJTIME_BIG
+ long long ndelta, odelta;
+ register long ntickdelta;
+ #else
register long ndelta, ntickdelta, odelta;
+ #endif
int s, error;
+ #ifdef BRH_ADJTIME_NULL
+ int for_real;
+ #endif
if ((error = suser(p->p_ucred, &p->p_acflag)))
return (error);
+ #ifndef BRH_ADJTIME_NULL
if ((error =
copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof(struct timeval))))
return (error);
+ #else
+ for_real = (caddr_t)NULL != (caddr_t)uap->delta;
+ if (for_real && (error =
+ copyin((caddr_t)uap->delta, (caddr_t)&atv, sizeof(struct timeval))))
+ return (error);
+ #endif
/*
* Compute the total correction and the rate at which to apply it.
***************
*** 354,360 ****
--- 373,386 ----
* hardclock(), tickdelta will become zero, lest the correction
* overshoot and start taking us away from the desired final time.
*/
+ #ifdef BRH_ADJTIME_NULL
+ if (for_real) {
+ #endif
+ #ifdef BRH_ADJTIME_BIG
+ ndelta = (long long)atv.tv_sec * 1000000 + atv.tv_usec;
+ #else
ndelta = atv.tv_sec * 1000000 + atv.tv_usec;
+ #endif
if (ndelta > bigadj || ndelta < -bigadj)
ntickdelta = 10 * tickadj;
else
***************
*** 369,378 ****
--- 395,413 ----
*/
if (ndelta < 0)
ntickdelta = -ntickdelta;
+ #ifdef BRH_ADJTIME_NULL
+ }
+ #endif
s = splclock();
odelta = timedelta;
+ #ifdef BRH_ADJTIME_NULL
+ if (for_real) {
+ #endif
timedelta = ndelta;
tickdelta = ntickdelta;
+ #ifdef BRH_ADJTIME_NULL
+ }
+ #endif
splx(s);
if (uap->olddelta) {
*** /usr/src/sys/sys/kernel.h.old Sun Mar 14 07:56:11 1999
--- /usr/src/sys/sys/kernel.h Sun Mar 14 07:57:04 1999
***************
*** 73,79 ****
--- 73,83 ----
extern int ticks;
extern int lbolt; /* once a second sleep address */
extern int tickdelta;
+ #ifdef BRH_ADJTIME_BIG
+ extern long long timedelta;
+ #else
extern long timedelta;
+ #endif
#endif /* KERNEL */
*** /usr/src/lib/libc/sys/adjtime.2.old Sun Mar 14 08:08:37 1999
--- /usr/src/lib/libc/sys/adjtime.2 Sun Mar 14 08:14:13 1999
***************
*** 66,71 ****
--- 66,76 ----
.Fn adjtime
is called again.
If
+ .Fa delta
+ is nil, then no changes are made to the clock.
+ This is useful when one wants to determine the amount of adjustment which
+ is yet to be performed.
+ If
.Fa olddelta
is non-nil,
the structure pointed to will contain, upon return, the
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199903160457.XAA05229>
