From marck@woozle.rinet.ru  Mon May 10 08:20:19 2004
Return-Path: <marck@woozle.rinet.ru>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id C640016A4CF
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 10 May 2004 08:20:19 -0700 (PDT)
Received: from woozle.rinet.ru (woozle.rinet.ru [195.54.192.68])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 979F543D31
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 10 May 2004 08:20:18 -0700 (PDT)
	(envelope-from marck@woozle.rinet.ru)
Received: from woozle.rinet.ru (localhost [127.0.0.1])
	by woozle.rinet.ru (8.12.11/8.12.11) with ESMTP id i4AFKHnO063340
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 10 May 2004 19:20:17 +0400 (MSD)
	(envelope-from marck@woozle.rinet.ru)
Received: (from marck@localhost)
	by woozle.rinet.ru (8.12.11/8.12.11/Submit) id i4AFKHhu063339;
	Mon, 10 May 2004 19:20:17 +0400 (MSD)
	(envelope-from marck)
Message-Id: <200405101520.i4AFKHhu063339@woozle.rinet.ru>
Date: Mon, 10 May 2004 19:20:17 +0400 (MSD)
From: Dmitry Morozovsky <marck@rinet.ru>
Reply-To: Dmitry Morozovsky <marck@rinet.ru>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: [patch] add jitter to cron(8) to smooth load spikes
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         66474
>Category:       bin
>Synopsis:       [patch] add jitter to cron(8) to smooth load spikes
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    yar
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Mon May 10 08:30:17 PDT 2004
>Closed-Date:    Mon May 31 11:59:11 PDT 2004
>Last-Modified:  Mon May 31 11:59:11 PDT 2004
>Originator:     Dmitry Morozovsky
>Release:        FreeBSD 4-STABLE i386
>Organization:
Cronyx Plus LLC (RiNet ISP)
>Environment:
System: FreeBSD 4-STABLE 

>Description:

An a system with many users there are load spikes at the beginning of any
minute when cron(8) executes jobs.  This problem is addressed with the
following patch (idea and first implementation by sply, cv-c -at- fluid
-dot- ru).

>How-To-Repeat:

>Fix:


Index: cron.8
===================================================================
RCS file: /home/ncvs/src/usr.sbin/cron/cron/cron.8,v
retrieving revision 1.7.2.9
diff -u -r1.7.2.9 cron.8
--- cron.8	11 Mar 2003 21:13:48 -0000	1.7.2.9
+++ cron.8	10 May 2004 15:05:13 -0000
@@ -25,6 +25,7 @@
 .Nd daemon to execute scheduled commands (Vixie Cron)
 .Sh SYNOPSIS
 .Nm
+.Op Fl j Ar jitter
 .Op Fl s
 .Op Fl o
 .Op Fl x Ar debugflag Ns Op , Ns Ar ...
@@ -78,6 +79,13 @@
 .Pp
 Available options:
 .Bl -tag -width indent
+.It Fl j Ar jitter
+Enable exec jitter: before executing commands,
+.Nm
+will sleep random time (in seconds) between 0 and
+.Ar jitter .
+.Ar jitter
+must be between 0 (disabled) and 60 (one minute).
 .It Fl s
 Enable special handling of situations when the GMT offset of the local
 timezone changes, such as the switches between the standard time and
