]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/scheduler.c
This commit was manufactured by cvs2svn to create tag
[bacula/bacula] / bacula / src / dird / scheduler.c
index 79d2b4fc6afd7831455df7ddd9be6619a64d12e1..ebb63ddec337a0b3db2fd9bc78adba6045687edb 100644 (file)
@@ -10,7 +10,7 @@
  *   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
@@ -35,6 +35,7 @@
 
 /* Forward referenced subroutines */
 static void find_runs();
+static void add_job(JOB *job, RUN *run, time_t now, time_t runtime);
 
 /* Imported subroutines */
 
@@ -66,6 +67,7 @@ JCR *wait_for_next_job(char *job_to_run)
    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) {
@@ -73,6 +75,7 @@ JCR *wait_for_next_job(char *job_to_run)
       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) {
@@ -83,15 +86,18 @@ JCR *wait_for_next_job(char *job_to_run)
         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,
@@ -101,12 +107,20 @@ JCR *wait_for_next_job(char *job_to_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"));
@@ -114,14 +128,13 @@ JCR *wait_for_next_job(char *job_to_run)
 
    /* 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;
@@ -131,10 +144,9 @@ JCR *wait_for_next_job(char *job_to_run)
 
    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 */
@@ -143,7 +155,10 @@ JCR *wait_for_next_job(char *job_to_run)
       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;
@@ -174,7 +189,7 @@ static void find_runs()
    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;
@@ -190,6 +205,8 @@ static void find_runs()
    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();
@@ -200,39 +217,31 @@ static void find_runs()
       }
       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 */
-
         }
       }  
    }
@@ -241,3 +250,26 @@ static void find_runs()
    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 */
+}