]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Fix bug #1046 VolumeToCatalog incorrectly reports mounted
authorKern Sibbald <kern@sibbald.com>
Tue, 28 Oct 2008 22:54:13 +0000 (22:54 +0000)
committerKern Sibbald <kern@sibbald.com>
Tue, 28 Oct 2008 22:54:13 +0000 (22:54 +0000)
     filesystems as missing on the Volume.
kes  Rewrite the set_jcr_job_status() code to include job status
     priorities so that more important status changes occur but
     lower priority status changes will not overwrite something
     more serious.  This could possibly cause reporting incorrect status
     reporting in some cases.  More testing is needed to ensure
     I have the right priorities. This vastly simplifies the previous
     contorted logic.
     Verify Diff status should now be correctly reported, whereas it
     was previously lost.
kes  Reduce some debug output.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@7928 91ce42f0-d328-0410-95d8-f526ca767f89

14 files changed:
bacula/patches/2.4.3-migrate-log.patch [new file with mode: 0644]
bacula/patches/2.4.3-migrate.patch [new file with mode: 0644]
bacula/patches/2.4.3-prune.patch [new file with mode: 0644]
bacula/src/cats/cats.h
bacula/src/cats/sql_get.c
bacula/src/dird/migrate.c
bacula/src/dird/protos.h
bacula/src/dird/verify.c
bacula/src/lib/jcr.c
bacula/src/stored/block.c
bacula/src/stored/fd_cmds.c
bacula/src/stored/spool.c
bacula/src/stored/vol_mgr.c
bacula/technotes-2.5

