From e087a0acbbf775b335d7cefdb0246e71bd8d0dc2 Mon Sep 17 00:00:00 2001 From: Thomas Lohman Date: Thu, 14 Jan 2016 11:27:24 +0100 Subject: [PATCH] Implement MaxVirtualFullInterval --- bacula/src/dird/backup.c | 25 +++++++++++++++++++------ bacula/src/dird/dird_conf.h | 3 +++ bacula/src/dird/fd_cmds.c | 17 +++++++++++++++-- bacula/src/dird/job.c | 12 ++++++++++++ bacula/src/dird/jobq.c | 2 ++ bacula/src/dird/run_conf.c | 4 ++++ bacula/src/dird/scheduler.c | 4 ++++ bacula/src/dird/vbackup.c | 24 +++++++----------------- bacula/src/jcr.h | 2 ++ 9 files changed, 68 insertions(+), 25 deletions(-) diff --git a/bacula/src/dird/backup.c b/bacula/src/dird/backup.c index 932751bf68..6e4c7c88cd 100644 --- a/bacula/src/dird/backup.c +++ b/bacula/src/dird/backup.c @@ -64,19 +64,19 @@ bool do_backup_init(JCR *jcr) /* Make local copy */ jcr->RescheduleIncompleteJobs = jcr->job->RescheduleIncompleteJobs; - if (jcr->is_JobLevel(L_VIRTUAL_FULL)) { - return do_vbackup_init(jcr); - } - free_rstorage(jcr); /* we don't read so release */ - if (!get_or_create_fileset_record(jcr)) { + Dmsg1(100, "JobId=%d no FileSet\n", (int)jcr->JobId); return false; } /* * Get definitive Job level and since time + * unless it's a virtual full. In that case + * it is not needed. */ - get_level_since_time(jcr, jcr->since, sizeof(jcr->since)); + if (!jcr->is_JobLevel(L_VIRTUAL_FULL)) { + get_level_since_time(jcr, jcr->since, sizeof(jcr->since)); + } apply_pool_overrides(jcr); @@ -86,9 +86,22 @@ bool do_backup_init(JCR *jcr) jcr->jr.PoolId = get_or_create_pool_record(jcr, jcr->pool->name()); if (jcr->jr.PoolId == 0) { + Dmsg1(100, "JobId=%d no PoolId\n", (int)jcr->JobId); + Jmsg(jcr, M_FATAL, 0, _("Could not get or create a Pool record.\n")); return false; } + /* + * If we are a virtual full job or got upgraded to one + * then we divert at this point and call the virtual full + * backup init method + */ + if (jcr->is_JobLevel(L_VIRTUAL_FULL)) { + return do_vbackup_init(jcr); + } + + free_rstorage(jcr); /* we don't read so release */ + /* If pool storage specified, use it instead of job storage */ copy_wstorage(jcr, jcr->pool->storage, _("Pool resource")); diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index b1101bd04c..aeced6c9b3 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -403,6 +403,7 @@ public: utime_t MaxRunSchedTime; /* max run time in seconds from Scheduled time*/ utime_t RescheduleInterval; /* Reschedule interval */ utime_t MaxFullInterval; /* Maximum time interval between Fulls */ + utime_t MaxVirtualFullInterval; /* Maximum time interval between Virtual Fulls */ utime_t MaxDiffInterval; /* Maximum time interval between Diffs */ utime_t DuplicateJobProximity; /* Permitted time between duplicicates */ utime_t SnapRetention; /* Snapshot retention period in seconds */ @@ -420,6 +421,7 @@ public: POOL *pool; /* Where is media -- Media Pool */ POOL *next_pool; /* Next Pool for Copy/Migrate/VirtualFull */ POOL *full_pool; /* Pool for Full backups */ + POOL *vfull_pool; /* Pool for Virtual Full backups */ POOL *inc_pool; /* Pool for Incremental backups */ POOL *diff_pool; /* Pool for Differental backups */ char *selection_pattern; @@ -676,6 +678,7 @@ public: POOL *pool; /* Pool override */ POOL *next_pool; /* Next pool override */ POOL *full_pool; /* Pool override */ + POOL *vfull_pool; /* Pool override */ POOL *inc_pool; /* Pool override */ POOL *diff_pool; /* Pool override */ STORE *storage; /* Storage override */ diff --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c index 84e198de8b..c1ebd57c0f 100644 --- a/bacula/src/dird/fd_cmds.c +++ b/bacula/src/dird/fd_cmds.c @@ -171,6 +171,7 @@ void get_level_since_time(JCR *jcr, char *since, int since_len) int JobLevel; bool have_full; bool do_full = false; + bool do_vfull = false; bool do_diff = false; utime_t now; utime_t last_full_time = 0; @@ -236,10 +237,15 @@ void get_level_since_time(JCR *jcr, char *since, int since_len) do_diff = ((now - last_diff_time) >= jcr->job->MaxDiffInterval); Dmsg2(50, "do_diff=%d diffInter=%lld\n", do_diff, jcr->job->MaxDiffInterval); } - /* Note, do_full takes precedence over do_diff */ + /* Note, do_full takes precedence over do_vfull and do_diff */ if (have_full && jcr->job->MaxFullInterval > 0) { do_full = ((now - last_full_time) >= jcr->job->MaxFullInterval); } + else + if (have_full && jcr->job->MaxVirtualFullInterval > 0) { + do_vfull = ((now - last_full_time) >= jcr->job->MaxVirtualFullInterval); + } + free_pool_memory(stime); if (do_full) { @@ -249,7 +255,14 @@ void get_level_since_time(JCR *jcr, char *since, int since_len) bsnprintf(since, since_len, _(" (upgraded from %s)"), level_to_str(jcr->getJobLevel())); jcr->setJobLevel(jcr->jr.JobLevel = L_FULL); - } else if (do_diff) { + } else if (do_vfull) { + /* No recent Full job found, and MaxVirtualFull is set so upgrade this one to Virtual Full */ + Jmsg(jcr, M_INFO, 0, "%s", db_strerror(jcr->db)); + Jmsg(jcr, M_INFO, 0, _("No prior or suitable Full backup found in catalog. Doing Virtual FULL backup.\n")); + bsnprintf(since, since_len, _(" (upgraded from %s)"), + level_to_str(jcr->getJobLevel())); + jcr->setJobLevel(jcr->jr.JobLevel = L_VIRTUAL_FULL); + } else if (do_diff) { /* No recent diff job found, so upgrade this one to Diff */ Jmsg(jcr, M_INFO, 0, _("No prior or suitable Differential backup found in catalog. Doing Differential backup.\n")); bsnprintf(since, since_len, _(" (upgraded from %s)"), diff --git a/bacula/src/dird/job.c b/bacula/src/dird/job.c index 2290a2bf1a..9ed9c27083 100644 --- a/bacula/src/dird/job.c +++ b/bacula/src/dird/job.c @@ -1175,6 +1175,17 @@ void apply_pool_overrides(JCR *jcr) } } break; + case L_VIRTUAL_FULL: + if (jcr->vfull_pool) { + jcr->pool = jcr->vfull_pool; + pool_override = true; + if (jcr->run_vfull_pool_override) { + pm_strcpy(jcr->pool_source, _("Run VFullPool override")); + } else { + pm_strcpy(jcr->pool_source, _("Job VFullPool override")); + } + } + break; case L_INCREMENTAL: if (jcr->inc_pool) { jcr->pool = jcr->inc_pool; @@ -1543,6 +1554,7 @@ void set_jcr_defaults(JCR *jcr, JOB *job) pm_strcpy(jcr->next_pool_source, _("Job Pool's NextPool resource")); } jcr->full_pool = job->full_pool; + jcr->vfull_pool = job->vfull_pool; jcr->inc_pool = job->inc_pool; jcr->diff_pool = job->diff_pool; if (job->pool->catalog) { diff --git a/bacula/src/dird/jobq.c b/bacula/src/dird/jobq.c index 11f586ff58..95168218b4 100644 --- a/bacula/src/dird/jobq.c +++ b/bacula/src/dird/jobq.c @@ -733,7 +733,9 @@ static bool reschedule_job(JCR *jcr, jobq_t *jq, jobq_item_t *je) njcr->next_pool = jcr->next_pool; njcr->run_next_pool_override = jcr->run_next_pool_override; njcr->full_pool = jcr->full_pool; + njcr->vfull_pool = jcr->vfull_pool; njcr->run_full_pool_override = jcr->run_full_pool_override; + njcr->run_vfull_pool_override = jcr->run_vfull_pool_override; njcr->inc_pool = jcr->inc_pool; njcr->run_inc_pool_override = jcr->run_inc_pool_override; njcr->diff_pool = jcr->diff_pool; diff --git a/bacula/src/dird/run_conf.c b/bacula/src/dird/run_conf.c index 880e4151c3..c4a41578a6 100644 --- a/bacula/src/dird/run_conf.c +++ b/bacula/src/dird/run_conf.c @@ -259,6 +259,7 @@ void store_run(LEX *lc, RES_ITEM *item, int index, int pass) case 'P': /* Pool */ case 'N': /* NextPool */ case 'f': /* FullPool */ + case 'v': /* VFullPool */ case 'i': /* IncPool */ case 'd': /* DifPool */ token = lex_get_token(lc, T_NAME); @@ -279,6 +280,9 @@ void store_run(LEX *lc, RES_ITEM *item, int index, int pass) case 'f': lrun.full_pool = (POOL *)res; break; + case 'v': + lrun.vfull_pool = (POOL *)res; + break; case 'i': lrun.inc_pool = (POOL *)res; break; diff --git a/bacula/src/dird/scheduler.c b/bacula/src/dird/scheduler.c index 856fdf84b6..5108142a2d 100644 --- a/bacula/src/dird/scheduler.c +++ b/bacula/src/dird/scheduler.c @@ -204,6 +204,10 @@ again: jcr->full_pool = run->full_pool; /* override full pool */ jcr->run_full_pool_override = true; } + if (run->vfull_pool) { + jcr->vfull_pool = run->vfull_pool; /* override virtual full pool */ + jcr->run_vfull_pool_override = true; + } if (run->inc_pool) { jcr->inc_pool = run->inc_pool; /* override inc pool */ jcr->run_inc_pool_override = true; diff --git a/bacula/src/dird/vbackup.c b/bacula/src/dird/vbackup.c index 07ec06c974..09ab291a85 100644 --- a/bacula/src/dird/vbackup.c +++ b/bacula/src/dird/vbackup.c @@ -50,23 +50,13 @@ void vbackup_cleanup(JCR *jcr, int TermCode); bool do_vbackup_init(JCR *jcr) { - if (!get_or_create_fileset_record(jcr)) { - Dmsg1(dbglevel, "JobId=%d no FileSet\n", (int)jcr->JobId); - return false; - } - - apply_pool_overrides(jcr); - - if (!allow_duplicate_job(jcr)) { - return false; - } + /* + * if the read pool has not been allocated yet due to the job + * being upgraded to a virtual full then allocate it now + */ + if (!jcr->rpool_source) + jcr->rpool_source = get_pool_memory(PM_MESSAGE); - jcr->jr.PoolId = get_or_create_pool_record(jcr, jcr->pool->name()); - if (jcr->jr.PoolId == 0) { - Dmsg1(dbglevel, "JobId=%d no PoolId\n", (int)jcr->JobId); - Jmsg(jcr, M_FATAL, 0, _("Could not get or create a Pool record.\n")); - return false; - } /* * Note, at this point, pool is the pool for this job. We * transfer it to rpool (read pool), and a bit later, @@ -76,7 +66,7 @@ bool do_vbackup_init(JCR *jcr) jcr->rpool = jcr->pool; /* save read pool */ pm_strcpy(jcr->rpool_source, jcr->pool_source); - /* If pool storage specified, use it for restore */ + /* If pool storage specified, use it for virtual full */ copy_rstorage(jcr, jcr->pool->storage, _("Pool resource")); Dmsg2(dbglevel, "Read pool=%s (From %s)\n", jcr->rpool->name(), jcr->rpool_source); diff --git a/bacula/src/jcr.h b/bacula/src/jcr.h index 154b62cbc4..f8bf739c54 100644 --- a/bacula/src/jcr.h +++ b/bacula/src/jcr.h @@ -331,6 +331,7 @@ public: POOL *next_pool; /* Next pool override */ POOL *rpool; /* Read pool. Used only in migration */ POOL *full_pool; /* Full backup pool resource */ + POOL *vfull_pool; /* Virtual Full backup pool resource */ POOL *inc_pool; /* Incremental backup pool resource */ POOL *diff_pool; /* Differential backup pool resource */ FILESET *fileset; /* FileSet resource */ @@ -395,6 +396,7 @@ public: bool cmdline_next_pool_override; /* Next pool is overridden */ bool run_next_pool_override; /* Next pool is overridden */ bool run_full_pool_override; + bool run_vfull_pool_override; bool run_inc_pool_override; bool run_diff_pool_override; bool sd_canceled; /* set if SD canceled */ -- 2.39.5