]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/block.c
Update the Microsoft Visual Studio build to match the MinGW32 build.
[bacula/bacula] / bacula / src / stored / block.c
index d9320e3e2e009bf98616b4035ee55a04905b3023..69f9ab616b15e34f366b976fd6fd211e3fce2e66 100644 (file)
@@ -27,7 +27,6 @@
 #include "bacula.h"
 #include "stored.h"
 
-extern int debug_level;
 static bool terminate_writing_volume(DCR *dcr);
 static bool do_new_file_bookkeeping(DCR *dcr);
 static bool do_dvd_size_checks(DCR *dcr);
@@ -510,9 +509,20 @@ bool write_block_to_dev(DCR *dcr)
 #endif
 
    /*
-    * Do write here
+    * Do write here, make a somewhat feeble attempt to recover from 
+    *  I/O errors, or from the OS telling us it is busy.
     */ 
-   stat = write(dev->fd, block->buf, (size_t)wlen);
+   int retry = 0;
+   do {
+      if (dev->is_tape()) {
+         stat = tape_write(dev->fd, block->buf, (size_t)wlen);
+      } else {
+         stat = write(dev->fd, block->buf, (size_t)wlen);
+      }
+      if (retry > 10) {
+         bmicrosleep(0, 100000);    /* pause a bit if lots of errors */
+      }
+   } while (stat == -1 && (errno == EBUSY || errno == EIO) && retry++ < 30);
 
 #ifdef DEBUG_BLOCK_ZEROING
    if (bp[0] == 0 && bp[1] == 0 && bp[2] == 0 && block->buf[12] == 0) {
@@ -565,13 +575,13 @@ bool write_block_to_dev(DCR *dcr)
    dev->VolCatInfo.VolCatBlocks++;
    dev->EndBlock = dev->block_num;
    dev->EndFile  = dev->file;
-   dev->block_num++;
    block->BlockNumber++;
 
    /* Update dcr values */
    if (dev->is_tape()) {
       dcr->EndBlock = dev->EndBlock;
       dcr->EndFile  = dev->EndFile;
+      dev->block_num++;
    } else {
       /* Save address of block just written */
       uint64_t addr = dev->file_addr + wlen - 1;
@@ -700,8 +710,15 @@ static bool terminate_writing_volume(DCR *dcr)
    dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs */
    
    if (dev->is_dvd()) {
-      dvd_write_part(dcr);                 /* write last part */
-      dev->VolCatInfo.VolCatParts = dev->num_parts;
+      if (!dvd_write_part(dcr)) {             /* write last part */
+         dev->VolCatInfo.VolCatErrors++;
+         Jmsg(dcr->jcr, M_FATAL, 0, _("Error writing final part to DVD. "
+                                 "This Volume may not be readable.\n%s"),
+                         dev->errmsg);
+         ok = false;
+         Dmsg0(100, "dvd_write_part error.\n");
+      }
+      dev->VolCatInfo.VolCatParts = dev->num_dvd_parts;
    }
    
    if (!dir_update_volume_info(dcr, false)) {
@@ -796,10 +813,10 @@ static bool do_dvd_size_checks(DCR *dcr)
    /* Limit maximum part size to value specified by user 
     */
    if (dev->max_part_size > 0 && ((dev->part_size + block->binbuf) >= dev->max_part_size)) {
-      if (dev->part < dev->num_parts) {
+      if (dev->part < dev->num_dvd_parts) {
          Jmsg3(dcr->jcr, M_FATAL, 0, _("Error while writing, current part number"
                " is less than the total number of parts (%d/%d, device=%s)\n"),
-               dev->part, dev->num_parts, dev->print_name());
+               dev->part, dev->num_dvd_parts, dev->print_name());
          dev->dev_errno = EIO;
          return false;
       }
@@ -811,7 +828,7 @@ static bool do_dvd_size_checks(DCR *dcr)
          return false;
       }
       
-      dev->VolCatInfo.VolCatParts = dev->num_parts;
+      dev->VolCatInfo.VolCatParts = dev->num_dvd_parts;
             
       if (!dir_update_volume_info(dcr, false)) {
          Dmsg0(190, "Error from update_vol_info.\n");
@@ -905,18 +922,19 @@ reread:
    Dmsg1(100, "dev->file_size-dev->part_start=%u\n",(unsigned int)dev->file_size-dev->part_start);
    Dmsg1(100, "dev->part_size=%u\n", (unsigned int)dev->part_size);
    Dmsg1(100, "dev->part=%u\n", (unsigned int)dev->part);
-   Dmsg1(100, "dev->num_parts=%u\n", (unsigned int)dev->num_parts);
+   Dmsg1(100, "dev->num_dvd_parts=%u\n", (unsigned int)dev->num_dvd_parts);
    Dmsg1(100, "dev->VolCatInfo.VolCatParts=%u\n", (unsigned int)dev->VolCatInfo.VolCatParts);
    Dmsg3(100, "Tests : %d %d %d\n", (dev->VolCatInfo.VolCatParts > 0), 
          ((dev->file_addr-dev->part_start) == dev->part_size), 
          (dev->part <= dev->VolCatInfo.VolCatParts));*/
-   /* Check for part file end */
-   if ((dev->num_parts > 0) &&
-        ((dev->file_addr-dev->part_start) == dev->part_size) && 
-        (dev->part < dev->num_parts)) {
+
+   /* Check for DVD part file end */
+   if (dev->at_eof() && dev->is_dvd() && dev->num_dvd_parts > 0 &&
+        dev->part < dev->num_dvd_parts) {
+      Dmsg0(400, "Call dvd_open_next_part\n");
       if (dvd_open_next_part(dcr) < 0) {
-         Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device next part %s: ERR=%s\n"),
-               dev->print_name(), dev->bstrerror());
+         Jmsg3(dcr->jcr, M_FATAL, 0, _("Unable to open device part=%d %s: ERR=%s\n"),
+               dev->part, dev->print_name(), dev->bstrerror());
          dev->dev_errno = EIO;
          return false;
       }
@@ -927,7 +945,11 @@ reread:
 //    uint32_t *bp = (uint32_t *)block->buf;
 //    Pmsg3(000, "Read %p %u at %llu\n", block->buf, block->buf_len, lseek(dev->fd, 0, SEEK_CUR));
 
-      stat = read(dev->fd, block->buf, (size_t)block->buf_len);
+      if (dev->is_tape()) {
+         stat = tape_read(dev->fd, block->buf, (size_t)block->buf_len);
+      } else {
+         stat = read(dev->fd, block->buf, (size_t)block->buf_len);
+      }
 
 //    Pmsg8(000, "stat=%d Csum=%u blen=%u bnum=%u %c%c%c%c\n",stat, bp[0],bp[1],bp[2],
 //      block->buf[12],block->buf[13],block->buf[14],block->buf[15]);
@@ -1076,10 +1098,11 @@ reread:
    if (block->read_len > block->block_len && !dev->is_tape()) {
       char ed1[50];
       off_t pos = lseek_dev(dev, (off_t)0, SEEK_CUR); /* get curr pos */
+      Dmsg1(200, "Current lseek pos=%s\n", edit_int64(pos, ed1));
       pos -= (block->read_len - block->block_len);
       lseek_dev(dev, pos, SEEK_SET);
       Dmsg3(200, "Did lseek pos=%s blk_size=%d rdlen=%d\n", 
-         edit_uint64(pos, ed1), block->block_len,
+         edit_int64(pos, ed1), block->block_len,
             block->read_len);
       dev->file_addr = pos;
       dev->file_size = pos;