]> git.sur5r.net Git - bacula/bacula/commitdiff
ebl Add MaxRunSchedTime option that specifies the maximum allowed time
authorEric Bollengier <eric@eb.homelinux.org>
Thu, 1 May 2008 14:27:28 +0000 (14:27 +0000)
committerEric Bollengier <eric@eb.homelinux.org>
Thu, 1 May 2008 14:27:28 +0000 (14:27 +0000)
     that a job may run, counted from when the job was scheduled.
ebl  Fix MaxWaitTime option that specifies the maximum allowed time that
     a job may block waiting for a resource, counted from the when the job starts
ebl  Rename (add) Max(Incr|Diff|Full)WaitTime to Max(Incr|Diff|Full)RunTime

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@6863 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/getmsg.c
bacula/src/dird/job.c
bacula/src/jcr.h
bacula/src/lib/jcr.c
bacula/technotes-2.3

index f95f25f175c41f5386b02782e06e563fe0f95768..e0cbb58898b03704fcce1a77ba19c6f3c51c4312 100644 (file)
@@ -289,10 +289,15 @@ RES_ITEM job_items[] = {
    {"writebootstrap",store_dir, ITEM(res_job.WriteBootstrap), 0, 0, 0},
    {"writeverifylist",store_dir, ITEM(res_job.WriteVerifyList), 0, 0, 0},
    {"replace",  store_replace,  ITEM(res_job.replace), 0, ITEM_DEFAULT, REPLACE_ALWAYS},
+   {"maxrunschedtime", store_time, ITEM(res_job.MaxRunSchedTime), 0, 0, 0},
    {"maxruntime",   store_time, ITEM(res_job.MaxRunTime), 0, 0, 0},
-   {"fullmaxwaittime",  store_time, ITEM(res_job.FullMaxWaitTime), 0, 0, 0},
-   {"incrementalmaxwaittime",  store_time, ITEM(res_job.IncMaxWaitTime), 0, 0, 0},
-   {"differentialmaxwaittime",  store_time, ITEM(res_job.DiffMaxWaitTime), 0, 0, 0},
+   /* xxxMaxWaitTime are deprecated */
+   {"fullmaxwaittime",  store_time, ITEM(res_job.FullMaxRunTime), 0, 0, 0},
+   {"incrementalmaxwaittime",  store_time, ITEM(res_job.IncMaxRunTime), 0, 0, 0},
+   {"differentialmaxwaittime",  store_time, ITEM(res_job.DiffMaxRunTime), 0, 0, 0},
+   {"fullmaxruntime",  store_time, ITEM(res_job.FullMaxRunTime), 0, 0, 0},
+   {"incrementalmaxruntime",  store_time, ITEM(res_job.IncMaxRunTime), 0, 0, 0},
+   {"differentialmaxruntime",  store_time, ITEM(res_job.DiffMaxRunTime), 0, 0, 0},
    {"maxwaittime",  store_time, ITEM(res_job.MaxWaitTime), 0, 0, 0},
    {"maxstartdelay",store_time, ITEM(res_job.MaxStartDelay), 0, 0, 0},
    {"maxfullinterval",  store_time, ITEM(res_job.MaxFullInterval), 0, 0, 0},
@@ -666,6 +671,15 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, const char *fm
       if (res->res_job.PluginOptions) {
          sendit(sock, _("  --> PluginOptions=%s\n"), NPRT(res->res_job.PluginOptions));
       }
+      if (res->res_job.MaxRunTime) {
+         sendit(sock, _("  --> MaxRunTime=%u\n"), res->res_job.MaxRunTime);
+      }
+      if (res->res_job.MaxWaitTime) {
+         sendit(sock, _("  --> MaxWaitTime=%u\n"), res->res_job.MaxWaitTime);
+      }
+      if (res->res_job.MaxStartDelay) {
+         sendit(sock, _("  --> MaxStartDelay=%u\n"), res->res_job.MaxStartDelay);
+      }
       if (res->res_job.storage) {
          STORE *store;
          foreach_alist(store, res->res_job.storage) {
index f13205096d52af15e3ecef7810feba6132ddcc53..57bc4bc4324327d689042326769e3b6793e22321 100644 (file)
@@ -384,10 +384,11 @@ public:
    };
    utime_t MaxRunTime;                /* max run time in seconds */
    utime_t MaxWaitTime;               /* max blocking time in seconds */
-   utime_t FullMaxWaitTime;           /* Max Full job wait time */
-   utime_t DiffMaxWaitTime;           /* Max Differential job wait time */
-   utime_t IncMaxWaitTime;            /* Max Incremental job wait time */
+   utime_t FullMaxRunTime;            /* Max Full job run time */
+   utime_t DiffMaxRunTime;            /* Max Differential job run time */
+   utime_t IncMaxRunTime;             /* Max Incremental job run time */
    utime_t MaxStartDelay;             /* max start delay in seconds */
+   utime_t MaxRunSchedTime;           /* max run time in seconds from Scheduled time*/
    utime_t RescheduleInterval;        /* Reschedule interval */
    utime_t JobRetention;              /* job retention period in seconds */
    utime_t MaxFullInterval;           /* Maximum time interval between Fulls */
index dae8f098fd0fc680305c79e88fe16dda65c21e62..59a1ecd2dec68ac82c0d6ef9a773a6eaea9b0f24 100644 (file)
@@ -70,6 +70,33 @@ static char Device_update[]   = "DevUpd Job=%127s "
 
 static char OK_msg[] = "1000 OK\n";
 
+
+void set_jcr_sd_job_status(JCR *jcr, int SDJobStatus)
+{
+   bool set_waittime=false;
+   Dmsg2(800, "set_jcr_sd_job_status(%s, %c)\n", jcr->Job, SDJobStatus);
+   /* if wait state is new, we keep current time for watchdog MaxWaitTime */
+   switch (SDJobStatus) {
+      case JS_WaitMedia:
+      case JS_WaitMount:
+      case JS_WaitMaxJobs:
+        set_waittime = true;
+      default:
+        break;
+   }
+
+   if (job_waiting(jcr)) {
+      set_waittime = false;
+   }
+
+   if (set_waittime) {
+      /* set it before JobStatus */
+      Dmsg0(800, "Setting wait_time\n");
+      jcr->wait_time = time(NULL);
+   }
+   jcr->SDJobStatus = SDJobStatus;
+}
+
 /*
  * Get a message
  *  Call appropriate processing routine
@@ -230,7 +257,7 @@ int bget_dirmsg(BSOCK *bs)
          int JobStatus;
          char Job[MAX_NAME_LENGTH];
          if (sscanf(bs->msg, Job_status, &Job, &JobStatus) == 2) {
-            jcr->SDJobStatus = JobStatus; /* current status */
+            set_jcr_sd_job_status(jcr,JobStatus); /* current status */
          } else {
             Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
          }
index 4523a31c48db2406c205d3f65fd5f4c5e9adb61a..56b15930b98d65c43889f253b5b29a7a76362e7e 100644 (file)
@@ -41,8 +41,9 @@
 static void *job_thread(void *arg);
 static void job_monitor_watchdog(watchdog_t *self);
 static void job_monitor_destructor(watchdog_t *self);
-static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr);
-static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr);
+static bool job_check_maxwaittime(JCR *jcr);
+static bool job_check_maxruntime(JCR *jcr);
+static bool job_check_maxschedruntime(JCR *jcr);
 
 /* Imported subroutines */
 extern void term_scheduler();
