From: Kern S. <ke...@us...> - 2010-02-12 15:12:56
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Bacula". The branch, master has been updated via f7cd04aad6c697630c5a73d2e45813a436d577de (commit) from d14160dccd6be8913f9d0eb5c6ab0e0723914e2c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f7cd04aad6c697630c5a73d2e45813a436d577de Author: Kern Sibbald <ke...@si...> Date: Fri Feb 12 16:12:19 2010 +0100 First cut at fixing AllowDuplicateJobs bugs ----------------------------------------------------------------------- Summary of changes: diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 18954b8..d58aeaa 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -336,6 +336,7 @@ RES_ITEM job_items[] = { {"accurate", store_bool, ITEM(res_job.accurate), 0,0,0}, {"allowduplicatejobs", store_bool, ITEM(res_job.AllowDuplicateJobs), 0, ITEM_DEFAULT, false}, {"allowhigherduplicates", store_bool, ITEM(res_job.AllowHigherDuplicates), 0, ITEM_DEFAULT, true}, + {"cancellowerlevelduplicates", store_bool, ITEM(res_job.CancelLowerLevelDuplicates), 0, ITEM_DEFAULT, false}, {"cancelqueuedduplicates", store_bool, ITEM(res_job.CancelQueuedDuplicates), 0, ITEM_DEFAULT, false}, {"cancelrunningduplicates", store_bool, ITEM(res_job.CancelRunningDuplicates), 0, ITEM_DEFAULT, false}, {"pluginoptions", store_str, ITEM(res_job.PluginOptions), 0, 0, 0}, diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index f57fe5f..60993d4 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -434,6 +434,7 @@ public: bool accurate; /* Set if it is an accurate backup job */ bool AllowDuplicateJobs; /* Allow duplicate jobs */ bool AllowHigherDuplicates; /* Permit Higher Level */ + bool CancelLowerLevelDuplicates; /* Cancel lower level backup jobs */ bool CancelQueuedDuplicates; /* Cancel queued jobs */ bool CancelRunningDuplicates; /* Cancel Running jobs */ alist *base; /* Base jobs */ diff --git a/bacula/src/dird/job.c b/bacula/src/dird/job.c index 331cfd1..3949cf3 100644 --- a/bacula/src/dird/job.c +++ b/bacula/src/dird/job.c @@ -678,58 +678,97 @@ DBId_t get_or_create_pool_record(JCR *jcr, char *pool_name) bool allow_duplicate_job(JCR *jcr) { JOB *job = jcr->job; - JCR *djcr; /* possible duplicate */ + JCR *djcr; /* possible duplicate job */ if (job->AllowDuplicateJobs) { return true; } - if (!job->AllowHigherDuplicates) { - foreach_jcr(djcr) { - if (jcr == djcr || djcr->JobId == 0) { - continue; /* do not cancel this job or consoles */ + /* + * 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 */ + } + if (strcmp(job->name(), djcr->job->name()) == 0) { + bool cancel_dup = false; + bool cancel_me = true; + if (job->DuplicateJobProximity > 0) { + utime_t now = (utime_t)time(NULL); + if ((now - djcr->start_time) > job->DuplicateJobProximity) { + continue; /* not really a duplicate */ + } } - if (strcmp(job->name(), djcr->job->name()) == 0) { - bool cancel_queued = false; - 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 */ - /* 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=%d.\n"), djcr->JobId); - ua->jcr = djcr; - cancel_job(ua, djcr); - free_ua_context(ua); - Dmsg2(800, "Have cancelled JCR %p JobId=%d\n", djcr, djcr->JobId); - } else { - /* Zap current job */ - Jmsg(jcr, M_FATAL, 0, _("JobId %d already running. Duplicate job not allowed.\n"), - djcr->JobId); + /* + * cancel_dup will be done below + */ + if (cancel_me) { + /* Zap current job */ + Jmsg(jcr, M_FATAL, 0, _("JobId %d already running. Duplicate job not allowed.\n"), + djcr->JobId); + break; /* get out of foreach_jcr */ } - break; /* did our work, get out */ + } + /* 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(djcr); + Jmsg(jcr, M_INFO, 0, _("Cancelling duplicate JobId=%d.\n"), djcr->JobId); + ua->jcr = djcr; + cancel_job(ua, djcr); + free_ua_context(ua); + Dmsg2(800, "Have cancelled JCR %p JobId=%d\n", djcr, djcr->JobId); + } else { + /* Zap current job */ + Jmsg(jcr, M_FATAL, 0, _("JobId %d already running. Duplicate job not allowed.\n"), + djcr->JobId); + } + break; /* did our work, get out of foreach loop */ } - endeach_jcr(djcr); } + endeach_jcr(djcr); + return true; } hooks/post-receive -- Bacula |