]> git.sur5r.net Git - bacula/bacula/commitdiff
Integrate patch into latest version, which fixes bug #1882
authorKern Sibbald <kern@sibbald.com>
Wed, 30 Dec 2015 18:19:27 +0000 (19:19 +0100)
committerKern Sibbald <kern@sibbald.com>
Wed, 30 Dec 2015 18:19:27 +0000 (19:19 +0100)
bacula/src/cats/bdb.h
bacula/src/cats/protos.h
bacula/src/cats/sql_find.c
bacula/src/dird/fd_cmds.c

index 717f0dab9068ff576046c09e7da79ebdadc103a5..87b260be03158c806e380e255db069a0b68bcf0d 100644 (file)
@@ -119,6 +119,7 @@ public:
    int bdb_delete_snapshot_record(JCR *jcr, SNAPSHOT_DBR *sr);
 
    /* sql_find.c */
+   bool bdb_find_last_job_end_time(JCR *jcr, JOB_DBR *jr, POOLMEM **etime, char *job);
    bool bdb_find_last_job_start_time(JCR *jcr, JOB_DBR *jr, POOLMEM **stime, char *job, int JobLevel);
    bool bdb_find_job_start_time(JCR *jcr, JOB_DBR *jr, POOLMEM **stime, char *job);
    bool bdb_find_last_jobid(JCR *jcr, const char *Name, JOB_DBR *jr);
index 5a6a726c95814055ac78520ec2178f980eba7ebb..61c9119c18995571960f024e847c5da5910bc273 100644 (file)
@@ -163,6 +163,8 @@ void bdb_free_restoreobject_record(JCR *jcr, ROBJECT_DBR *rr);
 
 
 /* sql_find.c */
+#define db_find_last_job_end_time(jcr, mdb, jr, etime, job) \
+           mdb->bdb_find_last_job_end_time(jcr, jr, etime, job)
 #define db_find_last_job_start_time(jcr, mdb, jr, stime, job, JobLevel) \
            mdb->bdb_find_last_job_start_time(jcr, jr, stime, job, JobLevel)
 #define db_find_job_start_time(jcr, mdb, jr, stime, job) \
index 16c8c3e77016c70fa47a27d1a75d9ab239f2a5a1..0a0878cd21ca64d6877dbb45c902cc04cd9e509d 100644 (file)
  * -----------------------------------------------------------------------
  */
 
