/*
- Bacula® - The Network Backup Solution
+ Bacula(R) - The Network Backup Solution
- Copyright (C) 2003-2014 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2015 Kern Sibbald
- The main author of Bacula is Kern Sibbald, with contributions from many
- others, a complete list can be found in the file AUTHORS.
+ The original author of Bacula is Kern Sibbald, with contributions
+ from many others, a complete list can be found in the file AUTHORS.
You may use this file and others of this release according to the
license defined in the LICENSE file, which includes the Affero General
Public License, v3.0 ("AGPLv3") and some additional permissions and
terms pursuant to its AGPLv3 Section 7.
- Bacula® is a registered trademark of Kern Sibbald.
+ This notice must be preserved when any source code is
+ conveyed and/or propagated.
+
+ Bacula(R) is a registered trademark of Kern Sibbald.
*/
/*
* Bacula job queue routines.
return NULL;
}
+/* Procedure to update the Client->NumConcurrentJobs */
+static void update_client_numconcurrentjobs(JCR *jcr, int val)
+{
+ if (!jcr->client) {
+ return;
+ }
+
+ switch (jcr->getJobType())
+ {
+ case JT_MIGRATE:
+ case JT_COPY:
+ case JT_ADMIN:
+ break;
+ case JT_BACKUP:
+ if (jcr->no_client_used()) {
+ break;
+ }
+ /* Failback wanted */
+ default:
+ jcr->client->NumConcurrentJobs += val;
+ break;
+ }
+}
+
/*
* Add a job to the queue
* jq is a queue that was created with jobq_init
remove_jcr_from_tsd(je->jcr);
je->jcr->set_killable(false);
- /* Clear the threadid, probably not necessary */
- memset(&jcr->my_thread_id, 0, sizeof(jcr->my_thread_id));
-
Dmsg2(2300, "Back from user engine jobid=%d use=%d.\n", jcr->JobId,
jcr->use_count());
if (jcr->acquired_resource_locks) {
dec_read_store(jcr);
dec_write_store(jcr);
- jcr->client->NumConcurrentJobs--;
+ update_client_numconcurrentjobs(jcr, -1);
jcr->job->NumConcurrentJobs--;
jcr->acquired_resource_locks = false;
}
if (jcr->job->RescheduleTimes == 0 ||
jcr->reschedule_count < jcr->job->RescheduleTimes) {
resched =
+ /* Check for incomplete jobs */
+ (jcr->RescheduleIncompleteJobs &&
+ jcr->is_incomplete() && jcr->is_JobType(JT_BACKUP) &&
+ !(jcr->HasBase||jcr->is_JobLevel(L_BASE))) ||
/* Check for failed jobs */
(jcr->job->RescheduleOnError &&
!jcr->is_JobStatus(JS_Terminated) &&
* Reschedule this job by cleaning it up, but
* reuse the same JobId if possible.
*/
+ jcr->rerunning = jcr->is_incomplete(); /* save incomplete status */
time_t now = time(NULL);
jcr->reschedule_count++;
jcr->sched_time = now + jcr->job->RescheduleInterval;
if (!allow_duplicate_job(jcr)) {
return false;
}
- /* Only jobs with no output jobs can run on same JCR */
- if (jcr->JobBytes == 0) {
+ /* Only jobs with no output or Incomplete jobs can run on same JCR */
+ if (jcr->JobBytes == 0 || jcr->rerunning) {
Dmsg2(2300, "Requeue job=%d use=%d\n", jcr->JobId, jcr->use_count());
V(jq->mutex);
/*
if (jcr->wasVirtualFull) {
jcr->setJobLevel(L_VIRTUAL_FULL);
}
+ /*
+ * When we are using the same jcr then make sure to reset
+ * RealEndTime back to zero.
+ */
+ jcr->jr.RealEndTime = 0;
jobq_add(jq, jcr); /* queue the job to run again */
P(jq->mutex);
free_jcr(jcr); /* release jcr */
*/
JCR *njcr = new_jcr(sizeof(JCR), dird_free_jcr);
set_jcr_defaults(njcr, jcr->job);
+ /*
+ * Eliminate the new job_end_push, then copy the one from
+ * the old job, and set the old one to be empty.
+ */
+ void *v;
+ lock_jobs(); /* protect ourself from reload_config() */
+ LockRes();
+ foreach_alist(v, (&jcr->job_end_push)) {
+ njcr->job_end_push.append(v);
+ }
+ jcr->job_end_push.destroy();
+ jcr->job_end_push.init(1, false);
+ UnlockRes();
+ unlock_jobs();
+
njcr->reschedule_count = jcr->reschedule_count;
njcr->sched_time = jcr->sched_time;
njcr->initial_sched_time = jcr->initial_sched_time;
njcr->next_pool = jcr->next_pool;
njcr->run_next_pool_override = jcr->run_next_pool_override;
njcr->full_pool = jcr->full_pool;
+ njcr->vfull_pool = jcr->vfull_pool;
njcr->run_full_pool_override = jcr->run_full_pool_override;
+ njcr->run_vfull_pool_override = jcr->run_vfull_pool_override;
njcr->inc_pool = jcr->inc_pool;
njcr->run_inc_pool_override = jcr->run_inc_pool_override;
njcr->diff_pool = jcr->diff_pool;
return false;
}
- if (jcr->client->NumConcurrentJobs < jcr->client->MaxConcurrentJobs) {
- jcr->client->NumConcurrentJobs++;
- } else {
- /* Back out previous locks */
- dec_write_store(jcr);
- dec_read_store(jcr);
- jcr->setJobStatus(JS_WaitClientRes);
- return false;
+ if (jcr->client) {
+ if (jcr->client->NumConcurrentJobs < jcr->client->MaxConcurrentJobs) {
+ update_client_numconcurrentjobs(jcr, 1);
+ } else {
+ /* Back out previous locks */
+ dec_write_store(jcr);
+ dec_read_store(jcr);
+ jcr->setJobStatus(JS_WaitClientRes);
+ return false;
+ }
}
if (jcr->job->NumConcurrentJobs < jcr->job->MaxConcurrentJobs) {
jcr->job->NumConcurrentJobs++;
/* Back out previous locks */
dec_write_store(jcr);
dec_read_store(jcr);
- jcr->client->NumConcurrentJobs--;
+ update_client_numconcurrentjobs(jcr, -1);
jcr->setJobStatus(JS_WaitJobRes);
return false;
}