]> git.ipfire.org Git - thirdparty/bacula.git/commitdiff
Fix creation of bad JobMedia records in Incomplete Job
authorKern Sibbald <kern@sibbald.com>
Sun, 3 Mar 2019 12:58:48 +0000 (13:58 +0100)
committerKern Sibbald <kern@sibbald.com>
Sun, 3 Mar 2019 12:58:48 +0000 (13:58 +0100)
bacula/src/lib/bsock.h
bacula/src/stored/append.c
bacula/src/stored/askdir.c

index fd4e76f1b7aae29fe209c8c60732a45511d26e62..81451d63026b5e7f9b081aed31a3dd3e13de1a7a 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2019 Kern Sibbald
 
    The original author of Bacula is Kern Sibbald, with contributions
    from many others, a complete list can be found in the file AUTHORS.
@@ -54,6 +54,7 @@ private:
    boffset_t m_last_data_end;         /* offset of last valid data written */
    int32_t m_FileIndex;               /* attr spool FI */
    int32_t m_lastFileIndex;           /* last valid attr spool FI */
+   int32_t m_lastFlushIndex;          /* Last FileIndex flushed */
    bool m_spool: 1;                   /* set for spooling */
    bool m_compress: 1;                /* set to use comm line compression */
    uint64_t m_CommBytes;              /* Bytes sent */
@@ -91,8 +92,10 @@ public:
               m_data_end = ftello(m_spool_fd);
            }
         };
+   void set_lastFlushIndex(int32_t FlushIndex) { m_lastFlushIndex = FlushIndex; };
    boffset_t get_last_data_end() { return m_last_data_end; };
-   int32_t get_lastFileIndex() { return m_lastFileIndex; };
+   uint32_t get_lastFileIndex() { return m_lastFileIndex; };
+   uint32_t get_lastFlushIndex() { return m_lastFlushIndex; };
    uint32_t CommBytes() { return m_CommBytes; };
    uint32_t CommCompressedBytes() { return m_CommCompressedBytes; };
    void set_spooling() { m_spool = true; };
index 144436ff280798453c6360e04004fd4c5c1e36df..5d119cee4fa81c3f938acf6cb63676a39d7c41de 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula(R) - The Network Backup Solution
 
-   Copyright (C) 2000-2017 Kern Sibbald
+   Copyright (C) 2000-2019 Kern Sibbald
 
    The original author of Bacula is Kern Sibbald, with contributions
    from many others, a complete list can be found in the file AUTHORS.
@@ -36,18 +36,23 @@ static char OK_append[]  = "3000 OK append data\n";
  * Check if we can mark this job incomplete
  *
  */
-void possible_incomplete_job(JCR *jcr, int32_t last_file_index)
+void possible_incomplete_job(JCR *jcr, uint32_t last_file_index)
 {
+   BSOCK *dir = jcr->dir_bsock;
    /*
     * Note, here we decide if it is worthwhile to restart
     *  the Job at this point. For the moment, if at least
     *  10 Files have been seen.
-    *  We must be sure that the saved files are safe.
-    *  Using this function when their is as comm line problem is probably safe,
+    * We must be sure that the saved files are safe.
+    * Using this function when there is as comm line problem is probably safe,
     *  it is inappropriate to use it for a any failure that could
     *  involve corrupted data.
+    * We cannot mark a job Incomplete if we have already flushed
+    *  a bad JobMedia record (i.e. one beyond the last FileIndex
+    *  that is known to be good).
     */
-   if (jcr->spool_attributes && last_file_index > 10) {
+   if (jcr->spool_attributes && last_file_index > 10 &&
+       dir->get_lastFlushIndex() < last_file_index) {
       jcr->setJobStatus(JS_Incomplete);
    }
 }
index 481f007763d63bb99310305e84edf66812e6eaf4..6d66dc4739a8fce97f1e0e4019401bd0b4536d20 100644 (file)
@@ -591,11 +591,21 @@ bool flush_jobmedia_queue(JCR *jcr)
 
    dir->fsend(Create_jobmedia, jcr->JobId);
    foreach_dlist(item, jcr->jobmedia_queue) {
+      if (jcr->is_JobStatus(JS_Incomplete)) {
+         if (item->VolFirstIndex >= dir->get_lastFileIndex()) {
+            continue;
+         }
+         if (item->VolLastIndex >= dir->get_lastFileIndex()) {
+            item->VolLastIndex = dir->get_lastFileIndex() - 1;
+         }
+      }
       ok = dir->fsend("%u %u %u %u %u %u %lld\n",
          item->VolFirstIndex, item->VolLastIndex,
          item->StartFile, item->EndFile,
          item->StartBlock, item->EndBlock,
          item->VolMediaId);
+      /* Keep track of last FileIndex flushed */
+      dir->set_lastFlushIndex(item->VolLastIndex);
       Dmsg2(400, "sd->dir: ok=%d Jobmedia=%s", ok, dir->msg);
    }
    dir->signal(BNET_EOD);
@@ -667,10 +677,6 @@ bool dir_create_jobmedia_record(DCR *dcr, bool zero)
     *  to the last correctly saved file so that the JobMedia
     *  LastIndex is correct.
     *
-    *  Note: ***FIXME*** though it is not required, we probably
-    *   should also keep a last EndFile and last EndBlock and
-    *   reset them correctly too so that the JobMedia record is
-    *   really correct.
     */
    if (jcr->is_JobStatus(JS_Incomplete)) {
       dcr->VolLastIndex = dir->get_lastFileIndex();
@@ -699,8 +705,8 @@ bool dir_create_jobmedia_record(DCR *dcr, bool zero)
       item->VolMediaId = dcr->VolMediaId;
    }
    jcr->jobmedia_queue->append(item);
-   /* Flush at 100 queue size of 100 jobmedia records */
-   if (zero || jcr->jobmedia_queue->size() >= 100) {
+   /* Flush at queue size of 1000 jobmedia records */
+   if (zero || jcr->jobmedia_queue->size() >= 1000) {
       ok = flush_jobmedia_queue(jcr);
    }