]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/block.c
Make out of freespace non-fatal for removable devices -- i.e. behaves like tape
[bacula/bacula] / bacula / src / stored / block.c
index 06c1320a8dba202d54abd912fd23e1d5d2159dc8..1a0ef854727f1508645037fb7da55027e7117ae0 100644 (file)
@@ -301,8 +301,12 @@ bool DCR::write_block_to_dev()
       if (dev->dev_errno == ENOSPC) {
          dev->update_freespace();
          if (dev->is_freespace_ok() && dev->free_space < dev->min_free_space) {
+            int mtype = M_FATAL;
             dev->set_nospace();
-            Jmsg(jcr, M_WARNING, 0, _("Out of freespace caused End of Volume \"%s\" at %s on device %s. Write of %u bytes got %d.\n"),
+            if (dev->is_removable()) {
+               mtype = M_INFO;
+            }
+            Jmsg(jcr, mtype, 0, _("Out of freespace caused End of Volume \"%s\" at %s on device %s. Write of %u bytes got %d.\n"),
                dev->getVolCatName(),
                dev->print_addr(ed1, sizeof(ed1)), dev->print_name(), wlen, stat);
          } else {
@@ -447,6 +451,7 @@ bool DCR::read_block_from_dev(bool check_block_numbers)
    DCR *dcr = this;
    boffset_t pos;
    char ed1[50];
+   uint32_t data_len;
 
    if (job_canceled(jcr)) {
       Mmsg(dev->errmsg, _("Job failed or canceled.\n"));
@@ -512,19 +517,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 +563,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);