]> git.sur5r.net Git - bacula/bacula/commitdiff
Implement MaxVirtualFullInterval
authorThomas Lohman <thomasl@mtl.mit.edu>
Thu, 14 Jan 2016 10:27:24 +0000 (11:27 +0100)
committerKern Sibbald <kern@sibbald.com>
Thu, 14 Jan 2016 10:27:24 +0000 (11:27 +0100)
bacula/src/dird/backup.c
bacula/src/dird/dird_conf.h
bacula/src/dird/fd_cmds.c
bacula/src/dird/job.c
bacula/src/dird/jobq.c
bacula/src/dird/run_conf.c
bacula/src/dird/scheduler.c
bacula/src/dird/vbackup.c
bacula/src/jcr.h

index 932751bf68e421fb1f74d43e9eaa52bc49c2020a..6e4c7c88cd5ee795e6d873b1e33925a76d4f40ce 100644 (file)
@@ -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"));
 
index b1101bd04cfd91b63b8fa2918497485885b79756..aeced6c9b3d6b7d894df16ebde313f1f9a274565 100644 (file)
@@ -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 */
index 84e198de8b52b67b0fcc95e49b414d8e57d3c940..c1ebd57c0fc4946276b20cd2d4691c1f852519f6 100644 (file)
@@ -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)"),
index 2290a2bf1aa7f3a7ba39abea61cc56326986b328..9ed9c27083800a0e2bb744e0382249e03939c9eb 100644 (file)
@@ -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) {
index 11f586ff582ff40451a942f29a3d020bd4a4ffca..95168218b45ac94c26f22b8ea03e06e80b31a820 100644 (file)
@@ -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;
index 880e4151c3b2565316d685f6eeb1d5dc2c33ad61..c4a41578a6101cac935de83821d9eef7e72c4465 100644 (file)
@@ -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;
index 856fdf84b6d6592f8de032b871c18b700dbc22db..5108142a2d3a6b11e174c063588f7ebd40278225 100644 (file)
@@ -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;
index 07ec06c9741821a6963384d2186d4fa660afdce1..09ab291a85d78e73f141bf24c142eaa293b32617 100644 (file)
@@ -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);
index 154b62cbc4a315026562398821d1f0a9e335697b..f8bf739c548efdfba77ad3305b1284f3c24e91c8 100644 (file)
@@ -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 */