]> git.sur5r.net Git - bacula/bacula/commitdiff
Apply patches from bugs #2325 and #2326 to fix FIFO bugs
authorV. Novy <bacula@vnovy.net>
Sun, 19 Nov 2017 11:57:03 +0000 (12:57 +0100)
committerKern Sibbald <kern@sibbald.com>
Sun, 19 Nov 2017 11:57:03 +0000 (12:57 +0100)
bacula/src/stored/block.c
bacula/src/stored/label.c
bacula/src/stored/read_records.c

index 5134b953d90e804fa20616d3cfb7655f81dbafe6..a0f33705cd6d7eb00dc5db218ce61bfe470d51c8 100644 (file)
@@ -447,6 +447,7 @@ bool DCR::read_block_from_dev(bool check_block_numbers)
    DCR *dcr = this;
    boffset_t pos;
    char ed1[50];
+   int data_len;
 
    if (job_canceled(jcr)) {
       Mmsg(dev->errmsg, _("Job failed or canceled.\n"));
@@ -512,19 +513,30 @@ reread:
       Dmsg2(200, "Pos for read=%s %lld\n",
          dev->print_addr(ed1, sizeof(ed1), pos), pos);
    }
+
+   data_len = 0;
+
    do {
-      if ((retry > 0 && stat == -1 && errno == EBUSY)) {
-         berrno be;
-         Dmsg4(100, "===== read retry=%d stat=%d errno=%d: ERR=%s\n",
-               retry, stat, errno, be.bstrerror());
-         bmicrosleep(10, 0);    /* pause a bit if busy or lots of errors */
-         dev->clrerror(-1);
-      }
-      stat = dev->read(block->buf, (size_t)block->buf_len);
+      retry = 0;
+
+      do {
+         if ((retry > 0 && stat == -1 && errno == EBUSY)) {
+            berrno be;
+            Dmsg4(100, "===== read retry=%d stat=%d errno=%d: ERR=%s\n",
+                  retry, stat, errno, be.bstrerror());
+            bmicrosleep(10, 0);    /* pause a bit if busy or lots of errors */
+            dev->clrerror(-1);
+         }
+         stat = dev->read(block->buf + data_len, (size_t)(block->buf_len - data_len));
+         if (stat > 0)
+            data_len += stat;
+
+      } while (stat == -1 && (errno == EBUSY || errno == EINTR || errno == EIO) && retry++ < 3);
+
+   } while (data_len < block->buf_len && stat > 0 && dev->dev_type == B_FIFO_DEV);
 
-   } while (stat == -1 && (errno == EBUSY || errno == EINTR || errno == EIO) && retry++ < 3);
    Dmsg4(110, "Read() adata=%d vol=%s nbytes=%d pos=%lld\n",
-      block->adata, dev->VolHdr.VolumeName, stat, pos);
+      block->adata, dev->VolHdr.VolumeName, stat < 0 ? stat : data_len, pos);
    if (stat < 0) {
       berrno be;
       dev->clrerror(-1);
@@ -547,6 +559,9 @@ reread:
       }
       return false;
    }
+
+   stat = data_len;
+
    if (stat == 0) {             /* Got EOF ! */
       pos = dev->lseek(dcr, (boffset_t)0, SEEK_CUR); /* get curr pos */
       pos = dev->get_full_addr(pos);
index 6f41b7bb0fe75908bc8d86fb9a31bc87eb091326..236cc70067618f58169f55a32e5c4f80cfc2b70e 100644 (file)
@@ -279,7 +279,9 @@ int DEVICE::read_dev_volume_label(DCR *dcr)
       goto bail_out;
    }
 
-   empty_block(block);
+   if (dcr->is_writing()) {
+       empty_block(block);
+   }
 
    Leave(dbglvl);
    return VOL_OK;
