systems.
- Require pools to match before allowing multiple simultaneous
accesses to same storage resource.
- Add patch supplied by Martin to correct buffer overrun in
bsnprintf() with no library snprintf().
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1738
91ce42f0-d328-0410-95d8-
f526ca767f89
+- Browse generations of files.
- Add offline command to Bacula console.
- I've seen an error when my catalog's File table fills up. I
then have to recreate the File table with a larger maximum row
- Add offline command to Bacula console.
- I've seen an error when my catalog's File table fills up. I
then have to recreate the File table with a larger maximum row
#include "bacula.h"
#include "dird.h"
#include "bacula.h"
#include "dird.h"
/* Forward referenced functions */
extern "C" void *jobq_server(void *arg);
/* Forward referenced functions */
extern "C" void *jobq_server(void *arg);
static int start_server(jobq_t *jq);
static int start_server(jobq_t *jq);
/*
* Initialize a job queue
*
/*
* Initialize a job queue
*
for ( ; je; ) {
/* je is current job item on the queue, jn is the next one */
JCR *jcr = je->jcr;
for ( ; je; ) {
/* je is current job item on the queue, jn is the next one */
JCR *jcr = je->jcr;
+ bool skip_this_jcr = false;
jobq_item_t *jn = (jobq_item_t *)jq->waiting_jobs->next(je);
Dmsg3(300, "Examining Job=%d JobPri=%d want Pri=%d\n",
jcr->JobId, jcr->JobPriority, Priority);
jobq_item_t *jn = (jobq_item_t *)jq->waiting_jobs->next(je);
Dmsg3(300, "Examining Job=%d JobPri=%d want Pri=%d\n",
jcr->JobId, jcr->JobPriority, Priority);
jcr->store->MaxConcurrentJobs = 1;
} else {
set_jcr_job_status(jcr, JS_WaitStoreRes);
jcr->store->MaxConcurrentJobs = 1;
} else {
set_jcr_job_status(jcr, JS_WaitStoreRes);
+ je = jn; /* point to next waiting job */
+ /* We are not doing a Restore or Verify */
+ } else if (jcr->store->NumConcurrentJobs == 0 &&
+ jcr->store->NumConcurrentJobs < jcr->store->MaxConcurrentJobs) {
+ /* Simple case, first job */
+ jcr->store->NumConcurrentJobs = 1;
} else if (jcr->store->NumConcurrentJobs < jcr->store->MaxConcurrentJobs) {
} else if (jcr->store->NumConcurrentJobs < jcr->store->MaxConcurrentJobs) {
- jcr->store->NumConcurrentJobs++;
- } else {
+ /*
+ * At this point, we already have at least one Job running
+ * for this Storage daemon, so we must ensure that there
+ * is no Volume conflict. In general, it should be OK, if
+ * all Jobs pull from the same Pool, so we check the Pools.
+ */
+ JCR *njcr;
+ lock_jcr_chain();
+ for (njcr=jobs; njcr; njcr=njcr->next) {
+ if (njcr->JobId == 0 || njcr == jcr) {
+ continue;
+ }
+ if (njcr->pool != jcr->pool) {
+ skip_this_jcr = true;
+ break;
+ }
+ }
+ unlock_jcr_chain();
+ if (!skip_this_jcr) {
+ jcr->store->NumConcurrentJobs++;
+ }
+ }
+ if (skip_this_jcr) {
set_jcr_job_status(jcr, JS_WaitStoreRes);
set_jcr_job_status(jcr, JS_WaitStoreRes);
+ je = jn; /* point to next waiting job */
jcr->store->MaxConcurrentJobs = jcr->saveMaxConcurrentJobs;
}
set_jcr_job_status(jcr, JS_WaitClientRes);
jcr->store->MaxConcurrentJobs = jcr->saveMaxConcurrentJobs;
}
set_jcr_job_status(jcr, JS_WaitClientRes);
+ je = jn; /* point to next waiting job */
continue;
}
if (jcr->job->NumConcurrentJobs < jcr->job->MaxConcurrentJobs) {
continue;
}
if (jcr->job->NumConcurrentJobs < jcr->job->MaxConcurrentJobs) {
}
jcr->client->NumConcurrentJobs--;
set_jcr_job_status(jcr, JS_WaitJobRes);
}
jcr->client->NumConcurrentJobs--;
set_jcr_job_status(jcr, JS_WaitJobRes);
+ je = jn; /* Point to next waiting job */
continue;
}
/* Got all locks, now remove it from wait queue and append it
continue;
}
/* Got all locks, now remove it from wait queue and append it
jq->waiting_jobs->remove(je);
jq->ready_jobs->append(je);
Dmsg1(300, "moved JobId=%d from wait to ready queue\n", je->jcr->JobId);
jq->waiting_jobs->remove(je);
jq->ready_jobs->append(je);
Dmsg1(300, "moved JobId=%d from wait to ready queue\n", je->jcr->JobId);
+ je = jn; /* Point to next waiting job */
} /* end for loop */
break;
} /* end while loop */
} /* end for loop */
break;
} /* end while loop */
+#ifdef HAVE_OLD_SOCKOPT
+int inet_aton(const char *cp, struct in_addr *inp)
+{
+ struct in_addr inaddr;
+
+ if((inaddr.s_addr = inet_addr(cp)) != INADDR_NONE) {
+ inp->s_addr = inaddr.s_addr;
+ return 1;
+ }
+ return 0;
+}
+#endif
+
/*
* Read a nbytes from the network.
* It is possible that the total bytes require in several
/*
* Read a nbytes from the network.
* It is possible that the total bytes require in several
- buf = get_memory(BIG_BUF);
+ buflen = size > BIG_BUF ? size : BIG_BUF;
+ buf = get_memory(buflen);
len = vsprintf(buf, format, ap);
len = vsprintf(buf, format, ap);
Emsg0(M_ABORT, 0, _("Buffer overflow.\n"));
}
Emsg0(M_ABORT, 0, _("Buffer overflow.\n"));
}
- memcpy(str, buf, size);
- str[size-1] = 0;
+ memcpy(str, buf, len);
+ str[len] = 0; /* len excludes the null */
free_memory(buf);
return len;
#endif
free_memory(buf);
return len;
#endif
dlist *last_jobs = NULL;
const int max_last_jobs = 10;
dlist *last_jobs = NULL;
const int max_last_jobs = 10;
-static JCR *jobs = NULL; /* pointer to JCR chain */
+JCR *jobs = NULL; /* pointer to JCR chain */
static brwlock_t lock; /* lock for last jobs and JCR chain */
void init_last_jobs_list()
static brwlock_t lock; /* lock for last jobs and JCR chain */
void init_last_jobs_list()
/* */
#undef VERSION
#define VERSION "1.37.1"
/* */
#undef VERSION
#define VERSION "1.37.1"
-#define BDATE "02 December 2004"
-#define LSMDATE "02Dec04"
+#define BDATE "03 December 2004"
+#define LSMDATE "03Dec04"
/* Debug flags */
#undef DEBUG
/* Debug flags */
#undef DEBUG