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

2018-06-08 Thread Piotr P. Stefaniak

On 2018-06-07 22:38:40, Gleb Smirnoff wrote:

Author: glebius
Date: Thu Jun  7 22:38:40 2018
New Revision: 334817
URL: https://svnweb.freebsd.org/changeset/base/334817

Log:
 Add new functionality and syntax to cron(1) to allow to run jobs at a
 given interval, which is counted in seconds since exit of the previous
 invocation of the job. Example user crontab entry:

 @25sleep 10

 The example will launch 'sleep 10' every 35 seconds. This is a rather
 useless example above, but clearly explains the functionality.

 The practical goal here is to avoid overlap of previous job invocation
 to a new one, or to avoid too short interval(s) for jobs that last long
 and doesn't have any point of immediate launch soon after previous run.

 Another useful effect of interval jobs can be noticed when a cluster of
 machines periodically communicates with a single node. Running the task
 time based creates too much load on the node. Running interval based
 spreads invocations across machines in cluster. Note that -j/-J won't
 help in this case.

 Sponsored by:  Netflix


Missing a Relnotes tag, possibly.
___
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"


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

2018-06-07 Thread Gleb Smirnoff
Author: glebius
Date: Thu Jun  7 22:38:40 2018
New Revision: 334817
URL: https://svnweb.freebsd.org/changeset/base/334817

Log:
  Add new functionality and syntax to cron(1) to allow to run jobs at a
  given interval, which is counted in seconds since exit of the previous
  invocation of the job. Example user crontab entry:
  
  @25   sleep 10
  
  The example will launch 'sleep 10' every 35 seconds. This is a rather
  useless example above, but clearly explains the functionality.
  
  The practical goal here is to avoid overlap of previous job invocation
  to a new one, or to avoid too short interval(s) for jobs that last long
  and doesn't have any point of immediate launch soon after previous run.
  
  Another useful effect of interval jobs can be noticed when a cluster of
  machines periodically communicates with a single node. Running the task
  time based creates too much load on the node. Running interval based
  spreads invocations across machines in cluster. Note that -j/-J won't
  help in this case.
  
  Sponsored by: Netflix

Modified:
  head/usr.sbin/cron/cron/cron.c
  head/usr.sbin/cron/cron/cron.h
  head/usr.sbin/cron/cron/do_command.c
  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  Thu Jun  7 21:24:21 2018
(r334816)
+++ head/usr.sbin/cron/cron/cron.c  Thu Jun  7 22:38:40 2018
(r334817)
@@ -46,7 +46,9 @@ staticvoidusage(void),
parse_args(int c, char *v[]);
 
 static int run_at_secres(cron_db *);
+static voidfind_interval_entry(pid_t);
 
+static cron_db database;
 static time_t  last_time = 0;
 static int dst_enabled = 0;
 static int dont_daemonize = 0;
@@ -100,7 +102,6 @@ main(argc, argv)
int argc;
char*argv[];
 {
-   cron_db database;
int runnum;
int secres1, secres2;
struct tm *tm;
@@ -154,8 +155,8 @@ main(argc, argv)
database.mtime = (time_t) 0;
load_database();
secres1 = secres2 = run_at_secres();
-   run_reboot_jobs();
cron_sync(secres1);
+   run_reboot_jobs();
runnum = 0;
while (TRUE) {
 # if DEBUGGING
@@ -210,6 +211,9 @@ run_reboot_jobs(db)
if (e->flags & WHEN_REBOOT) {
job_add(e, u);
}
+   if (e->flags & INTERVAL) {
+   e->lastexit = TargetTime;
+   }
}
}
(void) job_runqueue();
@@ -313,6 +317,13 @@ cron_tick(cron_db *db, int secres)
  env_get("LOGNAME", e->envp),
  e->uid, e->gid, e->cmd))
 
+   if (e->flags & INTERVAL) {
+   if (e->lastexit > 0 &&
+   TargetTime >= e->lastexit + e->interval)
+   job_add(e, u);
+   continue;
+   }
+
if ( diff != 0 && (e->flags & (RUN_AT|NOT_UNTIL)) ) {
if (bit_test(e->second, otzsecond)
 && bit_test(e->minute, otzminute)
@@ -489,6 +500,7 @@ sigchld_handler(int x)
("[%d] sigchld...no dead kids\n", getpid()))
return;
default:
+   find_interval_entry(pid);
Debug(DPROC,
("[%d] sigchld...pid #%d died, stat=%d\n",
getpid(), pid, WEXITSTATUS(waiter)))
@@ -557,9 +569,26 @@ run_at_secres(cron_db *db)
 
for (u = db->head;  u != NULL;  u = u->next) {
for (e = u->crontab;  e != NULL;  e = e->next) {
-   if ((e->flags & SEC_RES) != 0)
+   if ((e->flags & (SEC_RES | INTERVAL)) != 0)
return 1;
}
}
return 0;
+}
+
+static void
+find_interval_entry(pid_t pid)
+{
+   user *u;
+   entry *e;
+
+   for (u = database.head;  u != NULL;  u = u->next) {
+   for (e = u->crontab;  e != NULL;  e = e->next) {
+   if ((e->flags & INTERVAL) && e->child == pid) {
+   e->lastexit = time(NULL);
+   e->child = 0;
+   break;
+   }
+   }
+   }
 }

Modified: head/usr.sbin/cron/cron/cron.h
==
--- head/usr.sbin/cron/cron/cron.h  Thu Jun  7 21:24:21 2018
(r334816)
+++ head/usr.sbin/cron/cron/cron.h  Thu Jun  7 22:38:40 2018
(r334817)
@@ -168,19 +168,29 @@ typedef   struct _entry