+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)
-@@ -43,6 +43,7 @@
+@@ -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_maxschedruntime(JCR *control_jcr, JCR *jcr);
+-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();
-@@ -459,7 +460,11 @@
+@@ -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(control_jcr, jcr)) {
++ } 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) {
- Dmsg3(800, "Cancelling JCR %p jobid %d (%s)\n", jcr, jcr->JobId, jcr->Job);
-@@ -527,6 +533,24 @@
+@@ -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 *control_jcr, JCR *jcr)
++static bool job_check_maxschedruntime(JCR *jcr)
+{
+ if (jcr->job->MaxSchedRunTime == 0 || job_canceled(jcr)) {
+ return false;
{"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)
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;
+ }
+ }