diff --git a/bacula/patches/2.4.3-migrate-log.patch b/bacula/patches/2.4.3-migrate-log.patch
new file mode 100644 (file)
index 0000000..a35f815
--- /dev/null
@@ -0,0 +1,57 @@
+Index: src/dird/migrate.c
+===================================================================
+--- src/dird/migrate.c (revision 7926)
++++ src/dird/migrate.c (working copy)
+@@ -402,14 +402,6 @@
+    }
+    migration_cleanup(jcr, jcr->JobStatus);
+-   if (mig_jcr) {
+-      char jobid[50];
+-      UAContext *ua = new_ua_context(jcr);
+-      edit_uint64(jcr->previous_jr.JobId, jobid);
+-      /* Purge all old file records, but leave Job record */
+-      purge_files_from_jobs(ua, jobid);
+-      free_ua_context(ua);
+-   }
+    return true;
+ }
+@@ -1087,11 +1079,26 @@
+          edit_uint64(mig_jcr->jr.JobId, ec2));
+       db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
+-      /* Now mark the previous job as migrated if it terminated normally */
+-      if (jcr->JobStatus == JS_Terminated) {
++      /*
++       * If we terminated a migration normally:
++       *   - mark the previous job as migrated
++       *   - move any Log records to the new JobId
++       *   - Purge the File records from the previous job
++       */
++      if (jcr->JobType == JT_MIGRATE && jcr->JobStatus == JS_Terminated) {
++         char old_jobid[50], new_jobid[50];
+          Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s",
+-              (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, ec1));
++              (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, new_jobid));
+          db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
++         UAContext *ua = new_ua_context(jcr);
++         /* Move JobLog to new JobId */
++         Mmsg(query, "UPDATE Log SET JobId=%s WHERE JobId=%s",
++           new_jobid,
++           edit_uint64(jcr->previous_jr.JobId, old_jobid));
++         db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
++         /* Purge all old file records, but leave Job record */
++         purge_files_from_jobs(ua, old_jobid);
++         free_ua_context(ua);
+       } 
+       if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) {
+@@ -1100,7 +1107,6 @@
+          set_jcr_job_status(jcr, JS_ErrorTerminated);
+       }
+-
+       update_bootstrap_file(mig_jcr);
+       if (!db_get_job_volume_names(mig_jcr, mig_jcr->db, mig_jcr->jr.JobId, &mig_jcr->VolumeName)) {
diff --git a/bacula/patches/2.4.3-migrate.patch b/bacula/patches/2.4.3-migrate.patch
new file mode 100644 (file)
index 0000000..138c09c
--- /dev/null
@@ -0,0 +1,53 @@
+
+ This patch should prevent migration jobs from attempting to migrate
+ jobs that failed.  Apply it to Bacula 2.4.3 (possibly earlier versions)
+ with:
+
+ cd <bacula-source>
+ patch -p0 <2.4.3-migrate.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+
+Index: src/dird/migrate.c
+===================================================================
+--- src/dird/migrate.c (revision 7757)
++++ src/dird/migrate.c (working copy)
+@@ -377,7 +377,7 @@
+     * to avoid two threads from using the BSOCK structure at
+     * the same time.
+     */
+-   if (!bnet_fsend(sd, "run")) {
++   if (!sd->fsend("run")) {
+       return false;
+    }
+@@ -520,6 +520,7 @@
+    "SELECT DISTINCT Job.JobId,Job.StartTime FROM Job,Pool,Client"
+    " WHERE Client.Name='%s' AND Pool.Name='%s' AND Job.PoolId=Pool.PoolId"
+    " AND Job.ClientId=Client.ClientId AND Job.Type='B'"
++   " AND Job.JobStatus = 'T'"
+    " ORDER by Job.StartTime";
+ /* Get Volume names in Pool */
+@@ -533,9 +534,9 @@
+    "SELECT DISTINCT Job.JobId,Job.StartTime FROM Media,JobMedia,Job"
+    " WHERE Media.VolumeName='%s' AND Media.MediaId=JobMedia.MediaId"
+    " AND JobMedia.JobId=Job.JobId AND Job.Type='B'"
++   " AND Job.JobStatus = 'T' AND Media.Enabled=1"
+    " ORDER by Job.StartTime";
+-
+ const char *sql_smallest_vol = 
+    "SELECT Media.MediaId FROM Media,Pool,JobMedia WHERE"
+    " Media.MediaId in (SELECT DISTINCT MediaId from JobMedia) AND"
+@@ -570,7 +571,6 @@
+ const char *sql_job_bytes =
+    "SELECT SUM(JobBytes) FROM Job WHERE JobId IN (%s)";
+-
+ /* Get Media Ids in Pool */
+ const char *sql_mediaids =
+    "SELECT MediaId FROM Media,Pool WHERE"
diff --git a/bacula/patches/2.4.3-prune.patch b/bacula/patches/2.4.3-prune.patch
new file mode 100644 (file)
index 0000000..7af00a7
--- /dev/null
@@ -0,0 +1,57 @@
+
+ This patch should fix the bug reported on the bacula-users list where
+ a retention period of 100 years does immediate prunning.
+ Apply it to 2.4.3 (or earlier versions) with:
+
+ cd <bacula-source>
+ patch -p0 <2.4.3-prune.patch
+ ./configure <your-options>
+ make
+ ...
+ make install
+
+Index: src/dird/ua_prune.c
+===================================================================
+--- src/dird/ua_prune.c        (revision 7757)
++++ src/dird/ua_prune.c        (working copy)
+@@ -202,7 +202,7 @@
+    now = (utime_t)time(NULL);
+    /* Select Jobs -- for counting */
+-   Mmsg(query, count_select_job, edit_uint64(now - period, ed1), 
++   Mmsg(query, count_select_job, edit_int64(now - period, ed1), 
+         edit_int64(cr.ClientId, ed2));
+    Dmsg3(050, "select now=%u period=%u sql=%s\n", (uint32_t)now, 
+                (uint32_t)period, query.c_str());
+@@ -230,7 +230,7 @@
+    del.JobId = (JobId_t *)malloc(sizeof(JobId_t) * del.max_ids);
+    /* Now process same set but making a delete list */
+-   Mmsg(query, select_job, edit_uint64(now - period, ed1), 
++   Mmsg(query, select_job, edit_int64(now - period, ed1), 
+         edit_int64(cr.ClientId, ed2));
+    db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)&del);
+@@ -318,7 +318,7 @@
+     * Select all files that are older than the JobRetention period
+     *  and stuff them into the "DeletionCandidates" table.
+     */
+-   edit_uint64(now - period, ed1);
++   edit_int64(now - period, ed1);
+    Mmsg(query, insert_delcand, (char)JobType, ed1, 
+         edit_int64(cr.ClientId, ed2));
+    if (!db_sql_query(ua->db, query.c_str(), NULL, (void *)NULL)) {
+@@ -443,10 +443,10 @@
+    edit_int64(mr->MediaId, ed1); 
+    period = mr->VolRetention;
+    now = (utime_t)time(NULL);
+-   edit_uint64(now-period, ed2);
++   edit_int64(now-period, ed2);
+    Mmsg(query, sel_JobMedia, ed1, ed2);
+-   Dmsg3(250, "Now=%d period=%d now-period=%d\n", (int)now, (int)period,
+-      (int)(now-period));
++   Dmsg3(250, "Now=%d period=%d now-period=%s\n", (int)now, (int)period,
++      ed2);
+    Dmsg1(050, "Query=%s\n", query.c_str());
+    if (!db_sql_query(ua->db, query.c_str(), file_delete_handler, (void *)del)) {
index 63e6b08a5350d430b44b92ddb3d733f9e334dcdb..e8e1d40c82d32c844d79a6afe0ad13758c17af62 100644 (file)
@@ -822,6 +822,7 @@ struct JOB_DBR {
    /* Extra stuff not in DB */
    int limit;                         /* limit records to display */
    faddr_t rec_addr;
+   uint32_t FileIndex;                /* added during Verify */
 };
 
 /* Job Media information used to create the media records
index a50fb336aaf322906db9ec227e8b3512c21f3ea4..82602d5eef1af18fde7c448af07e78f9bb5f127e 100644 (file)
@@ -97,6 +97,18 @@ int db_get_file_attributes_record(JCR *jcr, B_DB *mdb, char *fname, JOB_DBR *jr,
  *  Note in this routine, we do not use Jmsg because it may be
  *    called to get attributes of a non-existent file, which is
  *    "normal" if a new file is found during Verify.
+ *
+ *  The following is a bit of a kludge: because we always backup a 
+ *    directory entry, we can end up with two copies of the directory 
+ *    in the backup. One is when we encounter the directory and find 
+ *    we cannot recurse into it, and the other is when we find an 
+ *    explicit mention of the directory. This can also happen if the 
+ *    use includes the directory twice.  In this case, Verify 
+ *    VolumeToCatalog fails because we have two copies in the catalog, 
+ *    and only the first one is marked (twice).  So, when calling from Verify, 
+ *    jr is not NULL and we know jr->FileIndex is the fileindex
+ *    of the version of the directory/file we actually want and do
+ *    a more explicit SQL search.
  */
 static
 int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr)
@@ -115,6 +127,15 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr)
       edit_int64(fdbr->FilenameId, ed2), 
       edit_int64(jr->ClientId,ed3));
 
+   } else if (jr != NULL) {
+      /* Called from Verify so jr->FileIndex is valid */
+      Mmsg(mdb->cmd,
+"SELECT FileId, LStat, MD5 FROM File WHERE File.JobId=%s AND File.PathId=%s AND "
+"File.FilenameId=%s AND FileIndex=%u", 
+      edit_int64(fdbr->JobId, ed1), 
+      edit_int64(fdbr->PathId, ed2), 
+      edit_int64(fdbr->FilenameId,ed3),
+      jr->FileIndex);
    } else {
       Mmsg(mdb->cmd,
 "SELECT FileId, LStat, MD5 FROM File WHERE File.JobId=%s AND File.PathId=%s AND "
@@ -123,7 +144,7 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr)
       edit_int64(fdbr->PathId, ed2), 
       edit_int64(fdbr->FilenameId,ed3));
    }