index 5b28576894b7a3d4f773d63d0e05fbe5c773310d..0e8f02ebe75a0b3be41ba5e5362afc846dd8cd80 100644 (file)
@@ -116,6 +116,7 @@ bool read_records(DCR *dcr,
    SESSION_LABEL sessrec;
    dlist *recs;                         /* linked list of rec packets open */
    char ed1[50];
+   bool first_block = true;
 
    recs = New(dlist(rec, &rec->link));
    /* We go to the first_file unless we need to reposition during an
@@ -131,44 +132,48 @@ bool read_records(DCR *dcr,
       }
       ASSERT2(!dcr->dev->adata, "Called with adata block. Wrong!");
 
-      if (dev->at_eot() || !dcr->read_block_from_device(CHECK_BLOCK_NUMBERS)) {
-         if (dev->at_eot()) {
-            Jmsg(jcr, M_INFO, 0,
-                 _("End of Volume \"%s\" at addr=%s on device %s.\n"),
-                 dcr->VolumeName,
-                 dev->print_addr(ed1, sizeof(ed1), dev->EndAddr),
-                 dev->print_name());
-            ok = mount_next_vol(jcr, dcr, jcr->bsr, &sessrec, &should_stop,
-                                record_cb, mount_cb);
-            /* Might have changed after the mount request */
-            dev = dcr->dev;
-            block = dcr->block;
-            if (should_stop) {
-               break;
-            }
-            continue;
 
-         } else if (dev->at_eof()) {
-            Dmsg3(200, "EOF at addr=%s on device %s, Volume \"%s\"\n",
-                  dev->print_addr(ed1, sizeof(ed1), dev->EndAddr),
-                  dev->print_name(), dcr->VolumeName);
-            continue;
-         } else if (dev->is_short_block()) {
-            Jmsg1(jcr, M_ERROR, 0, "%s", dev->errmsg);
-            continue;
-         } else {
-            /* I/O error or strange end of tape */
-            display_tape_error_status(jcr, dev);
-            if (forge_on || jcr->ignore_label_errors) {
-               dev->fsr(1);       /* try skipping bad record */
-               Pmsg0(000, _("Did fsr in attemp to skip bad record.\n"));
-               continue;              /* try to continue */
+      if (! first_block || dev->dev_type != B_FIFO_DEV ) {
+         if (dev->at_eot() || !dcr->read_block_from_device(CHECK_BLOCK_NUMBERS)) {
+            if (dev->at_eot()) {
+               Jmsg(jcr, M_INFO, 0,
+                    _("End of Volume \"%s\" at addr=%s on device %s.\n"),
+                    dcr->VolumeName,
+                    dev->print_addr(ed1, sizeof(ed1), dev->EndAddr),
+                    dev->print_name());
+               ok = mount_next_vol(jcr, dcr, jcr->bsr, &sessrec, &should_stop,
+                                   record_cb, mount_cb);
+               /* Might have changed after the mount request */
+               dev = dcr->dev;
+               block = dcr->block;
+               if (should_stop) {
+                  break;
+               }
+               continue;
+
+            } else if (dev->at_eof()) {
+               Dmsg3(200, "EOF at addr=%s on device %s, Volume \"%s\"\n",
+                     dev->print_addr(ed1, sizeof(ed1), dev->EndAddr),
+                     dev->print_name(), dcr->VolumeName);
+               continue;
+            } else if (dev->is_short_block()) {
+               Jmsg1(jcr, M_ERROR, 0, "%s", dev->errmsg);
+               continue;
+            } else {
+               /* I/O error or strange end of tape */
+               display_tape_error_status(jcr, dev);
+               if (forge_on || jcr->ignore_label_errors) {
+                  dev->fsr(1);       /* try skipping bad record */
+                  Pmsg0(000, _("Did fsr in attemp to skip bad record.\n"));
+                  continue;              /* try to continue */
+               }
+               ok = false;               /* stop everything */
+               break;
             }
-            ok = false;               /* stop everything */
-            break;
          }
+             Dmsg1(dbglvl, "Read new block at pos=%s\n", dev->print_addr(ed1, sizeof(ed1)));
       }
-      Dmsg1(dbglvl, "Read new block at pos=%s\n", dev->print_addr(ed1, sizeof(ed1)));
+      first_block = false;
 #ifdef if_and_when_FAST_BLOCK_REJECTION_is_working
       /* this does not stop when file/block are too big */
       if (!match_bsr_block(jcr->bsr, block)) {