svn commit: r241576 - in head/usr.sbin/cron: cron crontab lib

Pawel Jakub Dawidek pjd at FreeBSD.org
Mon Oct 15 20:25:42 UTC 2012


On Mon, Oct 15, 2012 at 08:21:50AM +0000, Maxim Sobolev wrote:
> Author: sobomax
> Date: Mon Oct 15 08:21:49 2012
> New Revision: 241576
> URL: http://svn.freebsd.org/changeset/base/241576
> 
> Log:
>   Add per-second scheduling into the cron(8). Right now it's
>   only available via the new @every_second shortcut. ENOTIME to
>   implement crontab(5) format extensions to allow more flexible
>   scheduling.
>   
>   In order to address some concerns expressed by Terry Lambert
>   while discussing the topic few years ago, about per-second cron
>   possibly causing some bad effects on /etc/crontab by stat()ing
>   it every second instead of every minute now (i.e. atime update),
>   only check that database needs to be reloaded on every 60-th
>   loop run. This should be close enough to the current behaviour.
>   
>   Add "@every_minute" shortcut while I am here.

Do I read the code correctly and the cron deamon will wake up every
second now even if @every_second is not used at all?

>   
>   MFC after:	1 month
> 
> Modified:
>   head/usr.sbin/cron/cron/cron.c
>   head/usr.sbin/cron/cron/cron.h
>   head/usr.sbin/cron/crontab/crontab.5
>   head/usr.sbin/cron/lib/entry.c
> 
> Modified: head/usr.sbin/cron/cron/cron.c
> ==============================================================================
> --- head/usr.sbin/cron/cron/cron.c	Mon Oct 15 07:57:55 2012	(r241575)
> +++ head/usr.sbin/cron/cron/cron.c	Mon Oct 15 08:21:49 2012	(r241576)
> @@ -98,6 +98,7 @@ main(argc, argv)
>  	char	*argv[];
>  {
>  	cron_db	database;
> +	int runnum;
>  
>  	ProgramName = argv[0];
>  
> @@ -149,21 +150,24 @@ main(argc, argv)
>  	load_database(&database);
>  	run_reboot_jobs(&database);
>  	cron_sync();
> +	runnum = 0;
>  	while (TRUE) {
>  # if DEBUGGING
>  	    /* if (!(DebugFlags & DTEST)) */
>  # endif /*DEBUGGING*/
>  			cron_sleep(&database);
>  
> -		load_database(&database);
> +		if (runnum % 60 == 0)
> +			load_database(&database);
>  
>  		/* do this iteration
>  		 */
>  		cron_tick(&database);
>  
> -		/* sleep 1 minute
> +		/* sleep 1 second
>  		 */
> -		TargetTime += 60;
> +		TargetTime += 1;
> +		runnum += 1;
>  	}
>  }
>  
> @@ -194,22 +198,23 @@ cron_tick(db)
>  	static time_t	diff = 0, /* time difference in seconds from the last offset change */
>  		difflimit = 0; /* end point for the time zone correction */
>  	struct tm	otztm; /* time in the old time zone */
> -	int		otzminute, otzhour, otzdom, otzmonth, otzdow;
> +	int		otzsecond, otzminute, otzhour, otzdom, otzmonth, otzdow;
>   	register struct tm	*tm = localtime(&TargetTime);
> -	register int		minute, hour, dom, month, dow;
> +	register int		second, minute, hour, dom, month, dow;
>  	register user		*u;
>  	register entry		*e;
>  
>  	/* make 0-based values out of these so we can use them as indicies
>  	 */
> +	second = tm->tm_sec -FIRST_SECOND;
>  	minute = tm->tm_min -FIRST_MINUTE;
>  	hour = tm->tm_hour -FIRST_HOUR;
>  	dom = tm->tm_mday -FIRST_DOM;
>  	month = tm->tm_mon +1 /* 0..11 -> 1..12 */ -FIRST_MONTH;
>  	dow = tm->tm_wday -FIRST_DOW;
>  
> -	Debug(DSCH, ("[%d] tick(%d,%d,%d,%d,%d)\n",
> -		getpid(), minute, hour, dom, month, dow))
> +	Debug(DSCH, ("[%d] tick(%d,%d,%d,%d,%d,%d)\n",
> +		getpid(), second, minute, hour, dom, month, dow))
>  
>  	if (dst_enabled && last_time != 0 
>  	&& TargetTime > last_time /* exclude stepping back */
> @@ -262,6 +267,7 @@ cron_tick(db)
>  
>  			/* make 0-based values out of these so we can use them as indicies
>  			 */
> +			otzsecond = otztm.tm_sec -FIRST_SECOND;
>  			otzminute = otztm.tm_min -FIRST_MINUTE;
>  			otzhour = otztm.tm_hour -FIRST_HOUR;
>  			otzdom = otztm.tm_mday -FIRST_DOM;
> @@ -283,7 +289,8 @@ cron_tick(db)
>  					  e->uid, e->gid, e->cmd))
>  
>  			if ( diff != 0 && (e->flags & (RUN_AT|NOT_UNTIL)) ) {
> -				if (bit_test(e->minute, otzminute)
> +				if (bit_test(e->second, otzsecond)
> +				 && bit_test(e->minute, otzminute)
>  				 && bit_test(e->hour, otzhour)
>  				 && bit_test(e->month, otzmonth)
>  				 && ( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR))
> @@ -302,7 +309,8 @@ cron_tick(db)
>  					continue;
>  			}
>  
> -			if (bit_test(e->minute, minute)
> +			if (bit_test(e->second, second)
> +			 && bit_test(e->minute, minute)
>  			 && bit_test(e->hour, hour)
>  			 && bit_test(e->month, month)
>  			 && ( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR))
> 
> Modified: head/usr.sbin/cron/cron/cron.h
> ==============================================================================
> --- head/usr.sbin/cron/cron/cron.h	Mon Oct 15 07:57:55 2012	(r241575)
> +++ head/usr.sbin/cron/cron/cron.h	Mon Oct 15 08:21:49 2012	(r241576)
> @@ -124,6 +124,10 @@
>  			 LineNumber = ln; \
>  			}
>  
> +#define	FIRST_SECOND	0
> +#define	LAST_SECOND	59
> +#define	SECOND_COUNT	(LAST_SECOND - FIRST_SECOND + 1)
> +
>  #define	FIRST_MINUTE	0
>  #define	LAST_MINUTE	59
>  #define	MINUTE_COUNT	(LAST_MINUTE - FIRST_MINUTE + 1)
> @@ -165,6 +169,7 @@ typedef	struct _entry {
>  #endif
>  	char		**envp;
>  	char		*cmd;
> +	bitstr_t	bit_decl(second, SECOND_COUNT);
>  	bitstr_t	bit_decl(minute, MINUTE_COUNT);
>  	bitstr_t	bit_decl(hour,   HOUR_COUNT);
>  	bitstr_t	bit_decl(dom,    DOM_COUNT);
> 
> Modified: head/usr.sbin/cron/crontab/crontab.5
> ==============================================================================
> --- head/usr.sbin/cron/crontab/crontab.5	Mon Oct 15 07:57:55 2012	(r241575)
> +++ head/usr.sbin/cron/crontab/crontab.5	Mon Oct 15 08:21:49 2012	(r241576)
> @@ -232,6 +232,8 @@ string		meaning
>  @daily		Run once a day, "0 0 * * *".
>  @midnight	(same as @daily)
>  @hourly		Run once an hour, "0 * * * *".
> + at every_minute	Run once a minute, "*/1 * * * *".
> + at every_second	Run once a second.
>  .Ed
>  .Sh EXAMPLE CRON FILE
>  .Bd -literal
> 
> Modified: head/usr.sbin/cron/lib/entry.c
> ==============================================================================
> --- head/usr.sbin/cron/lib/entry.c	Mon Oct 15 07:57:55 2012	(r241575)
> +++ head/usr.sbin/cron/lib/entry.c	Mon Oct 15 08:21:49 2012	(r241576)
> @@ -151,6 +151,7 @@ load_entry(file, error_func, pw, envp)
>  			e->flags |= WHEN_REBOOT;
>  		} else if (!strcmp("yearly", cmd) || !strcmp("annually", cmd)){
>  			Debug(DPARS, ("load_entry()...yearly shortcut\n"))
> +			bit_set(e->second, 0);
>  			bit_set(e->minute, 0);
>  			bit_set(e->hour, 0);
>  			bit_set(e->dom, 0);
> @@ -159,6 +160,7 @@ load_entry(file, error_func, pw, envp)
>  			e->flags |= DOW_STAR;
>  		} else if (!strcmp("monthly", cmd)) {
>  			Debug(DPARS, ("load_entry()...monthly shortcut\n"))
> +			bit_set(e->second, 0);
>  			bit_set(e->minute, 0);
>  			bit_set(e->hour, 0);
>  			bit_set(e->dom, 0);
> @@ -167,6 +169,7 @@ load_entry(file, error_func, pw, envp)
>  			e->flags |= DOW_STAR;
>  		} else if (!strcmp("weekly", cmd)) {
>  			Debug(DPARS, ("load_entry()...weekly shortcut\n"))
> +			bit_set(e->second, 0);
>  			bit_set(e->minute, 0);
>  			bit_set(e->hour, 0);
>  			bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
> @@ -175,6 +178,7 @@ load_entry(file, error_func, pw, envp)
>  			bit_set(e->dow, 0);
>  		} else if (!strcmp("daily", cmd) || !strcmp("midnight", cmd)) {
>  			Debug(DPARS, ("load_entry()...daily shortcut\n"))
> +			bit_set(e->second, 0);
>  			bit_set(e->minute, 0);
>  			bit_set(e->hour, 0);
>  			bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
> @@ -182,11 +186,28 @@ load_entry(file, error_func, pw, envp)
>  			bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1));
>  		} else if (!strcmp("hourly", cmd)) {
>  			Debug(DPARS, ("load_entry()...hourly shortcut\n"))
> +			bit_set(e->second, 0);
>  			bit_set(e->minute, 0);
>  			bit_nset(e->hour, 0, (LAST_HOUR-FIRST_HOUR+1));
>  			bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
>  			bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1));
>  			bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1));
> +		} else if (!strcmp("every_minute", cmd)) {
> +			Debug(DPARS, ("load_entry()...every_minute shortcut\n"))
> +			bit_set(e->second, 0);
> +			bit_nset(e->minute, 0, (LAST_MINUTE-FIRST_MINUTE+1));
> +			bit_nset(e->hour, 0, (LAST_HOUR-FIRST_HOUR+1));
> +			bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
> +			bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1));
> +			bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1));
> +		} else if (!strcmp("every_second", cmd)) {
> +			Debug(DPARS, ("load_entry()...every_second shortcut\n"))
> +			bit_nset(e->second, 0, (LAST_SECOND-FIRST_SECOND+1));
> +			bit_nset(e->minute, 0, (LAST_MINUTE-FIRST_MINUTE+1));
> +			bit_nset(e->hour, 0, (LAST_HOUR-FIRST_HOUR+1));
> +			bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
> +			bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1));
> +			bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1));
>  		} else {
>  			ecode = e_timespec;
>  			goto eof;

-- 
Pawel Jakub Dawidek                       http://www.wheelsystems.com
FreeBSD committer                         http://www.FreeBSD.org
Am I Evil? Yes, I Am!                     http://tupytaj.pl
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 196 bytes
Desc: not available
URL: <http://lists.freebsd.org/pipermail/svn-src-head/attachments/20121015/e11b4b74/attachment.sig>


More information about the svn-src-head mailing list