-   Dmsg3(050, "Get_file_record JobId=%u FilenameId=%u PathId=%u\n",
+   Dmsg3(450, "Get_file_record JobId=%u FilenameId=%u PathId=%u\n",
       fdbr->JobId, fdbr->FilenameId, fdbr->PathId);
 
    Dmsg1(100, "Query=%s\n", mdb->cmd);
@@ -134,6 +155,7 @@ int db_get_file_record(JCR *jcr, B_DB *mdb, JOB_DBR *jr, FILE_DBR *fdbr)
       if (mdb->num_rows > 1) {
          Mmsg1(mdb->errmsg, _("get_file_record want 1 got rows=%d\n"),
             mdb->num_rows);
+         Dmsg1(000, "=== Problem!  %s", mdb->errmsg);
       }
       if (mdb->num_rows >= 1) {
          if ((row = sql_fetch_row(mdb)) == NULL) {
index b6ea75f76f8ef533a0fd9ed7912113e94fb26e9f..bf20d4ba03655f0c8f25a7df2ffa7bb4b0278923 100644 (file)
@@ -406,14 +406,7 @@ bool do_migration(JCR *jcr)
    }
 
    migration_cleanup(jcr, jcr->JobStatus);
-   if (jcr->get_JobType() == JT_MIGRATE && mig_jcr) {
-      char jobid[50];
-      UAContext *ua = new_ua_context(jcr);
-      edit_uint64(jcr->previous_jr.JobId, jobid);
-      /* Purge all old file records, but leave Job record */
-      purge_files_from_jobs(ua, jobid);
-      free_ua_context(ua);
-   }
+
    return true;
 }
 
@@ -1137,11 +1130,26 @@ void migration_cleanup(JCR *jcr, int TermCode)
          edit_uint64(mig_jcr->jr.JobId, ec2));
       db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
 