@@ -253,6 +254,11 @@ static void *job_thread(void *arg)
       Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
    }
 
+   if (job_check_maxschedruntime(jcr)) {
+      set_jcr_job_status(jcr, JS_Canceled);
+      Jmsg(jcr, M_FATAL, 0, _("Job canceled because max sched run time exceeded.\n"));
+   }
+
    /* TODO : check if it is used somewhere */
    if (jcr->job->RunScripts == NULL) {
       Dmsg0(200, "Warning, job->RunScripts is empty\n");
@@ -493,15 +499,20 @@ static void job_monitor_watchdog(watchdog_t *self)
       }
 
       /* check MaxWaitTime */
-      if (job_check_maxwaittime(control_jcr, jcr)) {
+      if (job_check_maxwaittime(jcr)) {
          set_jcr_job_status(jcr, JS_Canceled);
          Jmsg(jcr, M_FATAL, 0, _("Max wait time exceeded. Job canceled.\n"));
          cancel = true;
       /* check MaxRunTime */
-      } else if (job_check_maxruntime(control_jcr, jcr)) {
+      } else if (job_check_maxruntime(jcr)) {
          set_jcr_job_status(jcr, JS_Canceled);
          Jmsg(jcr, M_FATAL, 0, _("Max run time exceeded. Job canceled.\n"));
          cancel = true;
+      /* check MaxRunSchedTime */ 
+      } else if (job_check_maxschedruntime(jcr)) {
+         set_jcr_job_status(jcr, JS_Canceled);
+         Jmsg(jcr, M_FATAL, 0, _("Max sched run time exceeded. Job canceled.\n"));
+         cancel = true;
       }
 
       if (cancel) {
@@ -522,47 +533,71 @@ static void job_monitor_watchdog(watchdog_t *self)
  * Check if the maxwaittime has expired and it is possible
  *  to cancel the job.
  */
-static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
+static bool job_check_maxwaittime(JCR *jcr)
 {
    bool cancel = false;
    JOB *job = jcr->job;
 
-   if (job_canceled(jcr)) {
-      return false;                /* already canceled */
+   if (!job_waiting(jcr)) {
+      return false;
    }
-   if (job->MaxWaitTime == 0 && job->FullMaxWaitTime == 0 &&
-       job->IncMaxWaitTime == 0 && job->DiffMaxWaitTime == 0) {
+   Dmsg3(200, "check maxwaittime %u - %u >= %u\n", watchdog_time, jcr->wait_time, job->MaxWaitTime);
+   if (job->MaxWaitTime != 0 &&
+       (watchdog_time - jcr->wait_time) >= job->MaxWaitTime) {
+      cancel = true;
+   }
+
+   return cancel;
+}
+
+/*
+ * Check if maxruntime has expired and if the job can be
+ *   canceled.
+ */
+static bool job_check_maxruntime(JCR *jcr)
+{
+   bool cancel = false;
+   JOB *job = jcr->job;
+
+   if (job_canceled(jcr) || jcr->JobStatus == JS_Created) {
       return false;
-   } 
-   if (jcr->JobLevel == L_FULL && job->FullMaxWaitTime != 0 &&
-         (watchdog_time - jcr->start_time) >= job->FullMaxWaitTime) {
+   }
+   if (jcr->job->MaxRunTime == 0 && job->FullMaxRunTime == 0 &&
+       job->IncMaxRunTime == 0 && job->DiffMaxRunTime == 0) {
+      return false;
+   }
+   Dmsg6(200, "check_maxruntime %u - %u >= %u|%u|%u|%u\n\n",
+        watchdog_time, jcr->start_time, job->MaxRunTime, job->FullMaxRunTime, 
+        job->IncMaxRunTime, job->DiffMaxRunTime);
+
+   if (jcr->JobLevel == L_FULL && job->FullMaxRunTime != 0 &&
+         (watchdog_time - jcr->start_time) >= job->FullMaxRunTime) {
       cancel = true;
-   } else if (jcr->JobLevel == L_DIFFERENTIAL && job->DiffMaxWaitTime != 0 &&
-         (watchdog_time - jcr->start_time) >= job->DiffMaxWaitTime) {
+   } else if (jcr->JobLevel == L_DIFFERENTIAL && job->DiffMaxRunTime != 0 &&
+         (watchdog_time - jcr->start_time) >= job->DiffMaxRunTime) {
       cancel = true;
-   } else if (jcr->JobLevel == L_INCREMENTAL && job->IncMaxWaitTime != 0 &&
-         (watchdog_time - jcr->start_time) >= job->IncMaxWaitTime) {
+   } else if (jcr->JobLevel == L_INCREMENTAL && job->IncMaxRunTime != 0 &&
+         (watchdog_time - jcr->start_time) >= job->IncMaxRunTime) {
       cancel = true;
-   } else if (job->MaxWaitTime != 0 &&
-         (watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
+   } else if ((watchdog_time - jcr->start_time) >= job->MaxRunTime) {
       cancel = true;
    }
-
    return cancel;
 }
 
 /*
- * Check if maxruntime has expired and if the job can be
+ * Check if MaxRunSchedTime has expired and if the job can be
  *   canceled.
  */
-static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr)
+static bool job_check_maxschedruntime(JCR *jcr)
 {
-   if (jcr->job->MaxRunTime == 0 || job_canceled(jcr) || jcr->JobStatus == JS_Created) {
+   if (jcr->job->MaxRunSchedTime == 0 || job_canceled(jcr)) {
       return false;
    }
-   if ((watchdog_time - jcr->start_time) < jcr->job->MaxRunTime) {
-      Dmsg3(200, "Job %p (%s) with MaxRunTime %d not expired\n",
-            jcr, jcr->Job, jcr->job->MaxRunTime);
+   if ((watchdog_time - jcr->sched_time) < jcr->job->MaxRunSchedTime) {
+      Dmsg3(200, "Job %p (%s) with MaxRunSchedTime %d not expired\n",
+            jcr, jcr->Job, jcr->job->MaxRunSchedTime);
       return false;
    }
 
index 4a3c0431335054c156a6f18a72e6622f9bb6ccd6..5adfc4af05f45255828df1ea7e7039bdbdda49bd 100644 (file)
@@ -109,6 +109,22 @@ enum {
    jcr->JobStatus == JS_ErrorTerminated || \
    jcr->JobStatus == JS_FatalError)
 
+#define job_waiting(jcr) \
+  (jcr->JobStatus == JS_WaitFD       || \
+   jcr->JobStatus == JS_WaitSD      || \
+   jcr->JobStatus == JS_WaitMedia    || \
+   jcr->JobStatus == JS_WaitMount    || \
+   jcr->JobStatus == JS_WaitStoreRes || \
+   jcr->JobStatus == JS_WaitJobRes   || \
+   jcr->JobStatus == JS_WaitClientRes|| \
+   jcr->JobStatus == JS_WaitMaxJobs  || \
+   jcr->JobStatus == JS_WaitPriority || \
+   jcr->SDJobStatus == JS_WaitMedia  || \
+   jcr->SDJobStatus == JS_WaitMount  || \
+   jcr->SDJobStatus == JS_WaitMaxJobs)
+
+
+
 #define foreach_jcr(jcr) \
    for (jcr=jcr_walk_start(); jcr; (jcr=jcr_walk_next(jcr)) )
 
@@ -189,6 +205,7 @@ public:
    time_t start_time;                 /* when job actually started */
    time_t run_time;                   /* used for computing speed */
    time_t end_time;                   /* job end time */
+   time_t wait_time;                  /* when job have started to wait */
    POOLMEM *client_name;              /* client name */
    POOLMEM *RestoreBootstrap;         /* Bootstrap file to restore */
    POOLMEM *stime;                    /* start time for incremental/differential */
index 80e404d7a03c10abc1aa8d7f72c5724faf6a981a..276a29ea68d229e30cc719f4a4f79b2ddf3f011c 100644 (file)
@@ -632,6 +632,24 @@ JCR *get_jcr_by_full_name(char *Job)
 
 void set_jcr_job_status(JCR *jcr, int JobStatus)
 {
+    bool set_waittime=false;
+    Dmsg2(800, "set_jcr_job_status(%s, %c)\n", jcr->Job, JobStatus);
+    /* if wait state is new, we keep current time for watchdog MaxWaitTime */
+    switch (JobStatus) {
+       case JS_WaitFD:
+       case JS_WaitSD:
+       case JS_WaitMedia:
+       case JS_WaitMount:
+       case JS_WaitStoreRes:
+       case JS_WaitJobRes:
+       case JS_WaitClientRes:
+       case JS_WaitMaxJobs:
+       case JS_WaitPriority:
+         set_waittime = true;
+       default:
+         break;
+    }
    /*
     * For a set of errors, ... keep the current status
     *   so it isn't lost. For all others, set it.
@@ -652,10 +670,29 @@ void set_jcr_job_status(JCR *jcr, int JobStatus)
          /* Override more minor status */
          jcr->JobStatus = JobStatus;
          break;
+      default:
+         break;
       }
-      break;
+   /*
+    * For a set of Wait situation, keep old time.
+    */
+   case JS_WaitFD:
+   case JS_WaitSD:
+   case JS_WaitMedia:
+   case JS_WaitMount:
+   case JS_WaitStoreRes:
+   case JS_WaitJobRes:
+   case JS_WaitClientRes:
+   case JS_WaitMaxJobs:
+   case JS_WaitPriority:
+       set_waittime = false;    /* keep old time */
    default:
       jcr->JobStatus = JobStatus;
+      if (set_waittime) {
+         /* set it before JobStatus */
+         Dmsg0(800, "Setting wait_time\n");
+         jcr->wait_time = time(NULL);
+      }
    }
    Dmsg3(100, "jid=%u OnExit JobStatus=%c set=%c\n", (uint32_t)jcr->JobId,
          jcr->JobStatus, JobStatus);
index 2d695e47801ef0e86fe2fca4c85bcecb5d1f587d..65458204e8761f06a3e73b7619fad9ba55363a0d 100644 (file)
@@ -25,6 +25,11 @@ Add long term statistics job table
 
 General:
 01May08
+ebl  Add MaxRunSchedTime option that specifies the maximum allowed time 
+     that a job may run, counted from when the job was scheduled.
+ebl  Fix MaxWaitTime option that specifies the maximum allowed time that 
+     a job may block waiting for a resource, counted from when the job starts
+ebl  Rename (add) Max(Incr|Diff|Full)WaitTime to Max(Incr|Diff|Full)RunTime
 kes  Apply patch from bug #1076 by Tullio Andreatta <t.andreatta@troppoavanti.it>
      that implements multiple commands per line in the console when using 
      readline. Modify the default to use a semicolon as the command separator.