]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/block.c
update version
[bacula/bacula] / bacula / src / stored / block.c
index 75538522f7caa56f8b9524f8e420713e44b3835b..313a3dde6f84951cec79a69df9ac74edb53658eb 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2001-2008 Free Software Foundation Europe e.V.
+   Copyright (C) 2001-2010 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.
@@ -32,8 +32,6 @@
  *              Kern Sibbald, March MMI
  *                 added BB02 format October MMII
  *
- *   Version $Id$
- *
  */
 
 
@@ -189,7 +187,7 @@ void empty_block(DEV_BLOCK *block)
  * in the buffer should have already been reserved by
  * init_block.
  */
-void ser_block_header(DEV_BLOCK *block)
+static void ser_block_header(DEV_BLOCK *block, bool do_checksum)
 {
    ser_declare;
    uint32_t CheckSum = 0;
@@ -207,8 +205,10 @@ void ser_block_header(DEV_BLOCK *block)
    }
 
    /* Checksum whole block except for the checksum */
-   CheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
-                 block_len-BLKHDR_CS_LENGTH);
+   if (do_checksum) {
+      CheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
+                    block_len-BLKHDR_CS_LENGTH);
+   }
    Dmsg1(1390, "ser_bloc_header: checksum=%x\n", CheckSum);
    ser_begin(block->buf, BLKHDR2_LENGTH);
    ser_uint32(CheckSum);              /* now add checksum to block header */
@@ -307,7 +307,7 @@ static bool unser_block_header(JCR *jcr, DEVICE *dev, DEV_BLOCK *block)
    block->BlockNumber = BlockNumber;
    Dmsg3(390, "Read binbuf = %d %d block_len=%d\n", block->binbuf,
       bhl, block_len);