-      /* Now mark the previous job as migrated if it terminated normally */
+      /*
+       * If we terminated a migration normally:
+       *   - mark the previous job as migrated
+       *   - move any Log records to the new JobId
+       *   - Purge the File records from the previous job
+       */
       if (jcr->get_JobType() == JT_MIGRATE && jcr->JobStatus == JS_Terminated) {
+         char old_jobid[50], new_jobid[50];
          Mmsg(query, "UPDATE Job SET Type='%c' WHERE JobId=%s",
-              (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, ec1));
+              (char)JT_MIGRATED_JOB, edit_uint64(jcr->previous_jr.JobId, new_jobid));
+         db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
+         UAContext *ua = new_ua_context(jcr);
+         /* Move JobLog to new JobId */
+         Mmsg(query, "UPDATE Log SET JobId=%s WHERE JobId=%s",
+           new_jobid,
+           edit_uint64(jcr->previous_jr.JobId, old_jobid));
          db_sql_query(mig_jcr->db, query.c_str(), NULL, NULL);
+         /* Purge all old file records, but leave Job record */
+         purge_files_from_jobs(ua, old_jobid);
+         free_ua_context(ua);
       } 
 
       if (!db_get_job_record(jcr, jcr->db, &jcr->jr)) {
index 84677d62bb9952615ef01cabe95cd09351543ee6..06c8660ee7561d09cee006a0337a926fdd9737f6 100644 (file)
@@ -97,7 +97,7 @@ extern bool send_exclude_list(JCR *jcr);
 extern bool send_bootstrap_file(JCR *jcr, BSOCK *sock);
 extern bool send_level_command(JCR *jcr);
 extern int get_attributes_and_put_in_catalog(JCR *jcr);
-extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId);
+extern void get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId);
 extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname,
                           char *link, char *attr, int stream);
 extern void get_level_since_time(JCR *jcr, char *since, int since_len);
index 50828f40bdfd5f80e434e3416e4d71221e7b0e6e..3f1e57b52113a656817c3aeb8a031a05003b59a0 100644 (file)
@@ -383,12 +383,6 @@ void verify_cleanup(JCR *jcr, int TermCode)
       TermCode = JS_ErrorTerminated;
    }
 
-   /* If no files were expected, there can be no error */
-   if (jcr->get_JobLevel() == L_VERIFY_VOLUME_TO_CATALOG &&
-       jcr->ExpectedFiles == 0) {
-      TermCode = JS_Terminated;
-   }
-
    JobId = jcr->jr.JobId;
 
    update_job_end(jcr, TermCode);
@@ -510,14 +504,13 @@ void verify_cleanup(JCR *jcr, int TermCode)
 /*
  * This routine is called only during a Verify
  */
-int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
+void get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
 {
    BSOCK   *fd;
    int n, len;
    FILE_DBR fdbr;
    struct stat statf;                 /* file stat */
    struct stat statc;                 /* catalog stat */
-   int stat = JS_Terminated;
    char buf[MAXSTRING];
    POOLMEM *fname = get_pool_memory(PM_MESSAGE);
    int do_Digest = CRYPTO_DIGEST_NONE;
@@ -545,7 +538,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
       char Opts_Digest[MAXSTRING];        /* Verify Opts or MD5/SHA1 digest */
 
       if (job_canceled(jcr)) {
-         return false;
+         return;
       }
       fname = check_pool_memory_size(fname, fd->msglen);
       jcr->fname = check_pool_memory_size(jcr->fname, fd->msglen);
@@ -554,7 +547,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
             fname)) != 3) {
          Jmsg3(jcr, M_FATAL, 0, _("bird<filed: bad attributes, expected 3 fields got %d\n"
 " mslen=%d msg=%s\n"), len, fd->msglen, fd->msg);
-         return false;
+         return;
       }
       /*
        * We read the Options or Signature into fname
@@ -582,6 +575,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
          Dmsg2(400, "file_index=%d attr=%s\n", file_index, attr);
          jcr->JobFiles++;
          jcr->FileIndex = file_index;    /* remember attribute file_index */
+         jcr->previous_jr.FileIndex = file_index;
          decode_stat(attr, &statf, &LinkFIf);  /* decode file stat packet */
          do_Digest = CRYPTO_DIGEST_NONE;
          jcr->fn_printed = false;
@@ -598,7 +592,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
               &jcr->previous_jr, &fdbr)) {
             Jmsg(jcr, M_INFO, 0, _("New file: %s\n"), jcr->fname);
             Dmsg1(020, _("File not in catalog: %s\n"), jcr->fname);
-            stat = JS_Differences;
+            set_jcr_job_status(jcr, JS_Differences);
             continue;
          } else {
             /*
@@ -624,7 +618,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
                   Jmsg(jcr, M_INFO, 0, _("      st_ino   differ. Cat: %s File: %s\n"),
                      edit_uint64((uint64_t)statc.st_ino, ed1),
                      edit_uint64((uint64_t)statf.st_ino, ed2));
-                  stat = JS_Differences;
+                  set_jcr_job_status(jcr, JS_Differences);
                }
                break;
             case 'p':                /* permissions bits */
@@ -632,7 +626,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
                   prt_fname(jcr);
                   Jmsg(jcr, M_INFO, 0, _("      st_mode  differ. Cat: %x File: %x\n"),
                      (uint32_t)statc.st_mode, (uint32_t)statf.st_mode);
-                  stat = JS_Differences;
+                  set_jcr_job_status(jcr, JS_Differences);
                }
                break;
             case 'n':                /* number of links */
@@ -640,7 +634,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
                   prt_fname(jcr);
                   Jmsg(jcr, M_INFO, 0, _("      st_nlink differ. Cat: %d File: %d\n"),
                      (uint32_t)statc.st_nlink, (uint32_t)statf.st_nlink);
-                  stat = JS_Differences;
+                  set_jcr_job_status(jcr, JS_Differences);
                }
                break;
             case 'u':                /* user id */
@@ -648,7 +642,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
                   prt_fname(jcr);
                   Jmsg(jcr, M_INFO, 0, _("      st_uid   differ. Cat: %u File: %u\n"),
                      (uint32_t)statc.st_uid, (uint32_t)statf.st_uid);
-                  stat = JS_Differences;
+                  set_jcr_job_status(jcr, JS_Differences);
                }
                break;
             case 'g':                /* group id */