Index: cron.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/cron/cron/cron.c,v
retrieving revision 1.9.2.2
diff -u -r1.9.2.2 cron.c
--- cron.c	28 May 2001 23:37:26 -0000	1.9.2.2
+++ cron.c	10 May 2004 15:05:13 -0000
@@ -51,7 +51,7 @@
 usage() {
     char **dflags;
 
-	fprintf(stderr, "usage: cron [-s] [-o] [-x debugflag[,...]]\n");
+	fprintf(stderr, "usage: cron [-j jitter] [-s] [-o] [-x debugflag[,...]]\n");
 	fprintf(stderr, "\ndebugflags: ");
 
         for(dflags = DebugFlagNames; *dflags; dflags++) {
@@ -415,8 +415,13 @@
 {
 	int	argch;
 
-	while ((argch = getopt(argc, argv, "osx:")) != -1) {
+	while ((argch = getopt(argc, argv, "j:osx:")) != -1) {
 		switch (argch) {
+		case 'j':
+			if ((Jitter = atoi(optarg)) < 0 ||
+			    Jitter > 60)
+				errx(1, "bad -j value: %s", optarg);
+			break;
 		case 'o':
 			dst_enabled = 0;
 			break;
Index: cron.h
===================================================================
RCS file: /home/ncvs/src/usr.sbin/cron/cron/cron.h,v
retrieving revision 1.9.2.3
diff -u -r1.9.2.3 cron.h
--- cron.h	28 May 2001 23:37:26 -0000	1.9.2.3
+++ cron.h	10 May 2004 15:05:13 -0000
@@ -268,7 +268,8 @@
 	};
 
 char	*ProgramName;
-int	LineNumber;
+int	LineNumber,
+	Jitter;
 time_t	TargetTime;
 
 # if DEBUGGING
@@ -283,7 +284,8 @@
 		*MonthNames[],
 		*DowNames[],
 		*ProgramName;
-extern	int	LineNumber;
+extern	int	LineNumber,
+		Jitter;
 extern	time_t	TargetTime;
 # if DEBUGGING
 extern	int	DebugFlags;
Index: do_command.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/cron/cron/do_command.c,v
retrieving revision 1.15.2.6
diff -u -r1.15.2.6 do_command.c
--- do_command.c	22 Jun 2003 18:49:39 -0000	1.15.2.6
+++ do_command.c	10 May 2004 15:05:13 -0000
@@ -251,6 +251,10 @@
 #endif
 		chdir(env_get("HOME", e->envp));
 
+		if (Jitter != 0) {
+			srandom(getpid());
+			sleep(random() % Jitter);
+		}
 		/* exec the command.
 		 */
 		{
>Release-Note:
>Audit-Trail:

From: Dmitry Morozovsky <marck@rinet.ru>
To: FreeBSD-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: bin/66474: [patch] add jitter to cron(8) to smooth load spikes
Date: Mon, 10 May 2004 19:39:49 +0400 (MSD)

 On Mon, 10 May 2004 FreeBSD-gnats-submit@FreeBSD.org wrote:
 
 Minor correction [do_command.c]: sleep part moved earlier to improve logging.
 
 Sincerely,
 D.Marck                                     [DM5020, MCK-RIPE, DM3-RIPN]
 ------------------------------------------------------------------------
 *** Dmitry Morozovsky --- D.Marck --- Wild Woozle --- marck@rinet.ru ***
 ------------------------------------------------------------------------
 
 Index: usr.sbin/cron/cron/do_command.c
 ===================================================================
 RCS file: /home/ncvs/src/usr.sbin/cron/cron/do_command.c,v
 retrieving revision 1.15.2.6
 diff -u -r1.15.2.6 do_command.c
 --- usr.sbin/cron/cron/do_command.c	22 Jun 2003 18:49:39 -0000	1.15.2.6
 +++ usr.sbin/cron/cron/do_command.c	10 May 2004 15:36:10 -0000
 @@ -166,6 +166,11 @@
  		Debug(DPROC, ("[%d] grandchild process Vfork()'ed\n",
  			      getpid()))
 
 +		if (Jitter != 0) {
 +			srandom(getpid());
 +			sleep(random() % Jitter);
 +		}
 +
  		/* write a log message.  we've waited this long to do it
  		 * because it was not until now that we knew the PID that
  		 * the actual user command shell was going to get and the
Responsible-Changed-From-To: freebsd-bugs->yar 
Responsible-Changed-By: yar 
Responsible-Changed-When: Tue May 11 08:43:02 PDT 2004 
Responsible-Changed-Why:  
I'm collaborating on the final solution with the originator. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=66474 
State-Changed-From-To: open->patched 
State-Changed-By: yar 
State-Changed-When: Sun May 16 12:30:36 PDT 2004 
State-Changed-Why:  
Keep it as MFC reminder. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=66474 
State-Changed-From-To: patched->closed 
State-Changed-By: yar 
State-Changed-When: Mon May 31 11:58:16 PDT 2004 
State-Changed-Why:  
This feature has appeared in both active branches, thanks. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=66474 
>Unformatted:
