]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/backup.c
Make Checksum as default when not using FileSet->Include->Options->BaseJob
[bacula/bacula] / bacula / src / dird / backup.c
index bbbb4460e0a47f2bcfcf74646db68a783f594a72..eb8e9f121751002b5fcf7bb4414b431a5993c143 100644 (file)
@@ -106,7 +106,7 @@ bool do_backup_init(JCR *jcr)
 /* Take all base jobs from job resource and find the
  * last L_BASE jobid.
  */
-static bool get_base_jobids(JCR *jcr, POOLMEM *jobids)
+static bool get_base_jobids(JCR *jcr, db_list_ctx *jobids)
 {
    JOB_DBR jr;
    JOB *job;
@@ -125,18 +125,19 @@ static bool get_base_jobids(JCR *jcr, POOLMEM *jobids)
       db_get_base_jobid(jcr, jcr->db, &jr, &id);
 
       if (id) {
-         if (jobids[0]) {
-            pm_strcat(jobids, ",");
+         if (jobids->count) {
+            pm_strcat(jobids->list, ",");
          }
-         pm_strcat(jobids, edit_uint64(id, str_jobid));
+         pm_strcat(jobids->list, edit_uint64(id, str_jobid));
+         jobids->count++;
       }
    }
 
-   return *jobids != '\0';
+   return jobids->count > 0;
 }
 
 /*
- * Foreach files in currrent list, send "/path/fname\0LStat" to FD
+ * Foreach files in currrent list, send "/path/fname\0LStat\0MD5" to FD
  */
 static int accurate_list_handler(void *ctx, int num_fields, char **row)
 {
@@ -146,17 +147,90 @@ static int accurate_list_handler(void *ctx, int num_fields, char **row)
       return 1;
    }
    
-   if (row[2] > 0) {            /* discard when file_index == 0 */
-      jcr->file_bsock->fsend("%s%s%c%s", row[0], row[1], 0, row[4]); 
+   if (row[2] == 0) {           /* discard when file_index == 0 */
+      return 0;
+   }
+
+   /* sending with checksum */
+   if (jcr->use_accurate_chksum 
+       && num_fields == 6 
+       && row[5][0] /* skip checksum = '0' */
+       && row[5][1])
+   { 
+      jcr->file_bsock->fsend("%s%s%c%s%c%s", 
+                             row[0], row[1], 0, row[4], 0, row[5]); 
+   } else {
+      jcr->file_bsock->fsend("%s%s%c%s", 
+                             row[0], row[1], 0, row[4]); 
    }
    return 0;
 }
 
+/* In this procedure, we check if the current fileset is using checksum
+ * FileSet-> Include-> Options-> Accurate/Verify/BaseJob=checksum
+ * This procedure uses jcr->HasBase, so it must be call after the initialization
+ */
+static bool is_checksum_needed_by_fileset(JCR *jcr)
+{
+   FILESET *f;
+   INCEXE *inc;
+   FOPTS *fopts;
+   bool in_block=false;
+   bool have_basejob_option=false;
+   if (!jcr->job || !jcr->job->fileset) {
+      return false;
+   }
+
+   f = jcr->job->fileset;
+   
+   for (int i=0; i < f->num_includes; i++) { /* Parse all Include {} */
+      inc = f->include_items[i];
+      
+      for (int j=0; j < inc->num_opts; j++) { /* Parse all Options {} */
+         fopts = inc->opts_list[j];
+         
+         for (char *k=fopts->opts; *k ; k++) { /* Try to find one request */
+            switch (*k) {
+            case 'V':           /* verify */
+               in_block = (jcr->get_JobType() == JT_VERIFY); /* not used now */
+               break;
+            case 'J':           /* Basejob keyword */
+               have_basejob_option = in_block = jcr->HasBase;
+               break;
+            case 'C':           /* Accurate keyword */
+               in_block = (jcr->get_JobLevel() != L_FULL);
+               break;
+            case ':':           /* End of keyword */
+               in_block = false;
+               break;
+            case '5':           /* MD5  */
+            case '1':           /* SHA1 */
+               if (in_block) {
+                  Dmsg0(50, "Checksum will be sent to FD\n");
+                  return true;
+               }
+               break;
+            default:
+               break;
+            }
+         }
+      }
+   }
+
+   /* By default for BaseJobs, we send the checksum */
+   if (!have_basejob_option && jcr->HasBase) {
+      return true;
+   }
+   
+   Dmsg0(50, "Checksum will be sent to FD\n");
+   return false;
+}
+
 /*
  * Send current file list to FD
  *    DIR -> FD : accurate files=xxxx
- *    DIR -> FD : /path/to/file\0Lstat
- *    DIR -> FD : /path/to/dir/\0Lstat
+ *    DIR -> FD : /path/to/file\0Lstat\0MD5
+ *    DIR -> FD : /path/to/dir/\0Lstat\0MD5
  *    ...
  *    DIR -> FD : EOD
  */