@@ -656,7 +650,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
                   prt_fname(jcr);
                   Jmsg(jcr, M_INFO, 0, _("      st_gid   differ. Cat: %u File: %u\n"),
                      (uint32_t)statc.st_gid, (uint32_t)statf.st_gid);
-                  stat = JS_Differences;
+                  set_jcr_job_status(jcr, JS_Differences);
                }
                break;
             case 's':                /* size */
@@ -665,28 +659,28 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
                   Jmsg(jcr, M_INFO, 0, _("      st_size  differ. Cat: %s File: %s\n"),
                      edit_uint64((uint64_t)statc.st_size, ed1),
                      edit_uint64((uint64_t)statf.st_size, ed2));
-                  stat = JS_Differences;
+                  set_jcr_job_status(jcr, JS_Differences);
                }
                break;
             case 'a':                /* access time */
                if (statc.st_atime != statf.st_atime) {
                   prt_fname(jcr);
                   Jmsg(jcr, M_INFO, 0, _("      st_atime differs\n"));
-                  stat = JS_Differences;
+                  set_jcr_job_status(jcr, JS_Differences);
                }
                break;
             case 'm':
                if (statc.st_mtime != statf.st_mtime) {
                   prt_fname(jcr);
                   Jmsg(jcr, M_INFO, 0, _("      st_mtime differs\n"));
-                  stat = JS_Differences;
+                  set_jcr_job_status(jcr, JS_Differences);
                }
                break;
             case 'c':                /* ctime */
                if (statc.st_ctime != statf.st_ctime) {
                   prt_fname(jcr);
                   Jmsg(jcr, M_INFO, 0, _("      st_ctime differs\n"));
-                  stat = JS_Differences;
+                  set_jcr_job_status(jcr, JS_Differences);
                }
                break;
             case 'd':                /* file size decrease */
@@ -695,7 +689,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
                   Jmsg(jcr, M_INFO, 0, _("      st_size  decrease. Cat: %s File: %s\n"),
                      edit_uint64((uint64_t)statc.st_size, ed1),
                      edit_uint64((uint64_t)statf.st_size, ed2));
-                  stat = JS_Differences;
+                  set_jcr_job_status(jcr, JS_Differences);
                }
                break;
             case '5':                /* compare MD5 */
@@ -724,7 +718,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
          if (jcr->FileIndex != (uint32_t)file_index) {
             Jmsg2(jcr, M_FATAL, 0, _("MD5/SHA1 index %d not same as attributes %d\n"),
                file_index, jcr->FileIndex);
-            return false;
+            return;
          }
          if (do_Digest != CRYPTO_DIGEST_NONE) {
             db_escape_string(jcr, jcr->db, buf, Opts_Digest, strlen(Opts_Digest));
@@ -732,7 +726,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
                prt_fname(jcr);
                Jmsg(jcr, M_INFO, 0, _("      %s differs. File=%s Cat=%s\n"),
                     stream_to_ascii(stream), buf, fdbr.Digest);
-               stat = JS_Differences;
+               set_jcr_job_status(jcr, JS_Differences);
             }
             do_Digest = CRYPTO_DIGEST_NONE;
          }
@@ -743,7 +737,7 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
       berrno be;
       Jmsg2(jcr, M_FATAL, 0, _("bdird<filed: bad attributes from filed n=%d : %s\n"),
                         n, be.bstrerror());
-      return false;
+      return;
    }
 
    /* Now find all the files that are missing -- i.e. all files in
@@ -759,13 +753,9 @@ int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId)
    /* missing_handler is called for each file found */
    db_sql_query(jcr->db, buf, missing_handler, (void *)jcr);
    if (jcr->fn_printed) {
-      stat = JS_Differences;
+      set_jcr_job_status(jcr, JS_Differences);
    }
    free_pool_memory(fname);
