+ return true;
+}
+
+/*
+ * Get or create a Pool record with the given name.
+ * Returns: 0 on error
+ * poolid if OK
+ */
+DBId_t get_or_create_pool_record(JCR *jcr, char *pool_name)
+{
+ POOL_DBR pr;
+
+ memset(&pr, 0, sizeof(pr));
+ bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
+ Dmsg1(110, "get_or_create_pool=%s\n", pool_name);
+
+ while (!db_get_pool_record(jcr, jcr->db, &pr)) { /* get by Name */
+ /* Try to create the pool */
+ if (create_pool(jcr, jcr->db, jcr->pool, POOL_OP_CREATE) < 0) {
+ Jmsg(jcr, M_FATAL, 0, _("Pool \"%s\" not in database. ERR=%s"), pr.Name,
+ db_strerror(jcr->db));
+ return 0;
+ } else {
+ Jmsg(jcr, M_INFO, 0, _("Created database record for Pool \"%s\".\n"), pr.Name);
+ }
+ }
+ return pr.PoolId;
+}
+
+/*
+ * Check for duplicate jobs.
+ * Returns: true if current job should continue
+ * false if current job should terminate
+ */
+bool allow_duplicate_job(JCR *jcr)
+{
+ JOB *job = jcr->job;
+ JCR *djcr; /* possible duplicate */
+
+ if (job->AllowDuplicateJobs) {
+ return true;
+ }
+ if (!job->AllowHigherDuplicates) {
+ foreach_jcr(djcr) {
+ char ec1[50];
+ if (strcmp(job->name(), djcr->job->name()) == 0) {
+ bool cancel_queued = false;
+ if (job->DuplicateJobProximity > 0) {
+ time_t now = time(NULL);
+ if ((now - djcr->start_time) > job->DuplicateJobProximity) {
+ continue; /* not really a duplicate */
+ }
+ }
+ /* Cancel */
+ if (!(job->CancelQueuedDuplicates || job->CancelRunningDuplicates)) {
+ /* Zap current job */
+ Jmsg(jcr, M_FATAL, 0, _("Duplicate job not allowed. JobId=%s\n"),
+ edit_uint64(djcr->JobId, ec1));
+ return false;
+ }
+ /* If CancelQueuedDuplicates is set do so only if job is queued */
+ if (job->CancelQueuedDuplicates) {
+ switch (djcr->JobStatus) {
+ case JS_Created:
+ case JS_WaitJobRes:
+ case JS_WaitClientRes:
+ case JS_WaitStoreRes:
+ case JS_WaitPriority:
+ case JS_WaitMaxJobs:
+ case JS_WaitStartTime:
+ cancel_queued = true;
+ break;
+ default:
+ break;
+ }
+ }
+ if (cancel_queued || job->CancelRunningDuplicates) {
+ UAContext *ua = new_ua_context(djcr);
+ Jmsg(jcr, M_INFO, 0, _("Cancelling duplicate JobId=%s.\n"),
+ edit_uint64(djcr->JobId, ec1));
+ ua->jcr = djcr;
+ cancel_job(ua, djcr);
+ free_ua_context(ua);
+ Dmsg2(800, "Have cancelled JCR %p Job=%d\n", djcr, djcr->JobId);
+ }
+ }
+ }
+ }
+ return true;
+}
+
+void apply_pool_overrides(JCR *jcr)
+{
+ bool pool_override = false;
+
+ if (jcr->run_pool_override) {
+ pm_strcpy(jcr->pool_source, _("Run pool override"));
+ }
+ /*
+ * Apply any level related Pool selections
+ */
+ switch (jcr->get_JobLevel()) {
+ case L_FULL:
+ if (jcr->full_pool) {
+ jcr->pool = jcr->full_pool;
+ pool_override = true;
+ if (jcr->run_full_pool_override) {
+ pm_strcpy(jcr->pool_source, _("Run FullPool override"));
+ } else {
+ pm_strcpy(jcr->pool_source, _("Job FullPool override"));
+ }
+ }
+ break;
+ case L_INCREMENTAL:
+ if (jcr->inc_pool) {
+ jcr->pool = jcr->inc_pool;
+ pool_override = true;
+ if (jcr->run_inc_pool_override) {
+ pm_strcpy(jcr->pool_source, _("Run IncPool override"));
+ } else {
+ pm_strcpy(jcr->pool_source, _("Job IncPool override"));
+ }
+ }
+ break;
+ case L_DIFFERENTIAL:
+ if (jcr->diff_pool) {
+ jcr->pool = jcr->diff_pool;
+ pool_override = true;
+ if (jcr->run_diff_pool_override) {
+ pm_strcpy(jcr->pool_source, _("Run DiffPool override"));
+ } else {
+ pm_strcpy(jcr->pool_source, _("Job DiffPool override"));
+ }
+ }
+ break;
+ }
+ /* Update catalog if pool overridden */
+ if (pool_override && jcr->pool->catalog) {
+ jcr->catalog = jcr->pool->catalog;
+ pm_strcpy(jcr->catalog_source, _("Pool resource"));
+ }