1 Index: patches/testing/maxschedruntime.patch
2 ===================================================================
3 --- patches/testing/maxschedruntime.patch (revision 6731)
4 +++ patches/testing/maxschedruntime.patch (working copy)
6 -Index: src/dird/getmsg.c
7 -===================================================================
8 ---- src/dird/getmsg.c (révision 4696)
9 -+++ src/dird/getmsg.c (copie de travail)
12 - static char OK_msg[] = "1000 OK\n";
15 -+void set_jcr_sd_job_status(JCR *jcr, int SDJobStatus)
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) {
23 -+ case JS_WaitMaxJobs:
24 -+ set_waittime = true;
29 -+ if (job_waiting(jcr)) {
30 -+ set_waittime = false;
33 -+ if (set_waittime) {
34 -+ /* set it before JobStatus */
35 -+ Dmsg0(800, "Setting wait_time\n");
36 -+ jcr->wait_time = time(NULL);
38 -+ jcr->SDJobStatus = SDJobStatus;
43 - * Call appropriate processing routine
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 */
51 - Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
53 -Index: src/dird/job.c
54 -===================================================================
55 ---- src/dird/job.c (révision 4696)
56 -+++ src/dird/job.c (copie de travail)
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);
67 - /* Imported subroutines */
68 - extern void term_scheduler();
70 - Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
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"));
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 @@
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"));
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"));
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"));
104 -@@ -479,29 +490,30 @@
105 - * Check if the maxwaittime has expired and it is possible
106 - * to cancel the job.
108 --static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
109 -+static bool job_check_maxwaittime(JCR *jcr)
111 - bool cancel = false;
112 - JOB *job = jcr->job;
114 -- if (job_canceled(jcr)) {
115 -- return false; /* already canceled */
116 -+ if (!job_waiting(jcr)) {
119 - if (job->MaxWaitTime == 0 && job->FullMaxWaitTime == 0 &&
120 - job->IncMaxWaitTime == 0 && job->DiffMaxWaitTime == 0) {
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) {
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) {
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) {
136 - } else if (job->MaxWaitTime != 0 &&
137 -- (watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
138 -+ (watchdog_time - jcr->wait_time) >= job->MaxWaitTime) {
143 - * Check if maxruntime has expired and if the job can be
146 --static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr)
147 -+static bool job_check_maxruntime(JCR *jcr)
149 - if (jcr->job->MaxRunTime == 0 || job_canceled(jcr)) {
151 -@@ -527,6 +539,24 @@
155 -+ * Check if MaxSchedRunTime has expired and if the job can be
158 -+static bool job_check_maxschedruntime(JCR *jcr)
160 -+ if (jcr->job->MaxSchedRunTime == 0 || job_canceled(jcr)) {
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);
173 - * Get or create a Pool record with the given name.
174 - * Returns: 0 on error
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)
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));
192 -+ if (res->res_job.MaxRunTime) {
193 -+ sendit(sock, _(" --> MaxRunTime=%u\n"), res->res_job.MaxRunTime);
195 -+ if (res->res_job.MaxWaitTime) {
196 -+ sendit(sock, _(" --> MaxWaitTime=%u\n"), res->res_job.MaxWaitTime);
198 -+ if (res->res_job.MaxStartDelay) {
199 -+ sendit(sock, _(" --> MaxStartDelay=%u\n"), res->res_job.MaxStartDelay);
201 - if (res->res_job.storage) {
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)
209 - char *WriteVerifyList; /* List of changed files */
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 */
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)
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)
240 - #define foreach_jcr(jcr) \
241 - for (jcr=jcr_walk_start(); jcr; (jcr=jcr_walk_next(jcr)) )
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 @@
257 - void set_jcr_job_status(JCR *jcr, int JobStatus)
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) {
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;
277 -+ switch (jcr->JobStatus) {
279 - * For a set of errors, ... keep the current status
280 - * so it isn't lost. For all others, set it.
282 -- switch (jcr->JobStatus) {
283 - case JS_ErrorTerminated:
285 - case JS_FatalError:
286 - case JS_Differences:
290 -+ * For a set of Wait situation, keep old time.
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 */
303 -+ if (set_waittime) {
304 -+ /* set it before JobStatus */
305 -+ Dmsg0(800, "Setting wait_time\n");
306 -+ jcr->wait_time = time(NULL);
308 - jcr->JobStatus = JobStatus;
311 Index: src/dird/getmsg.c
312 ===================================================================
313 --- src/dird/getmsg.c (revision 6731)
314 +++ src/dird/getmsg.c (working copy)
317 static char OK_msg[] = "1000 OK\n";
320 +void set_jcr_sd_job_status(JCR *jcr, int SDJobStatus)
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) {
328 + case JS_WaitMaxJobs:
329 + set_waittime = true;
334 + if (job_waiting(jcr)) {
335 + set_waittime = false;
338 + if (set_waittime) {
339 + /* set it before JobStatus */
340 + Dmsg0(800, "Setting wait_time\n");
341 + jcr->wait_time = time(NULL);
343 + jcr->SDJobStatus = SDJobStatus;
348 * Call appropriate processing routine
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 */
356 Emsg1(M_ERROR, 0, _("Malformed message: %s\n"), bs->msg);
358 Index: src/dird/job.c
359 ===================================================================
360 --- src/dird/job.c (revision 6731)
361 +++ src/dird/job.c (working copy)
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);
372 /* Imported subroutines */
373 extern void term_scheduler();
375 Jmsg(jcr, M_FATAL, 0, _("Job canceled because max start delay time exceeded.\n"));
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"));
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 @@
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"));
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"));
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"));
409 @@ -522,47 +533,71 @@
410 * Check if the maxwaittime has expired and it is possible
413 -static bool job_check_maxwaittime(JCR *control_jcr, JCR *jcr)
414 +static bool job_check_maxwaittime(JCR *jcr)
419 - if (job_canceled(jcr)) {
420 - return false; /* already canceled */
421 + if (!job_waiting(jcr)) {
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) {
436 + * Check if maxruntime has expired and if the job can be
439 +static bool job_check_maxruntime(JCR *jcr)
441 + bool cancel = false;
442 + JOB *job = jcr->job;
444 + if (job_canceled(jcr) || jcr->JobStatus == JS_Created) {
447 - if (jcr->JobLevel == L_FULL && job->FullMaxWaitTime != 0 &&
448 - (watchdog_time - jcr->start_time) >= job->FullMaxWaitTime) {
450 + if (jcr->job->MaxRunTime == 0 && job->FullMaxRunTime == 0 &&
451 + job->IncMaxRunTime == 0 && job->DiffMaxRunTime == 0) {
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);
458 + if (jcr->JobLevel == L_FULL && job->FullMaxRunTime != 0 &&
459 + (watchdog_time - jcr->start_time) >= job->FullMaxRunTime) {
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) {
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) {
471 - } else if (job->MaxWaitTime != 0 &&
472 - (watchdog_time - jcr->start_time) >= job->MaxWaitTime) {
473 + } else if ((watchdog_time - jcr->start_time) >= job->MaxRunTime) {
482 - * Check if maxruntime has expired and if the job can be
483 + * Check if MaxSchedRunTime has expired and if the job can be
486 -static bool job_check_maxruntime(JCR *control_jcr, JCR *jcr)
487 +static bool job_check_maxschedruntime(JCR *jcr)
489 - if (jcr->job->MaxRunTime == 0 || job_canceled(jcr) || jcr->JobStatus == JS_Created) {
490 + if (jcr->job->MaxSchedRunTime == 0 || job_canceled(jcr)) {
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);
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},
526 if (res->res_job.PluginOptions) {
527 sendit(sock, _(" --> PluginOptions=%s\n"), NPRT(res->res_job.PluginOptions));
529 + if (res->res_job.MaxRunTime) {
530 + sendit(sock, _(" --> MaxRunTime=%u\n"), res->res_job.MaxRunTime);
532 + if (res->res_job.MaxWaitTime) {
533 + sendit(sock, _(" --> MaxWaitTime=%u\n"), res->res_job.MaxWaitTime);
535 + if (res->res_job.MaxStartDelay) {
536 + sendit(sock, _(" --> MaxStartDelay=%u\n"), res->res_job.MaxStartDelay);
538 if (res->res_job.storage) {
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 @@
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 */
561 ===================================================================
562 --- src/jcr.h (revision 6731)
563 +++ src/jcr.h (working copy)
565 jcr->JobStatus == JS_ErrorTerminated || \
566 jcr->JobStatus == JS_FatalError)
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)
584 #define foreach_jcr(jcr) \
585 for (jcr=jcr_walk_start(); jcr; (jcr=jcr_walk_next(jcr)) )
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 */
596 ===================================================================
597 --- src/lib/jcr.c (revision 6731)
598 +++ src/lib/jcr.c (working copy)
601 void set_jcr_job_status(JCR *jcr, int JobStatus)
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) {
611 + case JS_WaitStoreRes:
612 + case JS_WaitJobRes:
613 + case JS_WaitClientRes:
614 + case JS_WaitMaxJobs:
615 + case JS_WaitPriority:
616 + set_waittime = true;
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;
633 + * For a set of Wait situation, keep old time.
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 */
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);
653 Dmsg3(100, "jid=%u OnExit JobStatus=%c set=%c\n", (uint32_t)jcr->JobId,
654 jcr->JobStatus, JobStatus);