-   if (!job_canceled(jcr)) {
-      jcr->JobStatus = stat;
-   }
-   return stat == JS_Terminated;
 }
 
 /*
@@ -782,8 +772,8 @@ static int missing_handler(void *ctx, int num_fields, char **row)
       return 1;
    }
    if (!jcr->fn_printed) {
-      Qmsg(jcr, M_INFO, 0, _("\nThe following files are in the Catalog but not on %s:\n"),
-       jcr->get_JobLevel() == L_VERIFY_VOLUME_TO_CATALOG ? "the Volume(s)" : "disk");
+      Qmsg(jcr, M_WARNING, 0, _("The following files are in the Catalog but not on %s:\n"),
+          jcr->get_JobLevel() == L_VERIFY_VOLUME_TO_CATALOG ? "the Volume(s)" : "disk");
       jcr->fn_printed = true;
    }
    Qmsg(jcr, M_INFO, 0, "      %s%s\n", row[0]?row[0]:"", row[1]?row[1]:"");
index e7acb12a15cce31b98e63cd30f88c1fe852245c4..4b8b9d110aaafbb6a0b8b04836fb8edec85c109d 100644 (file)
@@ -714,10 +714,38 @@ JCR *get_jcr_by_full_name(char *Job)
    return jcr;
 }
 
+/* 
+ * Priority runs from 0 (lowest) to 10 (highest)
+ */
+static int get_status_priority(int JobStatus)
+{
+   int priority = 0;
+   switch (JobStatus) {
+   case JS_ErrorTerminated:
+   case JS_FatalError:
+      priority = 10;
+      break;
+   case JS_Canceled:
+      priority = 9;
+      break;
+   case JS_Error:
+      priority = 8;
+      break;
+   case JS_Differences:
+      priority = 7;
+      break;
+   }
+   return priority;
+}
+
 void set_jcr_job_status(JCR *jcr, int JobStatus)
 {
     bool set_waittime = false;
     int oldJobStatus = jcr->JobStatus;
+    int priority, old_priority;
+
+    priority = get_status_priority(JobStatus);
+    old_priority = get_status_priority(oldJobStatus);
 
     Dmsg2(800, "set_jcr_job_status(%s, %c)\n", jcr->Job, JobStatus);
     /* if wait state is new, we keep current time for watchdog MaxWaitTime */
@@ -742,26 +770,15 @@ void set_jcr_job_status(JCR *jcr, int JobStatus)
     */
    Dmsg3(300, "jid=%u OnEntry JobStatus=%c set=%c\n", (uint32_t)jcr->JobId,
          jcr->JobStatus, JobStatus);
-   switch (jcr->JobStatus) {
-   case JS_ErrorTerminated:
-   case JS_FatalError:
-   case JS_Canceled:
-      break;
-   case JS_Error:
-   case JS_Differences:
-      switch (JobStatus) {
-      case JS_ErrorTerminated:
-      case JS_FatalError:
-      case JS_Canceled:
-         /* Override more minor status */
-         jcr->JobStatus = JobStatus;
-         break;
-      default:
-         break;
-      }
+   if (priority >= old_priority) {
+      jcr->JobStatus = JobStatus;     /* replace with new priority */
+   }
    /*
-    * For a set of Wait situation, keep old time.
+    * If we were previously waiting and are not any more
+    *   we want to update the wait_time variable, which is
+    *   the start of waiting.
     */
+   switch (oldJobStatus) {
    case JS_WaitFD:
    case JS_WaitSD:
    case JS_WaitMedia:
@@ -773,9 +790,7 @@ void set_jcr_job_status(JCR *jcr, int JobStatus)
    case JS_WaitPriority:
        set_waittime = false;    /* keep old time */
    default:
-      jcr->JobStatus = JobStatus;
       if (set_waittime) {
-         /* set it before JobStatus */
          Dmsg0(800, "Setting wait_time\n");
          jcr->wait_time = time(NULL);
       }
index 156b0fa8348eb35ebbe0843532a0963063b9f398..a173b8eb475b8ea79c1575683ab49a535c6b5749 100644 (file)
@@ -422,7 +422,7 @@ bool write_block_to_dev(DCR *dcr)
    if (dev->at_weot()) {
       Dmsg0(100, "return write_block_to_dev with ST_WEOT\n");
       dev->dev_errno = ENOSPC;
-      Jmsg(jcr, M_FATAL, 0,  _("Cannot write block. Device at EOM.\n"));
+      Jmsg0(jcr, M_FATAL, 0,  _("Cannot write block. Device at EOM.\n"));
       return false;
    }
    if (!dev->can_append()) {
index 7cd070e6c505664aea92ad6375d57b2f460759e1..558df83f3a121f889102c96fe7e86a604aa48b14 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
@@ -212,7 +212,6 @@ static bool append_end_session(JCR *jcr)
       fd->fsend(NOT_opened);
       return false;
    }
-   set_jcr_job_status(jcr, JS_Terminated);
    return fd->fsend(OK_end);
 }
 
index 01f6e2323bd1c6dd4095eaa634a330b9240ae5a0..bbd2f8601fe53305718db47cef4123a2b45c90f2 100644 (file)
@@ -296,6 +296,8 @@ static bool despool_data(DCR *dcr, bool commit)
       if (!ok) {
          Jmsg2(jcr, M_FATAL, 0, _("Fatal append error on device %s: ERR=%s\n"),
                dcr->dev->print_name(), dcr->dev->bstrerror());
+         Dmsg2(000, "Fatal append error on device %s: ERR=%s\n",
+               dcr->dev->print_name(), dcr->dev->bstrerror());
       }
       Dmsg3(800, "Write block ok=%d FI=%d LI=%d\n", ok, block->FirstIndex, block->LastIndex);
    }
index a3c7dc15b0fa230adffed7de1e3d6f50c20db006..0d5584d8c10f98057347c45e0fe57ba0a3dbc869 100644 (file)
@@ -158,9 +158,9 @@ void add_read_volume(JCR *jcr, const char *VolumeName)
    vol = (VOLRES *)read_vol_list->binary_insert(nvol, read_compare);
    if (vol != nvol) {
       free_vol_item(nvol);
-      Dmsg2(1, "read_vol=%s JobId=%d already in list.\n", VolumeName, jcr->JobId);
+      Dmsg2(dbglvl, "read_vol=%s JobId=%d already in list.\n", VolumeName, jcr->JobId);
    } else {
-      Dmsg2(1, "add read_vol=%s JobId=%d\n", VolumeName, jcr->JobId);
+      Dmsg2(dbglvl, "add read_vol=%s JobId=%d\n", VolumeName, jcr->JobId);
    }
    unlock_read_volumes();
 }
