Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 03 Sep 2019 14:07:26 -0000
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r346586 - in stable: 11/usr.sbin/cron/cron 11/usr.sbin/cron/crontab 12/usr.sbin/cron/cron 12/usr.sbin/cron/crontab
Message-ID:  <201904230229.x3N2T8bg025990@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kevans
Date: Tue Apr 23 02:29:08 2019
New Revision: 346586
URL: https://svnweb.freebsd.org/changeset/base/346586

Log:
  MFC r346427: cron(8): schedule interval jobs that loaded during execution
  
  Jobs using the @<second> syntax currently only get executed if they exist
  when cron is started. The simplest reproducer of this is:
  
  echo '@20 root echo "Hello!"' >> /etc/cron.d/myjob
  
  myjob will get loaded at the next second==0, but this echo job will not
  run until cron restarts. These jobs are normally handled in
  run_reboot_jobs(), which sets e->lastexit of INTERVAL jobs to the startup
  time so they run 'n' seconds later.
  
  Fix this by special-casing TargetTime > 0 in the database load. Preexisting
  jobs will be handled at startup during run_reboot_jobs as normal, but if
  we've reloaded a database during runtime we'll hit this case and set
  e->lastexit to the current time when we process it. They will then run every
  'n' seconds from that point, and a full restart of cron is no longer
  required to make these jobs work.

Modified:
  stable/12/usr.sbin/cron/cron/database.c
  stable/12/usr.sbin/cron/crontab/crontab.5
Directory Properties:
  stable/12/   (props changed)

Changes in other areas also in this revision:
Modified:
  stable/11/usr.sbin/cron/cron/database.c
  stable/11/usr.sbin/cron/crontab/crontab.5
Directory Properties:
  stable/11/   (props changed)

Modified: stable/12/usr.sbin/cron/cron/database.c
==============================================================================
--- stable/12/usr.sbin/cron/cron/database.c	Mon Apr 22 21:28:43 2019	(r346585)
+++ stable/12/usr.sbin/cron/cron/database.c	Tue Apr 23 02:29:08 2019	(r346586)
@@ -259,6 +259,8 @@ process_crontab(uname, fname, tabname, statbuf, new_db
 	struct passwd	*pw = NULL;
 	int		crontab_fd = OK - 1;
 	user		*u;
+	entry		*e;
+	time_t		now;
 
 	if (strcmp(fname, SYS_NAME) && !(pw = getpwnam(uname))) {
 		/* file doesn't have a user in passwd file.
@@ -307,6 +309,21 @@ process_crontab(uname, fname, tabname, statbuf, new_db
 	u = load_user(crontab_fd, pw, fname);
 	if (u != NULL) {
 		u->mtime = statbuf->st_mtime;
+		/*
+		 * TargetTime == 0 when we're initially populating the database,
+		 * and TargetTime > 0 any time after that (i.e. we're reloading
+		 * cron.d/ files because they've been created/modified).  In the
+		 * latter case, we should check for any interval jobs and run
+		 * them 'n' seconds from the time the job was loaded/reloaded.
+		 * Otherwise, they will not be run until cron is restarted.
+		 */
+		if (TargetTime != 0) {
+			now = time(NULL);
+			for (e = u->crontab; e != NULL; e = e->next) {
+				if ((e->flags & INTERVAL) != 0)
+					e->lastexit = now;
+			}
+		}
 		link_user(new_db, u);
 	}
 

Modified: stable/12/usr.sbin/cron/crontab/crontab.5
==============================================================================
--- stable/12/usr.sbin/cron/crontab/crontab.5	Mon Apr 22 21:28:43 2019	(r346585)
+++ stable/12/usr.sbin/cron/crontab/crontab.5	Tue Apr 23 02:29:08 2019	(r346586)
@@ -17,7 +17,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 15, 2019
+.Dd April 19, 2019
 .Dt CRONTAB 5
 .Os
 .Sh NAME
@@ -245,12 +245,14 @@ string		meaning
 The
 .Sq @
 symbol followed by a numeric value has a special notion of running
-a job that much seconds after completion of previous invocation of
+a job that many seconds after completion of the previous invocation of
 the job.
 Unlike regular syntax, it guarantees not to overlap two or more
-invocations of the same job.
-The first run is scheduled specified amount of seconds after cron
-has started.
+invocations of the same job during normal cron execution.
+Note, however, that overlap may occur if the job is running when the file
+containing the job is modified and subsequently reloaded.
+The first run is scheduled for the specified number of seconds after cron
+is started or the crontab entry is reloaded.
 .Sh EXAMPLE CRON FILE
 .Bd -literal
 





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