]> git.sur5r.net Git - bacula/bacula/blob - bacula/patches/testing/maxschedruntime.patch
ebl Update about STAP
[bacula/bacula] / bacula / patches / testing / maxschedruntime.patch
1 Index: patches/testing/maxschedruntime.patch
2 ===================================================================
3 --- patches/testing/maxschedruntime.patch       (revision 6731)
4 +++ patches/testing/maxschedruntime.patch       (working copy)
5 @@ -1,305 +0,0 @@
6 -Index: src/dird/getmsg.c
7 -===================================================================
8 ---- src/dird/getmsg.c  (révision 4696)
9 -+++ src/dird/getmsg.c  (copie de travail)
10 -@@ -70,6 +70,33 @@
11
12 - static char OK_msg[] = "1000 OK\n";
13
14 -+
15 -+void set_jcr_sd_job_status(JCR *jcr, int SDJobStatus)
16 -+{
17 -+   bool set_waittime=false;
18 -+   Dmsg2(800, "set_jcr_sd_job_status(%s, %c)\n", jcr->Job, SDJobStatus);
19 -+   /* if wait state is new, we keep current time for watchdog MaxWaitTime */
20 -+   switch (SDJobStatus) {
21 -+      case JS_WaitMedia:
22 -+      case JS_WaitMount:
23 -+      case JS_WaitMaxJobs:
24 -+       set_waittime = true;
25 -+      default:
26 -+       break;
27 -+   }
28 -+
29 -+   if (job_waiting(jcr)) {
30 -+      set_waittime = false;
31 -+   }
32 -+
33 -+   if (set_waittime) {
34 -+      /* set it before JobStatus */
35 -+      Dmsg0(800, "Setting wait_time\n");
36 -+      jcr->wait_time = time(NULL);
37 -+   }
38 -+   jcr->SDJobStatus = SDJobStatus;
39 -+}
40 -+
41 - /*
42 -  * Get a message
43 -  *  Call appropriate processing routine
44 -@@ -230,7 +257,7 @@
45 -          int JobStatus;
46 -          char Job[MAX_NAME_LENGTH];
47 -          if (sscanf(bs->msg, Job_status, &Job, &JobStatus) == 2) {
48 --            jcr->SDJobStatus = JobStatus; /* current status */
49 -+            set_jcr_sd_job_status(jcr,JobStatus); /* current status */
50 -          } else {
51 -             Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
52 -          }
53 -Index: src/dird/job.c
54 -===================================================================
55 ---- src/dird/job.c     (révision 4696)
56 -+++ src/dird/job.c     (copie de travail)
57 -@@ -41,8 +41,9 @@
58 - static void *job_thread(void *arg);
59 - static void job_monitor_watchdog(watchdog_t *self);
60 - static void job_monitor_destructor(watchdog_t *self);
61 --static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr);
62 --static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr);
63 -+static bool job_check_maxwaittime(JCR *jcr);
64 -+static bool job_check_maxruntime(JCR *jcr);
65 -+static bool job_check_maxschedruntime(JCR *jcr);
66
67 - /* Imported subroutines */
68 - extern void term_scheduler();
69 -@@ -250,6 +251,11 @@
70 -       Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
71 -    }
72
73 -+   if (job_check_maxschedruntime(jcr)) {
74 -+      set_jcr_job_status(jcr, JS_Canceled);
75 -+      Jmsg(jcr, M_FATAL, 0, _("Job canceled because max sched run time exceeded.\n"));
76 -+   }
77 -+
78 -    /* TODO : check if it is used somewhere */
79 -    if (jcr->job->RunScripts == NULL) {
80 -       Dmsg0(200, "Warning, job->RunScripts is empty\n");
81 -@@ -450,15 +456,20 @@
82 -       }
83
84 -       /* check MaxWaitTime */
85 --      if (job_check_maxwaittime(control_jcr, jcr)) {
86 -+      if (job_check_maxwaittime(jcr)) {
87 -          set_jcr_job_status(jcr, JS_Canceled);
88 -          Jmsg(jcr, M_FATAL, 0, _("Max wait time exceeded. Job canceled.\n"));
89 -          cancel = true;
90 -       /* check MaxRunTime */
91 --      } else if (job_check_maxruntime(control_jcr, jcr)) {
92 -+      } else if (job_check_maxruntime(jcr)) {
93 -          set_jcr_job_status(jcr, JS_Canceled);
94 -          Jmsg(jcr, M_FATAL, 0, _("Max run time exceeded. Job canceled.\n"));
95 -          cancel = true;
96 -+      /* check MaxSchedRunTime */ 
97 -+      } else if (job_check_maxschedruntime(jcr)) {
98 -+         set_jcr_job_status(jcr, JS_Canceled);
99 -+         Jmsg(jcr, M_FATAL, 0, _("Max sched run time exceeded. Job canceled.\n"));
100 -+         cancel = true;
101 -       }
102
103 -       if (cancel) {
104 -@@ -479,29 +490,30 @@
105 -  * Check if the maxwaittime has expired and it is possible
106 -  *  to cancel the job.
107 -  */
108 --static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
109 -+static bool job_check_maxwaittime(JCR *jcr)
110 - {
111 -    bool cancel = false;
112 -    JOB *job = jcr->job;
113
114 --   if (job_canceled(jcr)) {
115 --      return false;                /* already canceled */
116 -+   if (!job_waiting(jcr)) {
117 -+      return false;
118 -    }
119 -    if (job->MaxWaitTime == 0 && job->FullMaxWaitTime == 0 &&
120 -        job->IncMaxWaitTime == 0 && job->DiffMaxWaitTime == 0) {
121 -       return false;
122 -    } 
123 -+   Dmsg3(20, "check maxwaittime %u - %u >= %u\n", watchdog_time, jcr->wait_time, job->MaxWaitTime);
124 -    if (jcr->JobLevel == L_FULL && job->FullMaxWaitTime != 0 &&
125 --         (watchdog_time - jcr->start_time) >= job->FullMaxWaitTime) {
126 -+         (watchdog_time - jcr->wait_time) >= job->FullMaxWaitTime) {
127 -       cancel = true;
128 -    } else if (jcr->JobLevel == L_DIFFERENTIAL && job->DiffMaxWaitTime != 0 &&
129 --         (watchdog_time - jcr->start_time) >= job->DiffMaxWaitTime) {
130 -+         (watchdog_time - jcr->wait_time) >= job->DiffMaxWaitTime) {
131 -       cancel = true;
132 -    } else if (jcr->JobLevel == L_INCREMENTAL && job->IncMaxWaitTime != 0 &&
133 --         (watchdog_time - jcr->start_time) >= job->IncMaxWaitTime) {
134 -+         (watchdog_time - jcr->wait_time) >= job->IncMaxWaitTime) {
135 -       cancel = true;
136 -    } else if (job->MaxWaitTime != 0 &&
137 --         (watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
138 -+         (watchdog_time - jcr->wait_time) >= job->MaxWaitTime) {
139 -       cancel = true;
140 -    }
141
142 -@@ -512,7 +524,7 @@
143 -  * Check if maxruntime has expired and if the job can be
144 -  *   canceled.
145 -  */
146 --static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr)
147 -+static bool job_check_maxruntime(JCR *jcr)
148 - {
149 -    if (jcr->job->MaxRunTime == 0 || job_canceled(jcr)) {
150 -       return false;
151 -@@ -527,6 +539,24 @@
152 - }
153
154 - /*
155 -+ * Check if MaxSchedRunTime has expired and if the job can be
156 -+ *   canceled.
157 -+ */
158 -+static bool job_check_maxschedruntime(JCR *jcr)
159 -+{
160 -+   if (jcr->job->MaxSchedRunTime == 0 || job_canceled(jcr)) {
161 -+      return false;
162 -+   }
163 -+   if ((watchdog_time - jcr->sched_time) < jcr->job->MaxSchedRunTime) {
164 -+      Dmsg3(200, "Job %p (%s) with MaxSchedRunTime %d not expired\n",
165 -+            jcr, jcr->Job, jcr->job->MaxSchedRunTime);
166 -+      return false;
167 -+   }
168 -+
169 -+   return true;
170 -+}
171 -+
172 -+/*
173 -  * Get or create a Pool record with the given name.
174 -  * Returns: 0 on error
175 -  *          poolid if OK
176 -Index: src/dird/dird_conf.c
177 -===================================================================
178 ---- src/dird/dird_conf.c       (révision 4696)
179 -+++ src/dird/dird_conf.c       (copie de travail)
180 -@@ -281,6 +281,7 @@
181 -    {"writebootstrap",store_dir, ITEM(res_job.WriteBootstrap), 0, 0, 0},
182 -    {"writeverifylist",store_dir, ITEM(res_job.WriteVerifyList), 0, 0, 0},
183 -    {"replace",  store_replace,  ITEM(res_job.replace), 0, ITEM_DEFAULT, REPLACE_ALWAYS},
184 -+   {"maxschedruntime", store_time, ITEM(res_job.MaxSchedRunTime), 0, 0, 0},
185 -    {"maxruntime",   store_time, ITEM(res_job.MaxRunTime), 0, 0, 0},
186 -    {"fullmaxwaittime",  store_time, ITEM(res_job.FullMaxWaitTime), 0, 0, 0},
187 -    {"incrementalmaxwaittime",  store_time, ITEM(res_job.IncMaxWaitTime), 0, 0, 0},
188 -@@ -627,6 +628,15 @@
189 -       if (res->res_job.WriteBootstrap) {
190 -          sendit(sock, _("  --> WriteBootstrap=%s\n"), NPRT(res->res_job.WriteBootstrap));
191 -       }
192 -+      if (res->res_job.MaxRunTime) {
193 -+         sendit(sock, _("  --> MaxRunTime=%u\n"), res->res_job.MaxRunTime);
194 -+      }
195 -+      if (res->res_job.MaxWaitTime) {
196 -+         sendit(sock, _("  --> MaxWaitTime=%u\n"), res->res_job.MaxWaitTime);
197 -+      }
198 -+      if (res->res_job.MaxStartDelay) {
199 -+         sendit(sock, _("  --> MaxStartDelay=%u\n"), res->res_job.MaxStartDelay);
200 -+      }
201 -       if (res->res_job.storage) {
202 -          STORE *store;
203 -          foreach_alist(store, res->res_job.storage) {
204 -Index: src/dird/dird_conf.h
205 -===================================================================
206 ---- src/dird/dird_conf.h       (révision 4696)
207 -+++ src/dird/dird_conf.h       (copie de travail)
208 -@@ -371,6 +371,7 @@
209 -       char *WriteVerifyList;          /* List of changed files */
210 -    };
211 -    int   replace;                     /* How (overwrite, ..) */
212 -+   utime_t MaxSchedRunTime;           /* max run time in seconds from Scheduled time*/
213 -    utime_t MaxRunTime;                /* max run time in seconds */
214 -    utime_t MaxWaitTime;               /* max blocking time in seconds */
215 -    utime_t FullMaxWaitTime;           /* Max Full job wait time */
216 -Index: src/jcr.h
217 -===================================================================
218 ---- src/jcr.h  (révision 4696)
219 -+++ src/jcr.h  (copie de travail)
220 -@@ -105,6 +105,22 @@
221 -    jcr->JobStatus == JS_ErrorTerminated || \
222 -    jcr->JobStatus == JS_FatalError)
223
224 -+#define job_waiting(jcr) \
225 -+  (jcr->JobStatus == JS_WaitFD       || \
226 -+   jcr->JobStatus == JS_WaitSD             || \
227 -+   jcr->JobStatus == JS_WaitMedia    || \
228 -+   jcr->JobStatus == JS_WaitMount    || \
229 -+   jcr->JobStatus == JS_WaitStoreRes || \
230 -+   jcr->JobStatus == JS_WaitJobRes   || \
231 -+   jcr->JobStatus == JS_WaitClientRes|| \
232 -+   jcr->JobStatus == JS_WaitMaxJobs  || \
233 -+   jcr->JobStatus == JS_WaitPriority || \
234 -+   jcr->SDJobStatus == JS_WaitMedia  || \
235 -+   jcr->SDJobStatus == JS_WaitMount  || \
236 -+   jcr->SDJobStatus == JS_WaitMaxJobs)
237 -+
238 -+
239 -+
240 - #define foreach_jcr(jcr) \
241 -    for (jcr=jcr_walk_start(); jcr; (jcr=jcr_walk_next(jcr)) )
242
243 -@@ -166,6 +182,7 @@
244 -    time_t start_time;                 /* when job actually started */
245 -    time_t run_time;                   /* used for computing speed */
246 -    time_t end_time;                   /* job end time */
247 -+   time_t wait_time;                  /* when job have started to wait */
248 -    POOLMEM *client_name;              /* client name */
249 -    POOLMEM *RestoreBootstrap;         /* Bootstrap file to restore */
250 -    POOLMEM *stime;                    /* start time for incremental/differential */
251 -Index: src/lib/jcr.c
252 -===================================================================
253 ---- src/lib/jcr.c      (révision 4696)
254 -+++ src/lib/jcr.c      (copie de travail)
255 -@@ -546,18 +546,54 @@
256
257 - void set_jcr_job_status(JCR *jcr, int JobStatus)
258 - {
259 -+   bool set_waittime=false;
260 -+   Dmsg2(800, "set_jcr_job_status(%s, %c)\n", jcr->Job, JobStatus);
261 -+   /* if wait state is new, we keep current time for watchdog MaxWaitTime */
262 -+   switch (JobStatus) {
263 -+      case JS_WaitFD:
264 -+      case JS_WaitSD:
265 -+      case JS_WaitMedia:
266 -+      case JS_WaitMount:
267 -+      case JS_WaitStoreRes:
268 -+      case JS_WaitJobRes:
269 -+      case JS_WaitClientRes:
270 -+      case JS_WaitMaxJobs:
271 -+      case JS_WaitPriority:
272 -+       set_waittime = true;
273 -+      default:
274 -+       break;
275 -+   }
276 -+
277 -+   switch (jcr->JobStatus) {
278 -    /*
279 -     * For a set of errors, ... keep the current status
280 -     *   so it isn't lost. For all others, set it.
281 -     */
282 --   switch (jcr->JobStatus) {
283 -    case JS_ErrorTerminated:
284 -    case JS_Error:
285 -    case JS_FatalError:
286 -    case JS_Differences:
287 -    case JS_Canceled:
288 -       break;
289 -+   /*
290 -+    * For a set of Wait situation, keep old time.
291 -+    */
292 -+   case JS_WaitFD:
293 -+   case JS_WaitSD:
294 -+   case JS_WaitMedia:
295 -+   case JS_WaitMount:
296 -+   case JS_WaitStoreRes:
297 -+   case JS_WaitJobRes:
298 -+   case JS_WaitClientRes:
299 -+   case JS_WaitMaxJobs:
300 -+   case JS_WaitPriority:  
301 -+      set_waittime = false;   /* keep old time */
302 -    default:
303 -+      if (set_waittime) {
304 -+       /* set it before JobStatus */
305 -+       Dmsg0(800, "Setting wait_time\n");
306 -+       jcr->wait_time = time(NULL);
307 -+      }
308 -       jcr->JobStatus = JobStatus;
309 -    }
310 - }
311 Index: src/dird/getmsg.c
312 ===================================================================
313 --- src/dird/getmsg.c   (revision 6731)
314 +++ src/dird/getmsg.c   (working copy)
315 @@ -70,6 +70,33 @@
316  
317  static char OK_msg[] = "1000 OK\n";
318  
319 +
320 +void set_jcr_sd_job_status(JCR *jcr, int SDJobStatus)
321 +{
322 +   bool set_waittime=false;
323 +   Dmsg2(800, "set_jcr_sd_job_status(%s, %c)\n", jcr->Job, SDJobStatus);
324 +   /* if wait state is new, we keep current time for watchdog MaxWaitTime */
325 +   switch (SDJobStatus) {
326 +      case JS_WaitMedia:
327 +      case JS_WaitMount:
328 +      case JS_WaitMaxJobs:
329 +        set_waittime = true;
330 +      default:
331 +        break;
332 +   }
333 +
334 +   if (job_waiting(jcr)) {
335 +      set_waittime = false;
336 +   }
337 +
338 +   if (set_waittime) {
339 +      /* set it before JobStatus */
340 +      Dmsg0(800, "Setting wait_time\n");
341 +      jcr->wait_time = time(NULL);
342 +   }
343 +   jcr->SDJobStatus = SDJobStatus;
344 +}
345 +
346  /*
347   * Get a message
348   *  Call appropriate processing routine
349 @@ -230,7 +257,7 @@
350           int JobStatus;
351           char Job[MAX_NAME_LENGTH];
352           if (sscanf(bs->msg, Job_status, &Job, &JobStatus) == 2) {
353 -            jcr->SDJobStatus = JobStatus; /* current status */
354 +            set_jcr_sd_job_status(jcr,JobStatus); /* current status */
355           } else {
356              Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
357           }
358 Index: src/dird/job.c
359 ===================================================================
360 --- src/dird/job.c      (revision 6731)
361 +++ src/dird/job.c      (working copy)
362 @@ -41,8 +41,9 @@
363  static void *job_thread(void *arg);
364  static void job_monitor_watchdog(watchdog_t *self);
365  static void job_monitor_destructor(watchdog_t *self);
366 -static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr);
367 -static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr);
368 +static bool job_check_maxwaittime(JCR *jcr);
369 +static bool job_check_maxruntime(JCR *jcr);
370 +static bool job_check_maxschedruntime(JCR *jcr);
371  
372  /* Imported subroutines */
373  extern void term_scheduler();
374 @@ -253,6 +254,11 @@
375        Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
376     }
377  
378 +   if (job_check_maxschedruntime(jcr)) {
379 +      set_jcr_job_status(jcr, JS_Canceled);
380 +      Jmsg(jcr, M_FATAL, 0, _("Job canceled because max sched run time exceeded.\n"));
381 +   }
382 +
383     /* TODO : check if it is used somewhere */
384     if (jcr->job->RunScripts == NULL) {
385        Dmsg0(200, "Warning, job->RunScripts is empty\n");
386 @@ -493,15 +499,20 @@
387        }
388  
389        /* check MaxWaitTime */
390 -      if (job_check_maxwaittime(control_jcr, jcr)) {
391 +      if (job_check_maxwaittime(jcr)) {
392           set_jcr_job_status(jcr, JS_Canceled);
393           Jmsg(jcr, M_FATAL, 0, _("Max wait time exceeded. Job canceled.\n"));
394           cancel = true;
395        /* check MaxRunTime */
396 -      } else if (job_check_maxruntime(control_jcr, jcr)) {
397 +      } else if (job_check_maxruntime(jcr)) {
398           set_jcr_job_status(jcr, JS_Canceled);
399           Jmsg(jcr, M_FATAL, 0, _("Max run time exceeded. Job canceled.\n"));
400           cancel = true;
401 +      /* check MaxSchedRunTime */ 
402 +      } else if (job_check_maxschedruntime(jcr)) {
403 +         set_jcr_job_status(jcr, JS_Canceled);
404 +         Jmsg(jcr, M_FATAL, 0, _("Max sched run time exceeded. Job canceled.\n"));
405 +         cancel = true;
406        }
407  
408        if (cancel) {
409 @@ -522,47 +533,71 @@
410   * Check if the maxwaittime has expired and it is possible
411   *  to cancel the job.
412   */
413 -static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
414 +static bool job_check_maxwaittime(JCR *jcr)
415  {
416     bool cancel = false;
417     JOB *job = jcr->job;
418  
419 -   if (job_canceled(jcr)) {
420 -      return false;                /* already canceled */
421 +   if (!job_waiting(jcr)) {
422 +      return false;
423     }
424 -   if (job->MaxWaitTime == 0 && job->FullMaxWaitTime == 0 &&
425 -       job->IncMaxWaitTime == 0 && job->DiffMaxWaitTime == 0) {
426 +   Dmsg3(200, "check maxwaittime %u - %u >= %u\n", watchdog_time, jcr->wait_time, job->MaxWaitTime);
427 +   if (job->MaxWaitTime != 0 &&
428 +       (watchdog_time - jcr->wait_time) >= job->MaxWaitTime) {
429 +      cancel = true;
430 +   }
431 +
432 +   return cancel;
433 +}
434 +
435 +/*
436 + * Check if maxruntime has expired and if the job can be
437 + *   canceled.
438 + */
439 +static bool job_check_maxruntime(JCR *jcr)
440 +{
441 +   bool cancel = false;
442 +   JOB *job = jcr->job;
443 +
444 +   if (job_canceled(jcr) || jcr->JobStatus == JS_Created) {
445        return false;
446 -   } 
447 -   if (jcr->JobLevel == L_FULL && job->FullMaxWaitTime != 0 &&
448 -         (watchdog_time - jcr->start_time) >= job->FullMaxWaitTime) {
449 +   }
450 +   if (jcr->job->MaxRunTime == 0 && job->FullMaxRunTime == 0 &&
451 +       job->IncMaxRunTime == 0 && job->DiffMaxRunTime == 0) {
452 +      return false;
453 +   }
454 +   Dmsg6(200, "check_maxruntime %u - %u >= %u|%u|%u|%u\n\n",
455 +        watchdog_time, jcr->start_time, job->MaxRunTime, job->FullMaxRunTime, 
456 +        job->IncMaxRunTime, job->DiffMaxRunTime);
457 +
458 +   if (jcr->JobLevel == L_FULL && job->FullMaxRunTime != 0 &&
459 +         (watchdog_time - jcr->start_time) >= job->FullMaxRunTime) {
460        cancel = true;
461 -   } else if (jcr->JobLevel == L_DIFFERENTIAL && job->DiffMaxWaitTime != 0 &&
462 -         (watchdog_time - jcr->start_time) >= job->DiffMaxWaitTime) {
463 +   } else if (jcr->JobLevel == L_DIFFERENTIAL && job->DiffMaxRunTime != 0 &&
464 +         (watchdog_time - jcr->start_time) >= job->DiffMaxRunTime) {
465        cancel = true;
466 -   } else if (jcr->JobLevel == L_INCREMENTAL && job->IncMaxWaitTime != 0 &&
467 -         (watchdog_time - jcr->start_time) >= job->IncMaxWaitTime) {
468 +   } else if (jcr->JobLevel == L_INCREMENTAL && job->IncMaxRunTime != 0 &&
469 +         (watchdog_time - jcr->start_time) >= job->IncMaxRunTime) {
470        cancel = true;
471 -   } else if (job->MaxWaitTime != 0 &&
472 -         (watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
473 +   } else if ((watchdog_time - jcr->start_time) >= job->MaxRunTime) {
474        cancel = true;
475     }
476 -
477
478     return cancel;
479  }
480  
481  /*
482 - * Check if maxruntime has expired and if the job can be
483 + * Check if MaxSchedRunTime has expired and if the job can be
484   *   canceled.
485   */
486 -static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr)
487 +static bool job_check_maxschedruntime(JCR *jcr)
488  {
489 -   if (jcr->job->MaxRunTime == 0 || job_canceled(jcr) || jcr->JobStatus == JS_Created) {
490 +   if (jcr->job->MaxSchedRunTime == 0 || job_canceled(jcr)) {
491        return false;
492     }
493 -   if ((watchdog_time - jcr->start_time) < jcr->job->MaxRunTime) {
494 -      Dmsg3(200, "Job %p (%s) with MaxRunTime %d not expired\n",
495 -            jcr, jcr->Job, jcr->job->MaxRunTime);
496 +   if ((watchdog_time - jcr->sched_time) < jcr->job->MaxSchedRunTime) {
497 +      Dmsg3(200, "Job %p (%s) with MaxSchedRunTime %d not expired\n",
498 +            jcr, jcr->Job, jcr->job->MaxSchedRunTime);
499        return false;
500     }
501  
502 Index: src/dird/dird_conf.c
503 ===================================================================
504 --- src/dird/dird_conf.c        (revision 6731)
505 +++ src/dird/dird_conf.c        (working copy)
506 @@ -289,10 +289,15 @@
507     {"writebootstrap",store_dir, ITEM(res_job.WriteBootstrap), 0, 0, 0},
508     {"writeverifylist",store_dir, ITEM(res_job.WriteVerifyList), 0, 0, 0},
509     {"replace",  store_replace,  ITEM(res_job.replace), 0, ITEM_DEFAULT, REPLACE_ALWAYS},
510 +   {"maxschedruntime", store_time, ITEM(res_job.MaxSchedRunTime), 0, 0, 0},
511     {"maxruntime",   store_time, ITEM(res_job.MaxRunTime), 0, 0, 0},
512 -   {"fullmaxwaittime",  store_time, ITEM(res_job.FullMaxWaitTime), 0, 0, 0},
513 -   {"incrementalmaxwaittime",  store_time, ITEM(res_job.IncMaxWaitTime), 0, 0, 0},
514 -   {"differentialmaxwaittime",  store_time, ITEM(res_job.DiffMaxWaitTime), 0, 0, 0},
515 +   /* xxxMaxWaitTime are deprecated */
516 +   {"fullmaxwaittime",  store_time, ITEM(res_job.FullMaxRunTime), 0, 0, 0},
517 +   {"incrementalmaxwaittime",  store_time, ITEM(res_job.IncMaxRunTime), 0, 0, 0},
518 +   {"differentialmaxwaittime",  store_time, ITEM(res_job.DiffMaxRunTime), 0, 0, 0},
519 +   {"fullmaxruntime",  store_time, ITEM(res_job.FullMaxRunTime), 0, 0, 0},
520 +   {"incrementalmaxruntime",  store_time, ITEM(res_job.IncMaxRunTime), 0, 0, 0},
521 +   {"differentialmaxruntime",  store_time, ITEM(res_job.DiffMaxRunTime), 0, 0, 0},
522     {"maxwaittime",  store_time, ITEM(res_job.MaxWaitTime), 0, 0, 0},
523     {"maxstartdelay",store_time, ITEM(res_job.MaxStartDelay), 0, 0, 0},
524     {"maxfullinterval",  store_time, ITEM(res_job.MaxFullInterval), 0, 0, 0},
525 @@ -666,6 +671,15 @@
526        if (res->res_job.PluginOptions) {
527           sendit(sock, _("  --> PluginOptions=%s\n"), NPRT(res->res_job.PluginOptions));
528        }
529 +      if (res->res_job.MaxRunTime) {
530 +         sendit(sock, _("  --> MaxRunTime=%u\n"), res->res_job.MaxRunTime);
531 +      }
532 +      if (res->res_job.MaxWaitTime) {
533 +         sendit(sock, _("  --> MaxWaitTime=%u\n"), res->res_job.MaxWaitTime);
534 +      }
535 +      if (res->res_job.MaxStartDelay) {
536 +         sendit(sock, _("  --> MaxStartDelay=%u\n"), res->res_job.MaxStartDelay);
537 +      }
538        if (res->res_job.storage) {
539           STORE *store;
540           foreach_alist(store, res->res_job.storage) {
541 Index: src/dird/dird_conf.h
542 ===================================================================
543 --- src/dird/dird_conf.h        (revision 6731)
544 +++ src/dird/dird_conf.h        (working copy)
545 @@ -384,10 +384,11 @@
546     };
547     utime_t MaxRunTime;                /* max run time in seconds */
548     utime_t MaxWaitTime;               /* max blocking time in seconds */
549 -   utime_t FullMaxWaitTime;           /* Max Full job wait time */
550 -   utime_t DiffMaxWaitTime;           /* Max Differential job wait time */
551 -   utime_t IncMaxWaitTime;            /* Max Incremental job wait time */
552 +   utime_t FullMaxRunTime;            /* Max Full job run time */
553 +   utime_t DiffMaxRunTime;            /* Max Differential job run time */
554 +   utime_t IncMaxRunTime;             /* Max Incremental job run time */
555     utime_t MaxStartDelay;             /* max start delay in seconds */
556 +   utime_t MaxSchedRunTime;           /* max run time in seconds from Scheduled time*/
557     utime_t RescheduleInterval;        /* Reschedule interval */
558     utime_t JobRetention;              /* job retention period in seconds */
559     utime_t MaxFullInterval;           /* Maximum time interval between Fulls */
560 Index: src/jcr.h
561 ===================================================================
562 --- src/jcr.h   (revision 6731)
563 +++ src/jcr.h   (working copy)
564 @@ -109,6 +109,22 @@
565     jcr->JobStatus == JS_ErrorTerminated || \
566     jcr->JobStatus == JS_FatalError)
567  
568 +#define job_waiting(jcr) \
569 +  (jcr->JobStatus == JS_WaitFD       || \
570 +   jcr->JobStatus == JS_WaitSD      || \
571 +   jcr->JobStatus == JS_WaitMedia    || \
572 +   jcr->JobStatus == JS_WaitMount    || \
573 +   jcr->JobStatus == JS_WaitStoreRes || \
574 +   jcr->JobStatus == JS_WaitJobRes   || \
575 +   jcr->JobStatus == JS_WaitClientRes|| \
576 +   jcr->JobStatus == JS_WaitMaxJobs  || \
577 +   jcr->JobStatus == JS_WaitPriority || \
578 +   jcr->SDJobStatus == JS_WaitMedia  || \
579 +   jcr->SDJobStatus == JS_WaitMount  || \
580 +   jcr->SDJobStatus == JS_WaitMaxJobs)
581 +
582 +
583 +
584  #define foreach_jcr(jcr) \
585     for (jcr=jcr_walk_start(); jcr; (jcr=jcr_walk_next(jcr)) )
586  
587 @@ -188,6 +204,7 @@
588     time_t start_time;                 /* when job actually started */
589     time_t run_time;                   /* used for computing speed */
590     time_t end_time;                   /* job end time */
591 +   time_t wait_time;                  /* when job have started to wait */
592     POOLMEM *client_name;              /* client name */
593     POOLMEM *RestoreBootstrap;         /* Bootstrap file to restore */
594     POOLMEM *stime;                    /* start time for incremental/differential */
595 Index: src/lib/jcr.c
596 ===================================================================
597 --- src/lib/jcr.c       (revision 6731)
598 +++ src/lib/jcr.c       (working copy)
599 @@ -632,6 +632,24 @@
600  
601  void set_jcr_job_status(JCR *jcr, int JobStatus)
602  {
603 +    bool set_waittime=false;
604 +    Dmsg2(800, "set_jcr_job_status(%s, %c)\n", jcr->Job, JobStatus);
605 +    /* if wait state is new, we keep current time for watchdog MaxWaitTime */
606 +    switch (JobStatus) {
607 +       case JS_WaitFD:
608 +       case JS_WaitSD:
609 +       case JS_WaitMedia:
610 +       case JS_WaitMount:
611 +       case JS_WaitStoreRes:
612 +       case JS_WaitJobRes:
613 +       case JS_WaitClientRes:
614 +       case JS_WaitMaxJobs:
615 +       case JS_WaitPriority:
616 +         set_waittime = true;
617 +       default:
618 +         break;
619 +    }
620
621     /*
622      * For a set of errors, ... keep the current status
623      *   so it isn't lost. For all others, set it.
624 @@ -652,10 +670,29 @@
625           /* Override more minor status */
626           jcr->JobStatus = JobStatus;
627           break;
628 +      default:
629 +         break;
630        }
631 -      break;
632 +   /*
633 +    * For a set of Wait situation, keep old time.
634 +    */
635 +   case JS_WaitFD:
636 +   case JS_WaitSD:
637 +   case JS_WaitMedia:
638 +   case JS_WaitMount:
639 +   case JS_WaitStoreRes:
640 +   case JS_WaitJobRes:
641 +   case JS_WaitClientRes:
642 +   case JS_WaitMaxJobs:
643 +   case JS_WaitPriority:
644 +       set_waittime = false;    /* keep old time */
645     default:
646        jcr->JobStatus = JobStatus;
647 +      if (set_waittime) {
648 +         /* set it before JobStatus */
649 +         Dmsg0(800, "Setting wait_time\n");
650 +         jcr->wait_time = time(NULL);
651 +      }
652     }
653     Dmsg3(100, "jid=%u OnExit JobStatus=%c set=%c\n", (uint32_t)jcr->JobId,
654           jcr->JobStatus, JobStatus);