Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 Jan 2014 13:29:54 +0000 (UTC)
From:      "Andrey A. Chernov" <ache@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r261231 - stable/10/usr.sbin/cron/cron
Message-ID:  <201401281329.s0SDTsbw086098@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ache
Date: Tue Jan 28 13:29:54 2014
New Revision: 261231
URL: http://svnweb.freebsd.org/changeset/base/261231

Log:
  MFC: r261146
  
  Bad timespec_subtract() calculations produce negative tv_nsec on i386
  which cause EINVAL returned from nanosleep() which cause loop in
  cron_sleep() and making all cron jobs to start about 30 seconds earlier
  (which cause f.e. logfiles rotation by newsyslog delayed by 1 hour).
  
  Use simple and proved calculations from kernel's timespecsub() instead.

Modified:
  stable/10/usr.sbin/cron/cron/cron.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/usr.sbin/cron/cron/cron.c
==============================================================================
--- stable/10/usr.sbin/cron/cron/cron.c	Tue Jan 28 12:48:17 2014	(r261230)
+++ stable/10/usr.sbin/cron/cron/cron.c	Tue Jan 28 13:29:54 2014	(r261231)
@@ -376,30 +376,17 @@ cron_sync(int secres) {
 	}
 }
 
-static int
+static void
 timespec_subtract(struct timespec *result, struct timespec *x,
     struct timespec *y)
 {
-	time_t nsec;
-
-	/* Perform the carry for the later subtraction by updating y. */
-	if (x->tv_nsec < y->tv_nsec) {
-		nsec = (y->tv_nsec - x->tv_nsec) / 10000000 + 1;
-		y->tv_nsec -= 1000000000 * nsec;
-		y->tv_sec += nsec;
-	}
-	if (x->tv_nsec - y->tv_nsec > 1000000000) {
-		nsec = (x->tv_nsec - y->tv_nsec) / 1000000000;
-		y->tv_nsec += 1000000000 * nsec;
-		y->tv_sec -= nsec;
-	}
-     
-	/* tv_nsec is certainly positive. */
-	result->tv_sec = x->tv_sec - y->tv_sec;
-	result->tv_nsec = x->tv_nsec - y->tv_nsec;
-     
-	/* Return True if result is negative. */
-	return (x->tv_sec < y->tv_sec);
+	*result = *x;
+	result->tv_sec -= y->tv_sec;
+	result->tv_nsec -= y->tv_nsec;
+	if (result->tv_nsec < 0) {
+		result->tv_sec--;
+		result->tv_nsec += 1000000000;
+	}
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201401281329.s0SDTsbw086098>