+/*
+ * Find the most recent successful real end time for a job given.
+ *
+ *  RealEndTime is returned in etime
+ *  Job name is returned in job (MAX_NAME_LENGTH)
+ *
+ * Returns: false on failure
+ *          true  on success, jr is unchanged, but etime and job are set
+ */
+bool BDB::bdb_find_last_job_end_time(JCR *jcr, JOB_DBR *jr, POOLMEM **etime, 
+          char *job)
+{
+   SQL_ROW row;
+   char ed1[50], ed2[50];
+   char esc_name[MAX_ESCAPE_NAME_LENGTH];
+
+   bdb_lock();
+   bdb_escape_string(jcr, esc_name, jr->Name, strlen(jr->Name));
+   pm_strcpy(etime, "0000-00-00 00:00:00");   /* default */
+   job[0] = 0;
+
+   Mmsg(cmd,
+        "SELECT RealEndTime, Job FROM Job WHERE JobStatus IN ('T','W') AND Type='%c' AND "
+        "Level IN ('%c','%c','%c') AND Name='%s' AND ClientId=%s AND FileSetId=%s "
+        "ORDER BY RealEndTime DESC LIMIT 1", jr->JobType, 
+        L_FULL, L_DIFFERENTIAL, L_INCREMENTAL, esc_name, 
+        edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2));
+
+   if (!QueryDB(jcr, cmd)) {
+      Mmsg2(&errmsg, _("Query error for end time request: ERR=%s\nCMD=%s\n"),
+         sql_strerror(), cmd);
+      goto bail_out;
+   }
+   if ((row = sql_fetch_row()) == NULL) {
+      sql_free_result();
+      Mmsg(errmsg, _("No prior backup Job record found.\n"));
+      goto bail_out;
+   }
+   Dmsg1(100, "Got end time: %s\n", row[0]);
+   pm_strcpy(etime, row[0]);
+   bstrncpy(job, row[1], MAX_NAME_LENGTH);
+
+   sql_free_result();
+   bdb_unlock();
+   return true;
+
+bail_out:
+   bdb_unlock();
+   return false;
+}
+
+
 /*
  * Find job start time if JobId specified, otherwise
  * find last Job start time Incremental and Differential saves.
  *  StartTime is returned in stime
  *  Job name is returned in job (MAX_NAME_LENGTH)
  *
- * Returns: 0 on failure
- *          1 on success, jr is unchanged, but stime and job are set
+ * Returns: false on failure
+ *          true  on success, jr is unchanged, but stime and job are set
  */
 bool BDB::bdb_find_job_start_time(JCR *jcr, JOB_DBR *jr, POOLMEM **stime, char *job)
 {
@@ -208,10 +260,11 @@ bool BDB::bdb_find_failed_job_since(JCR *jcr, JOB_DBR *jr, POOLMEM *stime, int &
 
    /* Differential is since last Full backup */
    Mmsg(cmd,
-"SELECT Level FROM Job WHERE JobStatus NOT IN ('T','W') AND "
-"Type='%c' AND Level IN ('%c','%c') AND Name='%s' AND ClientId=%s "
-"AND FileSetId=%s AND StartTime>'%s' "
-"ORDER BY StartTime DESC LIMIT 1",
+   "SELECT Level FROM Job WHERE JobStatus IN ('%c','%c', '%c', '%c') AND "
+      "Type='%c' AND Level IN ('%c','%c') AND Name='%s' AND ClientId=%s "
+      "AND FileSetId=%s AND StartTime>'%s' "
+      "ORDER BY StartTime DESC LIMIT 1",
+         JS_Canceled, JS_ErrorTerminated, JS_Error, JS_FatalError,
          jr->JobType, L_FULL, L_DIFFERENTIAL, esc_name,
          edit_int64(jr->ClientId, ed1), edit_int64(jr->FileSetId, ed2),
          stime);
index 52d4d7fd51bcd085fb83c8ea2f129133f2c44de8..84e198de8b52b67b0fcc95e49b414d8e57d3c940 100644 (file)
@@ -257,16 +257,33 @@ void get_level_since_time(JCR *jcr, char *since, int since_len)
          jcr->setJobLevel(jcr->jr.JobLevel = L_DIFFERENTIAL);
       } else {
          if (jcr->job->rerun_failed_levels) {
-            if (db_find_failed_job_since(jcr, jcr->db, &jcr->jr,
-                                         jcr->stime, JobLevel)) {
-               Jmsg(jcr, M_INFO, 0, _("Prior failed job found in catalog. Upgrading to %s.\n"),
-                  level_to_str(JobLevel));
-               bsnprintf(since, since_len, _(" (upgraded from %s)"),
-                  level_to_str(jcr->getJobLevel()));
-               jcr->setJobLevel(jcr->jr.JobLevel = JobLevel);
-               jcr->jr.JobId = jcr->JobId;
-               break;
+
+            POOLMEM *etime = get_pool_memory(PM_MESSAGE);
+
+            /* Get the end time of our most recent successfull backup for this job */
+            /* This will be used to see if there have been any failures since then */
+           if (db_find_last_job_end_time(jcr, jcr->db, &jcr->jr, &etime, prev_job)) {
+
+              /* See if there are any failed Differential/Full backups since the completion */
+               /* of our last successful backup for this job                                 */
+               if (db_find_failed_job_since(jcr, jcr->db, &jcr->jr,
+                                         etime, JobLevel)) {
+                 /* If our job is an Incremental and we have a failed job then upgrade.              */
+                 /* If our job is a Differential and the failed job is a Full then upgrade.          */
+                 /* Otherwise there is no reason to upgrade.                                         */
+                if ((jcr->getJobLevel() == L_INCREMENTAL) || 
+                     ((jcr->getJobLevel() == L_DIFFERENTIAL) && (JobLevel == L_FULL))) {
+                    Jmsg(jcr, M_INFO, 0, _("Prior failed job found in catalog. Upgrading to %s.\n"),
+                       level_to_str(JobLevel));
+                    bsnprintf(since, since_len, _(" (upgraded from %s)"),
+                             level_to_str(jcr->getJobLevel()));
+                    jcr->setJobLevel(jcr->jr.JobLevel = JobLevel);
+                    jcr->jr.JobId = jcr->JobId;
+                    break;
+                 }
+               }
             }
+            free_pool_memory(etime);
          }
          bstrncpy(since, _(", since="), since_len);
          bstrncat(since, jcr->stime, since_len);