@@ -164,6 +238,8 @@ bool send_accurate_current_files(JCR *jcr)
 {
    POOL_MEM buf;
    bool ret=true;
+   db_list_ctx jobids;
+   db_list_ctx nb;
 
    if (!jcr->accurate || job_canceled(jcr)) {
       return true;
@@ -172,55 +248,53 @@ bool send_accurate_current_files(JCR *jcr)
    if (jcr->get_JobLevel() == L_BASE) {
       return true;
    }
-
-   POOLMEM *nb = get_pool_memory(PM_FNAME);
-   POOLMEM *jobids = get_pool_memory(PM_FNAME);
-   nb[0] = jobids[0] = '\0';
-
+   
    if (jcr->get_JobLevel() == L_FULL) {
       /* On Full mode, if no previous base job, no accurate things */
-      if (!get_base_jobids(jcr, jobids)) {
+      if (!get_base_jobids(jcr, &jobids)) {
          goto bail_out;
       }
       jcr->HasBase = true;
-      Jmsg(jcr, M_INFO, 0, _("Using BaseJobId(s): %s\n"), jobids);
+      Jmsg(jcr, M_INFO, 0, _("Using BaseJobId(s): %s\n"), jobids.list);
 
    } else {
       /* For Incr/Diff level, we search for older jobs */
-      db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, jobids);
+      db_accurate_get_jobids(jcr, jcr->db, &jcr->jr, &jobids);
 
       /* We are in Incr/Diff, but no Full to build the accurate list... */
-      if (*jobids == 0) {
+      if (jobids.count == 0) {
          ret=false;
          Jmsg(jcr, M_FATAL, 0, _("Cannot find previous jobids.\n"));
          goto bail_out;
       }
    }
 
+   /* Don't send and store the checksum if fileset doesn't require it */
+   jcr->use_accurate_chksum = is_checksum_needed_by_fileset(jcr);
+
    if (jcr->JobId) {            /* display the message only for real jobs */
       Jmsg(jcr, M_INFO, 0, _("Sending Accurate information.\n"));
    }
 
    /* to be able to allocate the right size for htable */
-   Mmsg(buf, "SELECT sum(JobFiles) FROM Job WHERE JobId IN (%s)",jobids);
-   db_sql_query(jcr->db, buf.c_str(), db_get_int_handler, nb);
-   Dmsg2(0, "jobids=%s nb=%s\n", jobids, nb);
-   jcr->file_bsock->fsend("accurate files=%s\n", nb); 
+   Mmsg(buf, "SELECT sum(JobFiles) FROM Job WHERE JobId IN (%s)", jobids.list);
+   db_sql_query(jcr->db, buf.c_str(), db_list_handler, &nb);
+   Dmsg2(200, "jobids=%s nb=%s\n", jobids.list, nb.list);
+   jcr->file_bsock->fsend("accurate files=%s\n", nb.list); 
 
    if (!db_open_batch_connexion(jcr, jcr->db)) {
-      ret = false;
-      Jmsg0(jcr, M_FATAL, 0, "Can't get dedicate sql connexion");
-      goto bail_out;
+      Jmsg0(jcr, M_FATAL, 0, "Can't get batch sql connexion");
+      return false;
    }
    
    if (jcr->HasBase) {
-      jcr->nb_base_files = str_to_int64(nb);
-      db_create_base_file_list(jcr, jcr->db, jobids);
+      jcr->nb_base_files = str_to_int64(nb.list);
+      db_create_base_file_list(jcr, jcr->db, jobids.list);
       db_get_base_file_list(jcr, jcr->db, 
                             accurate_list_handler, (void *)jcr);
 
    } else {
-      db_get_file_list(jcr, jcr->db_batch, jobids, 
+      db_get_file_list(jcr, jcr->db_batch, jobids.list
                        accurate_list_handler, (void *)jcr);
    } 
 
@@ -229,9 +303,6 @@ bool send_accurate_current_files(JCR *jcr)
    jcr->file_bsock->signal(BNET_EOD);
 
 bail_out:
-   free_pool_memory(jobids);
-   free_pool_memory(nb);
-
    return ret;
 }
 
@@ -514,6 +585,7 @@ void backup_cleanup(JCR *jcr, int TermCode)
    CLIENT_DBR cr;
    double kbps, compression;
    utime_t RunTime;
+   POOL_MEM base_info;
 
    if (jcr->get_JobLevel() == L_VIRTUAL_FULL) {
       vbackup_cleanup(jcr, TermCode);
@@ -619,9 +691,10 @@ void backup_cleanup(JCR *jcr, int TermCode)
    jobstatus_to_ascii(jcr->SDJobStatus, sd_term_msg, sizeof(sd_term_msg));
 
    if (jcr->HasBase) {
-      Dmsg3(0, "Base files/Used files %lld/%lld=%.2f%%\n", jcr->nb_base_files, 
-            jcr->nb_base_files_used, 
-            jcr->nb_base_files_used*100.0/jcr->nb_base_files);
+      Mmsg(base_info, "  Base files/Used files:  %lld/%lld (%.2f%%)\n",
+           jcr->nb_base_files, 
+           jcr->nb_base_files_used, 
+           jcr->nb_base_files_used*100.0/jcr->nb_base_files);
    }
 // bmicrosleep(15, 0);                /* for debugging SIGHUP */
 
@@ -646,6 +719,7 @@ void backup_cleanup(JCR *jcr, int TermCode)
 "  SD Bytes Written:       %s (%sB)\n"
 "  Rate:                   %.1f KB/s\n"
 "  Software Compression:   %s\n"
+"%s"                                         /* Basefile info */
 "  VSS:                    %s\n"
 "  Encryption:             %s\n"
 "  Accurate:               %s\n"
@@ -681,6 +755,7 @@ void backup_cleanup(JCR *jcr, int TermCode)
         edit_uint64_with_suffix(jcr->SDJobBytes, ec6),
         kbps,
         compress,
+        base_info.c_str(),
         jcr->VSS?_("yes"):_("no"),
         jcr->Encrypt?_("yes"):_("no"),
         jcr->accurate?_("yes"):_("no"),