]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/patches/testing/maxschedruntime.patch
ebl update
[bacula/bacula] / bacula / patches / testing / maxschedruntime.patch
index 1c122a4aead725d1ac6c8d69485af80a551c0dfd..6d0193a5532f92b1844e6c9707f6ce37a2d75dfe 100644 (file)
@@ -1,7 +1,317 @@
+Index: patches/testing/maxschedruntime.patch
+===================================================================
+--- patches/testing/maxschedruntime.patch      (revision 6731)
++++ patches/testing/maxschedruntime.patch      (working copy)
+@@ -1,305 +0,0 @@
+-Index: src/dird/getmsg.c
+-===================================================================
+---- src/dird/getmsg.c (révision 4696)
+-+++ src/dird/getmsg.c (copie de travail)
+-@@ -70,6 +70,33 @@
+- 
+- 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 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: src/dird/job.c
+-===================================================================
+---- src/dird/job.c    (révision 4696)
+-+++ src/dird/job.c    (copie de travail)
+-@@ -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();
+-@@ -250,6 +251,11 @@
+-       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");
+-@@ -450,15 +456,20 @@
+-       }
+- 
+-       /* 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 MaxSchedRunTime */ 
+-+      } 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) {
+-@@ -479,29 +490,30 @@
+-  * 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) {
+-       return false;
+-    } 
+-+   Dmsg3(20, "check maxwaittime %u - %u >= %u\n", watchdog_time, jcr->wait_time, job->MaxWaitTime);
+-    if (jcr->JobLevel == L_FULL && job->FullMaxWaitTime != 0 &&
+--         (watchdog_time - jcr->start_time) >= job->FullMaxWaitTime) {
+-+         (watchdog_time - jcr->wait_time) >= job->FullMaxWaitTime) {
+-       cancel = true;
+-    } else if (jcr->JobLevel == L_DIFFERENTIAL && job->DiffMaxWaitTime != 0 &&
+--         (watchdog_time - jcr->start_time) >= job->DiffMaxWaitTime) {
+-+         (watchdog_time - jcr->wait_time) >= job->DiffMaxWaitTime) {
+-       cancel = true;
+-    } else if (jcr->JobLevel == L_INCREMENTAL && job->IncMaxWaitTime != 0 &&
+--         (watchdog_time - jcr->start_time) >= job->IncMaxWaitTime) {
+-+         (watchdog_time - jcr->wait_time) >= job->IncMaxWaitTime) {
+-       cancel = true;
+-    } else if (job->MaxWaitTime != 0 &&
+--         (watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
+-+         (watchdog_time - jcr->wait_time) >= job->MaxWaitTime) {
+-       cancel = true;
+-    }
+- 
+-@@ -512,7 +524,7 @@
+-  * Check if maxruntime has expired and if the job can be
+-  *   canceled.
+-  */
+--static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr)
+-+static bool job_check_maxruntime(JCR *jcr)
+- {
+-    if (jcr->job->MaxRunTime == 0 || job_canceled(jcr)) {
+-       return false;
+-@@ -527,6 +539,24 @@
+- }
+- 
+- /*
+-+ * Check if MaxSchedRunTime has expired and if the job can be
+-+ *   canceled.
+-+ */
+-+static bool job_check_maxschedruntime(JCR *jcr)
+-+{
+-+   if (jcr->job->MaxSchedRunTime == 0 || job_canceled(jcr)) {
+-+      return false;
+-+   }
+-+   if ((watchdog_time - jcr->sched_time) < jcr->job->MaxSchedRunTime) {
+-+      Dmsg3(200, "Job %p (%s) with MaxSchedRunTime %d not expired\n",
+-+            jcr, jcr->Job, jcr->job->MaxSchedRunTime);
+-+      return false;
+-+   }
+-+
+-+   return true;
+-+}
+-+
+-+/*
+-  * Get or create a Pool record with the given name.
+-  * Returns: 0 on error
+-  *          poolid if OK
+-Index: src/dird/dird_conf.c
+-===================================================================
+---- src/dird/dird_conf.c      (révision 4696)
+-+++ src/dird/dird_conf.c      (copie de travail)
+-@@ -281,6 +281,7 @@
+-    {"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},
+-+   {"maxschedruntime", store_time, ITEM(res_job.MaxSchedRunTime), 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},
+-@@ -627,6 +628,15 @@
+-       if (res->res_job.WriteBootstrap) {
+-          sendit(sock, _("  --> WriteBootstrap=%s\n"), NPRT(res->res_job.WriteBootstrap));
+-       }
+-+      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: src/dird/dird_conf.h
+-===================================================================
+---- src/dird/dird_conf.h      (révision 4696)
+-+++ src/dird/dird_conf.h      (copie de travail)
+-@@ -371,6 +371,7 @@
+-       char *WriteVerifyList;          /* List of changed files */
+-    };
+-    int   replace;                     /* How (overwrite, ..) */
+-+   utime_t MaxSchedRunTime;           /* max run time in seconds from Scheduled time*/
+-    utime_t MaxRunTime;                /* max run time in seconds */
+-    utime_t MaxWaitTime;               /* max blocking time in seconds */
+-    utime_t FullMaxWaitTime;           /* Max Full job wait time */
+-Index: src/jcr.h
+-===================================================================
+---- src/jcr.h (révision 4696)
+-+++ src/jcr.h (copie de travail)
+-@@ -105,6 +105,22 @@
+-    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)) )
+- 
+-@@ -166,6 +182,7 @@
+-    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: src/lib/jcr.c
+-===================================================================
+---- src/lib/jcr.c     (révision 4696)
+-+++ src/lib/jcr.c     (copie de travail)
+-@@ -546,18 +546,54 @@
+- 
+- 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;
+-+   }
+-+
+-+   switch (jcr->JobStatus) {
+-    /*
+-     * For a set of errors, ... keep the current status
+-     *   so it isn't lost. For all others, set it.
+-     */
+--   switch (jcr->JobStatus) {
+-    case JS_ErrorTerminated:
+-    case JS_Error:
+-    case JS_FatalError:
+-    case JS_Differences:
+-    case JS_Canceled:
+-       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:
+-+      if (set_waittime) {
+-+      /* set it before JobStatus */
+-+      Dmsg0(800, "Setting wait_time\n");
+-+      jcr->wait_time = time(NULL);
+-+      }
+-       jcr->JobStatus = JobStatus;
+-    }
+- }
 Index: src/dird/getmsg.c
 ===================================================================
