jitter support for cron

Michal Belczyk belczyk at bsd.krakow.pl
Fri Mar 17 08:58:07 PST 2006


Quite useful when one has got multiple jails running their own crons.
Obtained from FreeBSD.

-- 
Michal Belczyk
Index: cron/cron.8
===================================================================
RCS file: /home/dcvs/src/usr.sbin/cron/cron/cron.8,v
retrieving revision 1.2
diff -u -r1.2 cron.8
--- cron/cron.8	17 Jun 2003 04:29:53 -0000	1.2
+++ cron/cron.8	14 Mar 2006 21:57:28 -0000
@@ -26,6 +26,8 @@
 .Nd daemon to execute scheduled commands (Vixie Cron)
 .Sh SYNOPSIS
 .Nm
+.Op Fl j Ar jitter
+.Op Fl J Ar rootjitter
 .Op Fl s
 .Op Fl o
 .Op Fl x Ar debugflag Ns Op , Ns Ar ...
@@ -79,6 +81,27 @@
 .Pp
 Available options:
 .Bl -tag -width indent
+.It Fl j Ar jitter
+Enable time jitter.
+Prior to executing commands,
+.Nm
+will sleep a random number of seconds in the range from 0 to
+.Ar jitter .
+This won't affect superuser jobs (see
+.Fl J ) .
+A value for
+.Ar jitter
+must be between 0 and 60 inclusive.
+Default is 0, which effectively disables time jitter.
+.Pp
+This option can help to smooth down system load spikes during
+moments when a lot of jobs are likely to start at once, e.g.,
+at the beginning of the first minute of each hour.
+.It Fl J Ar rootjitter
+Enable time jitter for superuser jobs.
+The same as
+.Fl j
+except that it will affect jobs run by the superuser only.
 .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/cron.c
===================================================================
RCS file: /home/dcvs/src/usr.sbin/cron/cron/cron.c,v
retrieving revision 1.6
diff -u -r1.6 cron.c
--- cron/cron.c	18 Dec 2004 22:48:03 -0000	1.6
+++ cron/cron.c	14 Mar 2006 20:59:06 -0000
@@ -50,8 +50,8 @@
 {
     char **dflags;
 
-	fprintf(stderr, "usage: cron [-s] [-o] [-x debugflag[,...]]\n");
-	fprintf(stderr, "\ndebugflags: ");
+	fprintf(stderr, "usage: cron [-j jitter] [-J rootjitter] "
+			"[-s] [-o] [-x debugflag[,...]]\n");
 
         for(dflags = DebugFlagNames; *dflags; dflags++) {
 		fprintf(stderr, "%s ", *dflags);
@@ -409,9 +409,22 @@
 parse_args(int argc, char **argv)
 {
 	int	argch;
+	char	*endp;
 
-	while ((argch = getopt(argc, argv, "osx:")) != -1) {
+	while ((argch = getopt(argc, argv, "j:J:osx:")) != -1) {
 		switch (argch) {
+		case 'j':
+			Jitter = strtoul(optarg, &endp, 10);
+			if (*optarg == '\0' || *endp != '\0' || Jitter > 60)
+				errx(ERROR_EXIT,
+				     "bad value for jitter: %s", optarg);
+			break;
+		case 'J':
+			RootJitter = strtoul(optarg, &endp, 10);
+			if (*optarg == '\0' || *endp != '\0' || RootJitter > 60)
+				errx(ERROR_EXIT,
+				     "bad value for root jitter: %s", optarg);
+			break;
 		case 'o':
 			dst_enabled = 0;
 			break;
Index: cron/cron.h
===================================================================
RCS file: /home/dcvs/src/usr.sbin/cron/cron/cron.h,v
retrieving revision 1.4
diff -u -r1.4 cron.h
--- cron/cron.h	10 Mar 2004 18:27:26 -0000	1.4
+++ cron/cron.h	14 Mar 2006 20:08:44 -0000
@@ -269,6 +269,8 @@
 
 char	*ProgramName;
 int	LineNumber;
+unsigned Jitter,
+	RootJitter;
 time_t	TargetTime;
 
 # if DEBUGGING
@@ -284,6 +286,8 @@
 		*DowNames[],
 		*ProgramName;
 extern	int	LineNumber;
+extern unsigned	Jitter,
+		RootJitter;
 extern	time_t	TargetTime;
 # if DEBUGGING
 extern	int	DebugFlags;
Index: cron/do_command.c
===================================================================
RCS file: /home/dcvs/src/usr.sbin/cron/cron/do_command.c,v
retrieving revision 1.6
diff -u -r1.6 do_command.c
--- cron/do_command.c	18 Dec 2004 22:48:03 -0000	1.6
+++ cron/do_command.c	14 Mar 2006 20:09:36 -0000
@@ -159,6 +159,13 @@
 		Debug(DPROC, ("[%d] grandchild process Vfork()'ed\n",
 			      getpid()))
 
+		if (e->uid == ROOT_UID)
+			Jitter = RootJitter;
+		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




More information about the Submit mailing list