@@ -176,7 +176,9 @@ void remove_read_volume(JCR *jcr, const char *VolumeName)
    vol.set_jobid(jcr->JobId);
    fvol = (VOLRES *)read_vol_list->binary_search(&vol, read_compare);
    free(vol.vol_name);
-   Dmsg3(1, "remove_read_vol=%s JobId=%d found=%d\n", VolumeName, jcr->JobId, fvol!=NULL);
+   if (fvol) {
+      Dmsg3(dbglvl, "remove_read_vol=%s JobId=%d found=%d\n", VolumeName, jcr->JobId, fvol!=NULL);
+   }
    debug_list_volumes("remove_read_volume");
    if (fvol) {
       read_vol_list->remove(fvol);
index 93cd89bd92a6f0fde818645c1cbaad3f515f9cdb..a053d8de56a8b0e1e41707a003d7fde1c8b0bf52 100644 (file)
@@ -11,6 +11,18 @@ mixed priorities
 
 General:
 28Oct08
+kes  Fix bug #1046 VolumeToCatalog incorrectly reports mounted 
+     filesystems as missing on the Volume.
+kes  Rewrite the set_jcr_job_status() code to include job status
+     priorities so that more important status changes occur but
+     lower priority status changes will not overwrite something
+     more serious.  This could possibly cause reporting incorrect status
+     reporting in some cases.  More testing is needed to ensure
+     I have the right priorities. This vastly simplifies the previous
+     contorted logic.
+     Verify Diff status should now be correctly reported, whereas it
+     was previously lost.
+kes  Reduce some debug output.
 kes  Apply Joao's patch to SQLite tables to make chars work.
 27Oct08
 ebl  Fix #1175 About update slots that don't reset InChanger flag when