/* * Given a JobId, find the JCR * Returns: jcr on success * NULL on failure */ JCR *get_jcr_by_id(uint32_t JobId) { JCR *jcr; foreach_jcr(jcr) { if (jcr->JobId == JobId) { jcr->inc_use_count(); Dmsg3(dbglvl, "Inc get_jcr jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); break; } } endeach_jcr(jcr); return jcr; }
/* * !!! WARNING !!! * * This function should be used ONLY after a fatal signal. We walk through the * JCR chain without doing any lock, BAREOS should not be running. */ void dbg_print_jcr(FILE *fp) { char buf1[128], buf2[128], buf3[128], buf4[128]; if (!jcrs) { return; } fprintf(fp, "Attempt to dump current JCRs. njcrs=%d\n", jcrs->size()); for (JCR *jcr = (JCR *)jcrs->first(); jcr ; jcr = (JCR *)jcrs->next(jcr)) { #ifdef HAVE_WIN32 fprintf(fp, "threadid=%p JobId=%d JobStatus=%c jcr=%p name=%s\n", (void *)&jcr->my_thread_id, (int)jcr->JobId, jcr->JobStatus, jcr, jcr->Job); fprintf(fp, "threadid=%p killable=%d JobId=%d JobStatus=%c " "jcr=%p name=%s\n", (void *)&jcr->my_thread_id, jcr->is_killable(), (int)jcr->JobId, jcr->JobStatus, jcr, jcr->Job); #else fprintf(fp, "threadid=%p JobId=%d JobStatus=%c jcr=%p name=%s\n", (void *)jcr->my_thread_id, (int)jcr->JobId, jcr->JobStatus, jcr, jcr->Job); fprintf(fp, "threadid=%p killable=%d JobId=%d JobStatus=%c " "jcr=%p name=%s\n", (void *)jcr->my_thread_id, jcr->is_killable(), (int)jcr->JobId, jcr->JobStatus, jcr, jcr->Job); #endif fprintf(fp, "\tuse_count=%i\n", jcr->use_count()); fprintf(fp, "\tJobType=%c JobLevel=%c\n", jcr->getJobType(), jcr->getJobLevel()); bstrftime(buf1, sizeof(buf1), jcr->sched_time); bstrftime(buf2, sizeof(buf2), jcr->start_time); bstrftime(buf3, sizeof(buf3), jcr->end_time); bstrftime(buf4, sizeof(buf4), jcr->wait_time); fprintf(fp, "\tsched_time=%s start_time=%s\n\tend_time=%s wait_time=%s\n", buf1, buf2, buf3, buf4); fprintf(fp, "\tdb=%p db_batch=%p batch_started=%i\n", jcr->db, jcr->db_batch, jcr->batch_started); /* * Call all the jcr debug hooks */ for(int i=0; i < dbg_jcr_handler_count; i++) { dbg_jcr_hook_t *hook = dbg_jcr_hooks[i]; hook(jcr, fp); } } }
/* * Given a SessionId and SessionTime, find the JCR * * Returns: jcr on success * NULL on failure */ JCR *get_jcr_by_session(uint32_t SessionId, uint32_t SessionTime) { JCR *jcr; foreach_jcr(jcr) { if (jcr->VolSessionId == SessionId && jcr->VolSessionTime == SessionTime) { jcr->inc_use_count(); Dmsg3(dbglvl, "Inc get_jcr jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); break; } } endeach_jcr(jcr); return jcr; }
/* * Given a Job, find the JCR requires an exact match of names. * * Returns: jcr on success * NULL on failure */ JCR *get_jcr_by_full_name(char *Job) { JCR *jcr; if (!Job) { return NULL; } foreach_jcr(jcr) { if (bstrcmp(jcr->Job, Job)) { jcr->inc_use_count(); Dmsg3(dbglvl, "Inc get_jcr jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); break; } } endeach_jcr(jcr); return jcr; }
/* * Get next jcr from chain, and release current one */ JCR *jcr_walk_next(JCR *prev_jcr) { JCR *jcr; lock_jcr_chain(); jcr = (JCR *)jcrs->next(prev_jcr); if (jcr) { jcr->inc_use_count(); if (jcr->JobId > 0) { Dmsg3(dbglvl, "Inc walk_next jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); } } unlock_jcr_chain(); if (prev_jcr) { free_jcr(prev_jcr); } return jcr; }
/* * Given a Job, find the JCR compares on the number of * characters in Job thus allowing partial matches. * * Returns: jcr on success * NULL on failure */ JCR *get_jcr_by_partial_name(char *Job) { JCR *jcr; int len; if (!Job) { return NULL; } len = strlen(Job); foreach_jcr(jcr) { if (bstrncmp(Job, jcr->Job, len)) { jcr->inc_use_count(); Dmsg3(dbglvl, "Inc get_jcr jid=%u use_count=%d Job=%s\n", jcr->JobId, jcr->use_count(), jcr->Job); break; } } endeach_jcr(jcr); return jcr; }
/* * Check for duplicate jobs. * Returns: true if current job should continue * false if current job should terminate */ bool allow_duplicate_job(JCR *jcr) { JCR *djcr; /* possible duplicate job */ JOBRES *job = jcr->res.job; bool cancel_dup = false; bool cancel_me = false; /* * See if AllowDuplicateJobs is set or * if duplicate checking is disabled for this job. */ if (job->AllowDuplicateJobs || jcr->IgnoreDuplicateJobChecking) { return true; } Dmsg0(800, "Enter allow_duplicate_job\n"); /* * After this point, we do not want to allow any duplicate * job to run. */ foreach_jcr(djcr) { if (jcr == djcr || djcr->JobId == 0) { continue; /* do not cancel this job or consoles */ } /* * See if this Job has the IgnoreDuplicateJobChecking flag set, ignore it * for any checking against other jobs. */ if (djcr->IgnoreDuplicateJobChecking) { continue; } if (bstrcmp(job->name(), djcr->res.job->name())) { if (job->DuplicateJobProximity > 0) { utime_t now = (utime_t)time(NULL); if ((now - djcr->start_time) > job->DuplicateJobProximity) { continue; /* not really a duplicate */ } } if (job->CancelLowerLevelDuplicates && djcr->getJobType() == 'B' && jcr->getJobType() == 'B') { switch (jcr->getJobLevel()) { case L_FULL: if (djcr->getJobLevel() == L_DIFFERENTIAL || djcr->getJobLevel() == L_INCREMENTAL) { cancel_dup = true; } break; case L_DIFFERENTIAL: if (djcr->getJobLevel() == L_INCREMENTAL) { cancel_dup = true; } if (djcr->getJobLevel() == L_FULL) { cancel_me = true; } break; case L_INCREMENTAL: if (djcr->getJobLevel() == L_FULL || djcr->getJobLevel() == L_DIFFERENTIAL) { cancel_me = true; } } /* * cancel_dup will be done below */ if (cancel_me) { /* Zap current job */ jcr->setJobStatus(JS_Canceled); Jmsg(jcr, M_FATAL, 0, _("JobId %d already running. Duplicate job not allowed.\n"), djcr->JobId); break; /* get out of foreach_jcr */ } } /* * Cancel one of the two jobs (me or dup) * 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_dup = true; /* cancel queued duplicate */ break; default: break; } } if (cancel_dup || job->CancelRunningDuplicates) { /* * Zap the duplicated job djcr */ UAContext *ua = new_ua_context(jcr); Jmsg(jcr, M_INFO, 0, _("Cancelling duplicate JobId=%d.\n"), djcr->JobId); cancel_job(ua, djcr); bmicrosleep(0, 500000); djcr->setJobStatus(JS_Canceled); cancel_job(ua, djcr); free_ua_context(ua); Dmsg2(800, "Cancel dup %p JobId=%d\n", djcr, djcr->JobId); } else { /* * Zap current job */ jcr->setJobStatus(JS_Canceled); Jmsg(jcr, M_FATAL, 0, _("JobId %d already running. Duplicate job not allowed.\n"), djcr->JobId); Dmsg2(800, "Cancel me %p JobId=%d\n", jcr, jcr->JobId); } Dmsg4(800, "curJobId=%d use_cnt=%d dupJobId=%d use_cnt=%d\n", jcr->JobId, jcr->use_count(), djcr->JobId, djcr->use_count()); break; /* did our work, get out of foreach loop */ } } endeach_jcr(djcr); return true; }