2 This patch should hold jobs in the Director's start queue if
3 more than one simultaneous backup job wants to use the same
4 Storage device with two different Pools (i.e. 2 Volumes).
5 Apply the patch to version 1.36.1 with:
8 patch -p0 <1.36.1-pool.patch
13 Index: src/dird/jobq.c
14 ===================================================================
15 RCS file: /cvsroot/bacula/bacula/src/dird/jobq.c,v
16 retrieving revision 1.25
17 retrieving revision 1.26
19 --- src/dird/jobq.c 24 Sep 2004 12:30:14 -0000 1.25
20 +++ src/dird/jobq.c 3 Dec 2004 21:00:18 -0000 1.26
23 * Kern Sibbald, July MMIII
28 * This code was adapted from the Bacula workq, which was
29 * adapted from "Programming with POSIX Threads", by
36 /* Forward referenced functions */
37 extern "C" void *jobq_server(void *arg);
40 static int start_server(jobq_t *jq);
45 * Initialize a job queue
49 /* je is current job item on the queue, jn is the next one */
51 + bool skip_this_jcr = false;
52 jobq_item_t *jn = (jobq_item_t *)jq->waiting_jobs->next(je);
53 Dmsg3(300, "Examining Job=%d JobPri=%d want Pri=%d\n",
54 jcr->JobId, jcr->JobPriority, Priority);
56 jcr->store->MaxConcurrentJobs = 1;
58 set_jcr_job_status(jcr, JS_WaitStoreRes);
60 + je = jn; /* point to next waiting job */
63 + /* We are not doing a Restore or Verify */
64 + } else if (jcr->store->NumConcurrentJobs == 0 &&
65 + jcr->store->NumConcurrentJobs < jcr->store->MaxConcurrentJobs) {
66 + /* Simple case, first job */
67 + jcr->store->NumConcurrentJobs = 1;
68 } else if (jcr->store->NumConcurrentJobs < jcr->store->MaxConcurrentJobs) {
69 - jcr->store->NumConcurrentJobs++;
72 + * At this point, we already have at least one Job running
73 + * for this Storage daemon, so we must ensure that there
74 + * is no Volume conflict. In general, it should be OK, if
75 + * all Jobs pull from the same Pool, so we check the Pools.
79 + for (njcr=jobs; njcr; njcr=njcr->next) {
80 + if (njcr->JobId == 0 || njcr == jcr) {
83 + if (njcr->pool != jcr->pool) {
84 + skip_this_jcr = true;
89 + if (!skip_this_jcr) {
90 + jcr->store->NumConcurrentJobs++;
93 + if (skip_this_jcr) {
94 set_jcr_job_status(jcr, JS_WaitStoreRes);
96 + je = jn; /* point to next waiting job */
101 jcr->store->MaxConcurrentJobs = jcr->saveMaxConcurrentJobs;
103 set_jcr_job_status(jcr, JS_WaitClientRes);
105 + je = jn; /* point to next waiting job */
108 if (jcr->job->NumConcurrentJobs < jcr->job->MaxConcurrentJobs) {
111 jcr->client->NumConcurrentJobs--;
112 set_jcr_job_status(jcr, JS_WaitJobRes);
114 + je = jn; /* Point to next waiting job */
117 /* Got all locks, now remove it from wait queue and append it
119 jq->waiting_jobs->remove(je);
120 jq->ready_jobs->append(je);
121 Dmsg1(300, "moved JobId=%d from wait to ready queue\n", je->jcr->JobId);
123 + je = jn; /* Point to next waiting job */
126 } /* end while loop */
128 ===================================================================
129 RCS file: /cvsroot/bacula/bacula/src/lib/jcr.c,v
130 retrieving revision 1.61
131 retrieving revision 1.62
132 diff -u -r1.61 -r1.62
133 --- src/lib/jcr.c 15 Nov 2004 22:43:33 -0000 1.61
134 +++ src/lib/jcr.c 3 Dec 2004 21:00:19 -0000 1.62
137 * Kern E. Sibbald, December 2000
142 * These routines are thread safe.
145 dlist *last_jobs = NULL;
146 const int max_last_jobs = 10;
148 -static JCR *jobs = NULL; /* pointer to JCR chain */
149 +JCR *jobs = NULL; /* pointer to JCR chain */
150 static brwlock_t lock; /* lock for last jobs and JCR chain */
152 void init_last_jobs_list()