---- src/dird/getmsg.c  (révision 4696)
-+++ src/dird/getmsg.c  (copie de travail)
+--- src/dird/getmsg.c  (revision 6731)
++++ src/dird/getmsg.c  (working copy)
 @@ -70,6 +70,33 @@
  
  static char OK_msg[] = "1000 OK\n";
@@ -47,8 +357,8 @@ Index: src/dird/getmsg.c
           }
 Index: src/dird/job.c
 ===================================================================
---- src/dird/job.c     (révision 4696)
-+++ src/dird/job.c     (copie de travail)
+--- src/dird/job.c     (revision 6731)
++++ src/dird/job.c     (working copy)
 @@ -41,8 +41,9 @@
  static void *job_thread(void *arg);
  static void job_monitor_watchdog(watchdog_t *self);
@@ -61,7 +371,7 @@ Index: src/dird/job.c
  
  /* Imported subroutines */
  extern void term_scheduler();
-@@ -250,6 +251,11 @@
+@@ -253,6 +254,11 @@
        Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
     }
  
@@ -73,7 +383,7 @@ Index: src/dird/job.c
     /* TODO : check if it is used somewhere */
     if (jcr->job->RunScripts == NULL) {
        Dmsg0(200, "Warning, job->RunScripts is empty\n");
-@@ -450,15 +456,20 @@
+@@ -493,15 +499,20 @@
        }
  
        /* check MaxWaitTime */