-   if (block_len <= block->read_len) {
+   if (block_len <= block->read_len && dev->do_checksum()) {
       BlockCheckSum = bcrc32((uint8_t *)block->buf+BLKHDR_CS_LENGTH,
                          block_len-BLKHDR_CS_LENGTH);
       if (BlockCheckSum != CheckSum) {
@@ -365,8 +365,8 @@ bool write_block_to_device(DCR *dcr)
       /* Create a jobmedia record for this job */
       if (!dir_create_jobmedia_record(dcr)) {
          dev->dev_errno = EIO;
-         Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
-            dcr->VolCatInfo.VolCatName, jcr->Job);
+         Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
+            dcr->getVolCatName(), jcr->Job);
          set_new_volume_parameters(dcr);
          stat = false;
          goto bail_out;
@@ -380,7 +380,7 @@ bool write_block_to_device(DCR *dcr)
    }
 
    if (!write_block_to_dev(dcr)) {
-       if (job_canceled(jcr) || jcr->get_JobType() == JT_SYSTEM) {
+       if (job_canceled(jcr) || jcr->getJobType() == JT_SYSTEM) {
           stat = false;
        } else {
           stat = fixup_device_block_write_error(dcr);
@@ -415,25 +415,34 @@ bool write_block_to_dev(DCR *dcr)
    empty_block(block);
    return true;
 #endif
+   if (job_canceled(jcr)) {
+      return false;
+   }
+
    ASSERT(block->binbuf == ((uint32_t) (block->bufp - block->buf)));
-   ASSERT(dev->is_open());
+
+   wlen = block->binbuf;
+   if (wlen <= WRITE_BLKHDR_LENGTH) {  /* Does block have data in it? */
+      Dmsg0(100, "return write_block_to_dev no data to write\n");
+      return true;
+   }
 
    /* dump_block(block, "before write"); */
    if (dev->at_weot()) {
       Dmsg0(100, "return write_block_to_dev with ST_WEOT\n");
       dev->dev_errno = ENOSPC;
-      Jmsg0(jcr, M_FATAL, 0,  _("Cannot write block. Device at EOM.\n"));
+      Jmsg1(jcr, M_FATAL, 0,  _("Cannot write block. Device at EOM. dev=%s\n"), dev->print_name());
       return false;
    }
    if (!dev->can_append()) {
       dev->dev_errno = EIO;
-      Jmsg(jcr, M_FATAL, 0, _("Attempt to write on read-only Volume.\n"));
+      Jmsg1(jcr, M_FATAL, 0, _("Attempt to write on read-only Volume. dev=%s\n"), dev->print_name());
       return false;
    }
-   wlen = block->binbuf;
-   if (wlen <= WRITE_BLKHDR_LENGTH) {  /* Does block have data in it? */
-      Dmsg0(100, "return write_block_to_dev no data to write\n");
-      return true;
+
+   if (!dev->is_open()) {
+      Jmsg1(jcr, M_FATAL, 0, _("Attempt to write on closed device=%s\n"), dev->print_name());
+      return false;
    }
    /*
     * Clear to the end of the buffer if it is not full,
@@ -463,7 +472,7 @@ bool write_block_to_dev(DCR *dcr)
       }
    }
 
-   ser_block_header(block);
+   ser_block_header(block, dev->do_checksum());
 
    /* Limit maximum Volume size to value specified by user */
    hit_max1 = (dev->max_volume_size > 0) &&
@@ -572,7 +581,7 @@ bool write_block_to_dev(DCR *dcr)
       }
       if (dev->dev_errno == ENOSPC) {
          Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s. Write of %u bytes got %d.\n"),
-            dev->VolCatInfo.VolCatName,
+            dev->getVolCatName(),
             dev->file, dev->block_num, dev->print_name(), wlen, stat);
       }
       if (debug_level >= 100) {
@@ -689,15 +698,17 @@ static void reread_last_block(DCR *dcr)
              * If we wrote block and the block numbers don't agree
              *  we have a possible problem.
              */
-#ifdef xxx
-            if (lblock->VolSessionId == block->VolSessionId &&
-                lblock->VolSessionTime == block->VolSessionTime &&
-                lblock->BlockNumber+1 != block->BlockNumber) {
-#endif
             if (lblock->BlockNumber != dev->LastBlock) {
-               Jmsg(jcr, M_ERROR, 0, _(
+                if (dev->LastBlock > (lblock->BlockNumber + 1)) {
+                   Jmsg(jcr, M_FATAL, 0, _(
+"Re-read of last block: block numbers differ by more than one.\n"
+"Probable tape misconfiguration and data loss. Read block=%u Want block=%u.\n"),
+                       lblock->BlockNumber, dev->LastBlock);
+                 } else {
+                   Jmsg(jcr, M_ERROR, 0, _(
 "Re-read of last block OK, but block numbers differ. Read block=%u Want block=%u.\n"),
-                    lblock->BlockNumber, dev->LastBlock);
+                       lblock->BlockNumber, dev->LastBlock);
+                 }
             } else {
                Jmsg(jcr, M_INFO, 0, _("Re-read of last block succeeded.\n"));
             }
@@ -724,8 +735,8 @@ static bool terminate_writing_volume(DCR *dcr)
    if (!dir_create_jobmedia_record(dcr)) {
       Dmsg0(190, "Error from create JobMedia\n");
       dev->dev_errno = EIO;
-       Jmsg(dcr->jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
-            dcr->VolCatInfo.VolCatName, dcr->jcr->Job);
+       Jmsg2(dcr->jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
+            dcr->getVolCatName(), dcr->jcr->Job);
        ok = false;
    }
    dcr->block->write_failed = true;
@@ -798,8 +809,8 @@ static bool do_new_file_bookkeeping(DCR *dcr)
    if (!dir_create_jobmedia_record(dcr)) {
       Dmsg0(190, "Error from create_job_media.\n");
       dev->dev_errno = EIO;
-      Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
-           dcr->VolCatInfo.VolCatName, jcr->Job);
+      Jmsg2(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"),
+           dcr->getVolCatName(), jcr->Job);
       terminate_writing_volume(dcr);
       dev->dev_errno = EIO;
       return false;
@@ -877,7 +888,7 @@ static bool do_dvd_size_checks(DCR *dcr)
       Dmsg1(100, "Cannot get free space on the device ERR=%s.\n", dev->errmsg);
       Jmsg(jcr, M_FATAL, 0, _("End of Volume \"%s\" at %u:%u on device %s "
          "(part_size=%s, free_space=%s, free_space_errno=%d, errmsg=%s).\n"),
-           dev->VolCatInfo.VolCatName,
+           dev->getVolCatName(),
            dev->file, dev->block_num, dev->print_name(),
            edit_uint64_with_commas(dev->part_size, ed1), edit_uint64_with_commas(dev->free_space, ed2),
            dev->free_space_errno, dev->errmsg);
@@ -890,7 +901,7 @@ static bool do_dvd_size_checks(DCR *dcr)
       Dmsg0(100, "==== Just enough free space on the device to write the current part...\n");
       Jmsg(jcr, M_INFO, 0, _("End of Volume \"%s\" at %u:%u on device %s "
          "(part_size=%s, free_space=%s, free_space_errno=%d).\n"),
-            dev->VolCatInfo.VolCatName,
+            dev->getVolCatName(),
             dev->file, dev->block_num, dev->print_name(),
             edit_uint64_with_commas(dev->part_size, ed1), edit_uint64_with_commas(dev->free_space, ed2),
             dev->free_space_errno);
@@ -933,6 +944,9 @@ bool read_block_from_dev(DCR *dcr, bool check_block_numbers)
    DEVICE *dev = dcr->dev;
    DEV_BLOCK *block = dcr->block;
 
+   if (job_canceled(jcr)) {
+      return false;
+   }
    ASSERT(dev->is_open());
    
    if (dev->at_eot()) {
@@ -1116,10 +1130,10 @@ reread:
       dcr->EndBlock = dev->EndBlock;
       dcr->EndFile  = dev->EndFile;
    } else {
-      uint32_t len = block->read_len;
-      if (len > block->block_len) {
-         len = block->block_len;
-      }
+      /* We need to take care about a short block in EndBlock/File
+       * computation 
+       */
+      uint32_t len = MIN(block->read_len, block->block_len);
       uint64_t addr = dev->file_addr + len - 1;
       dcr->EndBlock = (uint32_t)addr;
       dcr->EndFile = (uint32_t)(addr >> 32);