Skip to content

Commit

Permalink
Added support for Max VirtualFull Interval and Virtual Full Pool over…
Browse files Browse the repository at this point in the history
…ride.

Implement a Max Virtual Full Interval analog to the existing Max Full
Interval and a Virtual Full Backup Pool analog to the existing Full
Backup Pool.

Fixes #239: Max VirtualFull Interval like Max Full Interval
  • Loading branch information
Marco van Wieringen committed Feb 17, 2015
1 parent b8ef82e commit 0aa3983
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 8 deletions.
8 changes: 8 additions & 0 deletions src/dird/dird_conf.c
Expand Up @@ -305,6 +305,7 @@ RES_ITEM job_items[] = {
{ "Storage", CFG_TYPE_ALIST_RES, ITEM(res_job.storage), R_STORAGE, 0, NULL },
{ "Pool", CFG_TYPE_RES, ITEM(res_job.pool), R_POOL, CFG_ITEM_REQUIRED, NULL },
{ "FullBackupPool", CFG_TYPE_RES, ITEM(res_job.full_pool), R_POOL, 0, NULL },
{ "VirtualFullBackupPool", CFG_TYPE_RES, ITEM(res_job.vfull_pool), R_POOL, 0, NULL },
{ "IncrementalBackupPool", CFG_TYPE_RES, ITEM(res_job.inc_pool), R_POOL, 0, NULL },
{ "DifferentialBackupPool", CFG_TYPE_RES, ITEM(res_job.diff_pool), R_POOL, 0, NULL },
{ "NextPool", CFG_TYPE_RES, ITEM(res_job.next_pool), R_POOL, 0, NULL },
Expand Down Expand Up @@ -340,6 +341,7 @@ RES_ITEM job_items[] = {
{ "MaxWaitTime", CFG_TYPE_TIME, ITEM(res_job.MaxWaitTime), 0, 0, NULL },
{ "MaxStartDelay", CFG_TYPE_TIME, ITEM(res_job.MaxStartDelay), 0, 0, NULL },
{ "MaxFullInterval", CFG_TYPE_TIME, ITEM(res_job.MaxFullInterval), 0, 0, NULL },
{ "MaxVirtualFullInterval", CFG_TYPE_TIME, ITEM(res_job.MaxVFullInterval), 0, 0, NULL },
{ "MaxDiffInterval", CFG_TYPE_TIME, ITEM(res_job.MaxDiffInterval), 0, 0, NULL },
{ "PrefixLinks", CFG_TYPE_BOOL, ITEM(res_job.PrefixLinks), 0, CFG_ITEM_DEFAULT, "false" },
{ "PruneJobs", CFG_TYPE_BOOL, ITEM(res_job.PruneJobs), 0, CFG_ITEM_DEFAULT, "false" },
Expand Down Expand Up @@ -868,6 +870,11 @@ static inline void print_config_run(RES_ITEM *item, POOL_MEM &cfg_str)
pm_strcat(run_str, temp.c_str());
}

if (run->vfull_pool) {
Mmsg(temp, "virtualfullpool=\"%s\" ", run->vfull_pool->name());
pm_strcat(run_str, temp.c_str());
}

if (run->inc_pool) {
Mmsg(temp, "incrementalpool=\"%s\" ", run->inc_pool->name());
pm_strcat(run_str, temp.c_str());
Expand Down Expand Up @@ -2120,6 +2127,7 @@ void save_resource(int type, RES_ITEM *items, int pass)
res->res_job.base = res_all.res_job.base;
res->res_job.pool = res_all.res_job.pool;
res->res_job.full_pool = res_all.res_job.full_pool;
res->res_job.vfull_pool = res_all.res_job.vfull_pool;
res->res_job.inc_pool = res_all.res_job.inc_pool;
res->res_job.diff_pool = res_all.res_job.diff_pool;
res->res_job.next_pool = res_all.res_job.next_pool;
Expand Down
3 changes: 3 additions & 0 deletions src/dird/dird_conf.h
Expand Up @@ -392,6 +392,7 @@ class JOBRES : public BRSRES {
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 MaxVFullInterval; /* Maximum time interval between Virtual Fulls */
utime_t MaxDiffInterval; /* Maximum time interval between Diffs */
utime_t DuplicateJobProximity; /* Permitted time between duplicicates */
int64_t spool_size; /* Size of spool file for this job */
Expand All @@ -407,6 +408,7 @@ class JOBRES : public BRSRES {
alist *storage; /* Where is device -- list of Storage to be used */
POOLRES *pool; /* Where is media -- Media Pool */
POOLRES *full_pool; /* Pool for Full backups */
POOLRES *vfull_pool; /* Pool for Virtual Full backups */
POOLRES *inc_pool; /* Pool for Incremental backups */
POOLRES *diff_pool; /* Pool for Differental backups */
POOLRES *next_pool; /* Next Pool for Copy/Migration Jobs and Virtual backups */
Expand Down Expand Up @@ -603,6 +605,7 @@ class RUNRES: public BRSRES {

POOLRES *pool; /* Pool override */
POOLRES *full_pool; /* Full Pool override */
POOLRES *vfull_pool; /* Virtual Full Pool override */
POOLRES *inc_pool; /* Incr Pool override */
POOLRES *diff_pool; /* Diff Pool override */
POOLRES *next_pool; /* Next Pool override */
Expand Down
50 changes: 42 additions & 8 deletions src/dird/job.c
Expand Up @@ -911,6 +911,7 @@ bool get_level_since_time(JCR *jcr)
int JobLevel;
bool have_full;
bool do_full = false;
bool do_vfull = false;
bool do_diff = false;
bool pool_updated = false;
utime_t now;
Expand Down Expand Up @@ -1003,10 +1004,12 @@ bool get_level_since_time(JCR *jcr)
}

/*
* Note, do_full takes precedence over do_diff
* Note, do_full takes precedence over do_vfull and do_diff
*/
if (have_full && jcr->res.job->MaxFullInterval > 0) {
do_full = ((now - last_full_time) >= jcr->res.job->MaxFullInterval);
} else if (have_full && jcr->res.job->MaxVFullInterval > 0) {
do_vfull = ((now - last_full_time) >= jcr->res.job->MaxVFullInterval);
}
free_pool_memory(stime);

Expand All @@ -1019,7 +1022,24 @@ bool get_level_since_time(JCR *jcr)
bsnprintf(jcr->since, sizeof(jcr->since), _(" (upgraded from %s)"), level_to_str(JobLevel));
jcr->setJobLevel(jcr->jr.JobLevel = L_FULL);
pool_updated = true;
} 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(jcr->since, sizeof(jcr->since), _(" (upgraded from %s)"), level_to_str(jcr->getJobLevel()));
jcr->setJobLevel(jcr->jr.JobLevel = L_VIRTUAL_FULL);
pool_updated = true;

/*
* If we get upgraded to a Virtual Full we will be using a read pool so make sure we have a rpool_source.
*/
if (!jcr->res.rpool_source) {
jcr->res.rpool_source = get_pool_memory(PM_MESSAGE);
pm_strcpy(jcr->res.rpool_source, _("unknown source"));
}
} else if (do_diff) {
/*
* No recent diff job found, so upgrade this one to Diff
*/
Expand Down Expand Up @@ -1080,6 +1100,7 @@ void apply_pool_overrides(JCR *jcr, bool force)
*/
if (jcr->res.run_pool_override &&
!jcr->res.run_full_pool_override &&
!jcr->res.run_vfull_pool_override &&
!jcr->res.run_inc_pool_override &&
!jcr->res.run_diff_pool_override) {
pm_strcpy(jcr->res.pool_source, _("Run Pool override"));
Expand All @@ -1095,10 +1116,23 @@ void apply_pool_overrides(JCR *jcr, bool force)
pool_override = true;
if (jcr->res.run_full_pool_override) {
pm_strcpy(jcr->res.pool_source, _("Run FullPool override"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), _("Run FullPool override\n"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), "Run FullPool override\n");
} else {
pm_strcpy(jcr->res.pool_source, _("Job FullPool override"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), _("Job FullPool override\n"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), "Job FullPool override\n");
}
}
break;
case L_VIRTUAL_FULL:
if (jcr->res.vfull_pool) {
jcr->res.pool = jcr->res.vfull_pool;
pool_override = true;
if (jcr->res.run_vfull_pool_override) {
pm_strcpy(jcr->res.pool_source, _("Run VFullPool override"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.vfull_pool->name(), "Run VFullPool override\n");
} else {
pm_strcpy(jcr->res.pool_source, _("Job VFullPool override"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.vfull_pool->name(), "Job VFullPool override\n");
}
}
break;
Expand All @@ -1108,10 +1142,10 @@ void apply_pool_overrides(JCR *jcr, bool force)
pool_override = true;
if (jcr->res.run_inc_pool_override) {
pm_strcpy(jcr->res.pool_source, _("Run IncPool override"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), _("Run IncPool override\n"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), "Run IncPool override\n");
} else {
pm_strcpy(jcr->res.pool_source, _("Job IncPool override"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), _("Job IncPool override\n"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), "Job IncPool override\n");
}
}
break;
Expand All @@ -1121,10 +1155,10 @@ void apply_pool_overrides(JCR *jcr, bool force)
pool_override = true;
if (jcr->res.run_diff_pool_override) {
pm_strcpy(jcr->res.pool_source, _("Run DiffPool override"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), _("Run DiffPool override\n"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), "Run DiffPool override\n");
} else {
pm_strcpy(jcr->res.pool_source, _("Job DiffPool override"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), _("Job DiffPool override\n"));
Dmsg2(100, "Pool set to '%s' because of %s", jcr->res.full_pool->name(), "Job DiffPool override\n");
}
}
break;
Expand Down
4 changes: 4 additions & 0 deletions src/dird/run_conf.c
Expand Up @@ -236,6 +236,7 @@ void store_run(LEX *lc, RES_ITEM *item, int index, int pass)
break;
case 'P': /* Pool */
case 'f': /* FullPool */
case 'v': /* VFullPool */
case 'i': /* IncPool */
case 'd': /* DiffPool */
case 'n': /* NextPool */
Expand All @@ -254,6 +255,9 @@ void store_run(LEX *lc, RES_ITEM *item, int index, int pass)
case 'f':
lrun.full_pool = (POOLRES *)res;
break;
case 'v':
lrun.vfull_pool = (POOLRES *)res;
break;
case 'i':
lrun.inc_pool = (POOLRES *)res;
break;
Expand Down
17 changes: 17 additions & 0 deletions src/dird/scheduler.c
Expand Up @@ -200,47 +200,64 @@ JCR *wait_for_next_job(char *one_shot_job_to_run)
if (run->level) {
jcr->setJobLevel(run->level); /* override run level */
}

if (run->pool) {
jcr->res.pool = run->pool; /* override pool */
jcr->res.run_pool_override = true;
}

if (run->full_pool) {
jcr->res.full_pool = run->full_pool; /* override full pool */
jcr->res.run_full_pool_override = true;
}

if (run->vfull_pool) {
jcr->res.vfull_pool = run->vfull_pool; /* override virtual full pool */
jcr->res.run_vfull_pool_override = true;
}

if (run->inc_pool) {
jcr->res.inc_pool = run->inc_pool; /* override inc pool */
jcr->res.run_inc_pool_override = true;
}

if (run->diff_pool) {
jcr->res.diff_pool = run->diff_pool; /* override diff pool */
jcr->res.run_diff_pool_override = true;
}

if (run->next_pool) {
jcr->res.next_pool = run->next_pool; /* override next pool */
jcr->res.run_next_pool_override = true;
}

if (run->storage) {
USTORERES store;
store.store = run->storage;
pm_strcpy(store.store_source, _("run override"));
set_rwstorage(jcr, &store); /* override storage */
}

if (run->msgs) {
jcr->res.messages = run->msgs; /* override messages */
}

if (run->Priority) {
jcr->JobPriority = run->Priority;
}

if (run->spool_data_set) {
jcr->spool_data = run->spool_data;
}

if (run->accurate_set) {
jcr->accurate = run->accurate; /* overwrite accurate mode */
}

if (run->MaxRunSchedTime_set) {
jcr->MaxRunSchedTime = run->MaxRunSchedTime;
}

Dmsg0(dbglvl, "Leave wait_for_next_job()\n");
return jcr;
}
Expand Down
2 changes: 2 additions & 0 deletions src/include/jcr.h
Expand Up @@ -220,6 +220,7 @@ struct RESOURCES {
POOLRES *pool; /* Pool resource = write for migration */
POOLRES *rpool; /* Read pool. Used only in migration */
POOLRES *full_pool; /* Full backup pool resource */
POOLRES *vfull_pool; /* Virtual Full backup pool resource */
POOLRES *inc_pool; /* Incremental backup pool resource */
POOLRES *diff_pool; /* Differential backup pool resource */
POOLRES *next_pool; /* Next Pool used for migration/copy and virtual backup */
Expand All @@ -234,6 +235,7 @@ struct RESOURCES {
POOLMEM *catalog_source; /* Where catalog came from */
bool run_pool_override; /* Pool override was given on run cmdline */
bool run_full_pool_override; /* Full pool override was given on run cmdline */
bool run_vfull_pool_override; /* Virtual Full pool override was given on run cmdline */
bool run_inc_pool_override; /* Incremental pool override was given on run cmdline */
bool run_diff_pool_override; /* Differential pool override was given on run cmdline */
bool run_next_pool_override; /* Next pool override was given on run cmdline */
Expand Down

0 comments on commit 0aa3983

Please sign in to comment.