@@ -96,7 +406,7 @@ Index: src/dird/job.c
        }
  
        if (cancel) {
-@@ -479,29 +490,30 @@
+@@ -522,47 +533,71 @@
   * Check if the maxwaittime has expired and it is possible
   *  to cancel the job.
   */
@@ -111,78 +421,110 @@ Index: src/dird/job.c
 +   if (!job_waiting(jcr)) {
 +      return false;
     }
-    if (job->MaxWaitTime == 0 && job->FullMaxWaitTime == 0 &&
-        job->IncMaxWaitTime == 0 && job->DiffMaxWaitTime == 0) {
+-   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;
-    } 
-+   Dmsg3(20, "check maxwaittime %u - %u >= %u\n", watchdog_time, jcr->wait_time, job->MaxWaitTime);
-    if (jcr->JobLevel == L_FULL && job->FullMaxWaitTime != 0 &&
+-   } 
+-   if (jcr->JobLevel == L_FULL && job->FullMaxWaitTime != 0 &&
 -         (watchdog_time - jcr->start_time) >= job->FullMaxWaitTime) {
-+         (watchdog_time - jcr->wait_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 &&
+-   } else if (jcr->JobLevel == L_DIFFERENTIAL && job->DiffMaxWaitTime != 0 &&
 -         (watchdog_time - jcr->start_time) >= job->DiffMaxWaitTime) {
-+         (watchdog_time - jcr->wait_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 &&
+-   } else if (jcr->JobLevel == L_INCREMENTAL && job->IncMaxWaitTime != 0 &&
 -         (watchdog_time - jcr->start_time) >= job->IncMaxWaitTime) {
-+         (watchdog_time - jcr->wait_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 &&
+-   } else if (job->MaxWaitTime != 0 &&
 -         (watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
-+         (watchdog_time - jcr->wait_time) >= job->MaxWaitTime) {
++   } else if ((watchdog_time - jcr->start_time) >= job->MaxRunTime) {
        cancel = true;
     }
-@@ -512,7 +524,7 @@
-  * Check if maxruntime has expired and if the job can be
-  *   canceled.
-  */
--static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr)
-+static bool job_check_maxruntime(JCR *jcr)
- {
-    if (jcr->job->MaxRunTime == 0 || job_canceled(jcr)) {
-       return false;
-@@ -527,6 +539,24 @@
+-
++ 
+    return cancel;
  }
  
  /*
+- * Check if maxruntime has expired and if the job can be
 + * Check if MaxSchedRunTime has expired and if the job can be
-+ *   canceled.
-+ */
+  *   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->MaxSchedRunTime == 0 || job_canceled(jcr)) {
-+      return false;
-+   }
+       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->MaxSchedRunTime) {
 +      Dmsg3(200, "Job %p (%s) with MaxSchedRunTime %d not expired\n",
 +            jcr, jcr->Job, jcr->job->MaxSchedRunTime);
-+      return false;
-+   }
-+
-+   return true;
-+}
-+
-+/*
-  * Get or create a Pool record with the given name.
-  * Returns: 0 on error
-  *          poolid if OK
+       return false;
+    }
 Index: src/dird/dird_conf.c
 ===================================================================
---- src/dird/dird_conf.c       (révision 4696)
-+++ src/dird/dird_conf.c       (copie de travail)
-@@ -281,6 +281,7 @@
+--- src/dird/dird_conf.c       (revision 6731)
++++ src/dird/dird_conf.c       (working copy)
+@@ -289,10 +289,15 @@
     {"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},
 +   {"maxschedruntime", store_time, ITEM(res_job.MaxSchedRunTime), 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},
-@@ -627,6 +628,15 @@
-       if (res->res_job.WriteBootstrap) {
-          sendit(sock, _("  --> WriteBootstrap=%s\n"), NPRT(res->res_job.WriteBootstrap));
+-   {"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 @@
+       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);
@@ -198,21 +540,28 @@ Index: src/dird/dird_conf.c
           foreach_alist(store, res->res_job.storage) {
 Index: src/dird/dird_conf.h
 ===================================================================
---- src/dird/dird_conf.h       (révision 4696)
-+++ src/dird/dird_conf.h       (copie de travail)
-@@ -371,6 +371,7 @@
-       char *WriteVerifyList;          /* List of changed files */
+--- src/dird/dird_conf.h       (revision 6731)
++++ src/dird/dird_conf.h       (working copy)
+@@ -384,10 +384,11 @@
     };
-    int   replace;                     /* How (overwrite, ..) */
-+   utime_t MaxSchedRunTime;           /* max run time in seconds from Scheduled time*/
     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 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 MaxSchedRunTime;           /* 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: src/jcr.h
 ===================================================================
---- src/jcr.h  (révision 4696)
-+++ src/jcr.h  (copie de travail)
-@@ -105,6 +105,22 @@
+--- src/jcr.h  (revision 6731)
++++ src/jcr.h  (working copy)
+@@ -109,6 +109,22 @@
     jcr->JobStatus == JS_ErrorTerminated || \
     jcr->JobStatus == JS_FatalError)
  
@@ -235,7 +584,7 @@ Index: src/jcr.h
  #define foreach_jcr(jcr) \
     for (jcr=jcr_walk_start(); jcr; (jcr=jcr_walk_next(jcr)) )
  
-@@ -166,6 +182,7 @@
+@@ -188,6 +204,7 @@
     time_t start_time;                 /* when job actually started */
     time_t run_time;                   /* used for computing speed */
     time_t end_time;                   /* job end time */
@@ -245,42 +594,41 @@ Index: src/jcr.h
     POOLMEM *stime;                    /* start time for incremental/differential */
 Index: src/lib/jcr.c
 ===================================================================
---- src/lib/jcr.c      (révision 4696)
-+++ src/lib/jcr.c      (copie de travail)
-@@ -546,18 +546,54 @@
+--- src/lib/jcr.c      (revision 6731)
++++ src/lib/jcr.c      (working copy)
+@@ -632,6 +632,24 @@
  
  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;
-+   }
-+
-+   switch (jcr->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.
-     */
--   switch (jcr->JobStatus) {
-    case JS_ErrorTerminated:
-    case JS_Error:
-    case JS_FatalError:
-    case JS_Differences:
-    case JS_Canceled:
-       break;
+@@ -652,10 +670,29 @@
+          /* Override more minor status */
+          jcr->JobStatus = JobStatus;
+          break;
++      default:
++         break;
+       }
+-      break;
 +   /*
 +    * For a set of Wait situation, keep old time.
 +    */
@@ -292,14 +640,15 @@ Index: src/lib/jcr.c
 +   case JS_WaitJobRes:
 +   case JS_WaitClientRes:
 +   case JS_WaitMaxJobs:
-+   case JS_WaitPriority:  
-+      set_waittime = false;   /* keep old time */
++   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);
++         /* set it before JobStatus */
++         Dmsg0(800, "Setting wait_time\n");
++         jcr->wait_time = time(NULL);
 +      }
-       jcr->JobStatus = JobStatus;
     }
- }
+    Dmsg3(100, "jid=%u OnExit JobStatus=%c set=%c\n", (uint32_t)jcr->JobId,
+          jcr->JobStatus, JobStatus);