* Version $Id$
*/
/*
- Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker
+ Copyright (C) 2000-2003 Kern Sibbald and John Walker
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
/* Forward referenced subroutines */
static void find_runs();
+static void add_job(JOB *job, RUN *run, time_t now, time_t runtime);
/* Imported subroutines */
time_t now, runtime, nexttime;
int jobindex, i;
static int first = TRUE;
+ char dt[MAX_TIME_LENGTH];
Dmsg0(200, "Enter wait_for_next_job\n");
if (first) {
max_runjobs = 10;
runjobs = (RUNJOB *) malloc(sizeof(RUNJOB) * max_runjobs);
num_runjobs = 0;
+ rem_runjobs = 0;
if (job_to_run) { /* one shot */
job = (JOB *)GetResWithName(R_JOB, job_to_run);
if (!job) {
set_jcr_defaults(jcr, job);
return jcr;
}
- find_runs();
}
/* Wait until we have something in the
* next hour or so.
*/
- while (num_runjobs == 0 || rem_runjobs == 0) {
- sleep(60);
+ while (rem_runjobs == 0) {
find_runs();
+ if (rem_runjobs > 0) {
+ break;
+ }
+ bmicrosleep(60, 0); /* recheck once per minute */
}
+
/*
* Sort through what is to be run in the next
* two hours to find the first job to be run,
time(&now);
nexttime = now + 60 * 60 * 24; /* a much later time */
jobindex = -1;
+ bstrftime(dt, sizeof(dt), now);
+ Dmsg2(400, "jobs=%d. Now is %s\n", rem_runjobs, dt);
for (i=0; i<num_runjobs; i++) {
runtime = runjobs[i].runtime;
if (runtime > 0 && runtime < nexttime) { /* find minimum time job */
nexttime = runtime;
jobindex = i;
}
+#ifdef xxxx_debug
+ if (runtime > 0) {
+ bstrftime(dt, sizeof(dt), runjobs[i].runtime);
+ Dmsg2(100, " %s run %s\n", dt, runjobs[i].job->hdr.name);
+ }
+#endif
}
if (jobindex < 0) { /* we really should have something now */
Emsg0(M_ABORT, 0, _("Scheduler logic error\n"));
/* Now wait for the time to run the job */
for (;;) {
- int twait;
- time(&now);
+ time_t twait;
+ now = time(NULL);
twait = nexttime - now;
- if (twait <= 0) /* time to run it */
+ if (twait <= 0) { /* time to run it */
break;
- if (twait > 20) /* sleep max 20 seconds */
- twait = 20;
- sleep(twait);
+ }
+ bmicrosleep(twait, 0);
}
run = runjobs[jobindex].run;
job = runjobs[jobindex].job;
jcr = new_jcr(sizeof(JCR), dird_free_jcr);
ASSERT(job);
- sm_check(__FILE__, __LINE__, False);
set_jcr_defaults(jcr, job);
if (run->level) {
- jcr->level = run->level; /* override run level */
+ jcr->JobLevel = run->level; /* override run level */
}
if (run->pool) {
jcr->pool = run->pool; /* override pool */
jcr->store = run->storage; /* override storage */
}
if (run->msgs) {
- jcr->msgs = run->msgs; /* override messages */
+ jcr->messages = run->msgs; /* override messages */
+ }
+ if (run->Priority) {
+ jcr->JobPriority = run->Priority;
}
Dmsg0(200, "Leave wait_for_next_job()\n");
return jcr;
JOB *job;
SCHED *sched;
struct tm tm;
- int hour, next_hour, minute, mday, wday, month;
+ int hour, next_hour, minute, mday, wday, month, wom, woy;
Dmsg0(200, "enter find_runs()\n");
num_runjobs = 0;
mday = tm.tm_mday - 1;
wday = tm.tm_wday;
month = tm.tm_mon;
+ wom = mday / 7;
+ woy = tm_woy(now); /* get week of year */
/* Loop through all jobs */
LockRes();
}
for (run=sched->run; run; run=run->next) {
- if (now - run->last_run < 60 * 20)
- continue; /* wait at least 20 minutes */
-
/* Find runs scheduled in this our or in the
* next hour (we may be one second before the next hour).
*/
if ((bit_is_set(hour, run->hour) || bit_is_set(next_hour, run->hour)) &&
(bit_is_set(mday, run->mday) || bit_is_set(wday, run->wday)) &&
- bit_is_set(month, run->month)) {
+ bit_is_set(month, run->month) &&
+ bit_is_set(wom, run->wom) &&
+ bit_is_set(woy, run->woy)) {
/* find time (time_t) job is to be run */
localtime_r(&now, &tm);
- if (bit_is_set(next_hour, run->hour))
- tm.tm_hour++;
- if (tm.tm_hour > 23)
- tm.tm_hour = 0;
tm.tm_min = run->minute;
tm.tm_sec = 0;
- runtime = mktime(&tm);
- if (runtime < (now - 5 * 60)) /* give 5 min grace to pickup straglers */
- continue;
- /* Make sure array is big enough */
- if (num_runjobs == max_runjobs) {
- max_runjobs += 10;
- runjobs = (RUNJOB *) realloc(runjobs, sizeof(RUNJOB) * max_runjobs);
- if (!runjobs)
- Emsg0(M_ABORT, 0, _("Out of memory\n"));
+ if (bit_is_set(hour, run->hour)) {
+ runtime = mktime(&tm);
+ add_job(job, run, now, runtime);
+ }
+ if (bit_is_set(next_hour, run->hour)) {
+ tm.tm_hour++;
+ if (tm.tm_hour > 23) {
+ continue; /* next day */
+ }
+ runtime = mktime(&tm);
+ add_job(job, run, now, runtime);
}
- /* accept to run this job */
- runjobs[num_runjobs].run = run;
- runjobs[num_runjobs].job = job;
- runjobs[num_runjobs++].runtime = runtime; /* when to run it */
-
}
}
}
rem_runjobs = num_runjobs;
Dmsg0(200, "Leave find_runs()\n");
}
+
+static void add_job(JOB *job, RUN *run, time_t now, time_t runtime)
+{
+ /*
+ * Don't run any job that ran less than a minute ago, but
+ * do run any job scheduled less than a minute ago.
+ */
+ if ((runtime - run->last_run < 61) || (runtime+59 < now)) {
+ return;
+ }
+
+ /* Make sure array is big enough */
+ if (num_runjobs == max_runjobs) {
+ max_runjobs += 10;
+ runjobs = (RUNJOB *)realloc(runjobs, sizeof(RUNJOB) * max_runjobs);
+ if (!runjobs)
+ Emsg0(M_ABORT, 0, _("Out of memory\n"));
+ }
+ /* accept to run this job */
+ runjobs[num_runjobs].run = run;
+ runjobs[num_runjobs].job = job;
+ runjobs[num_runjobs++].runtime = runtime; /* when to run it */
+}