In some cases, Bacula will get an error on a tape and not be able to write and EOF mark. In this case, the tape will no longer be readable. When this happens, Bacula tries to plunge on but gets into lots of trouble. This patch should fix that by immediately marking the Job in error, and by avoiding running through code that doesn't make any sense after a fatal error. Apply the patch to Bacula 1.34.6 (possibly earlier versions) with: cd patch -p0 <1.34.6-block.patch make make install ... Index: src/stored/block.c =================================================================== RCS file: /cvsroot/bacula/bacula/src/stored/block.c,v retrieving revision 1.74.2.1 diff -u -r1.74.2.1 block.c --- src/stored/block.c 20 Jun 2004 11:43:04 -0000 1.74.2.1 +++ src/stored/block.c 23 Aug 2004 19:02:10 -0000 @@ -356,7 +356,7 @@ /* Create a jobmedia record for this job */ if (!dir_create_jobmedia_record(jcr)) { dev->dev_errno = EIO; - Jmsg(jcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"), + Jmsg(jcr, M_FATAL, 0, _("Could not create JobMedia record for Volume=\"%s\" Job=%s\n"), jcr->VolCatInfo.VolCatName, jcr->Job); set_new_volume_parameters(jcr, dev); stat = 0; @@ -372,7 +372,11 @@ } if (!write_block_to_dev(dcr, block)) { - stat = fixup_device_block_write_error(jcr, dev, block); + if (job_canceled(jcr)) { + stat = 0; + } else { + stat = fixup_device_block_write_error(jcr, dev, block); + } } bail_out: @@ -393,7 +397,7 @@ ssize_t stat = 0; uint32_t wlen; /* length to write */ int hit_max1, hit_max2; - bool ok; + bool ok = true; DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; @@ -463,9 +467,9 @@ edit_uint64_with_commas(max_cap, ed1), dev->dev_name); block->write_failed = true; if (weof_dev(dev, 1) != 0) { /* end tape */ - Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); + Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); dev->VolCatInfo.VolCatErrors++; - } + } /* Don't do update after second EOF or file count will be wrong */ Dmsg0(100, "dir_update_volume_info\n"); dev->VolCatInfo.VolCatFiles = dev->file; @@ -485,7 +489,7 @@ if (dev_state(dev, ST_TAPE) && weof_dev(dev, 1) != 0) { /* write eof */ /* Write EOF */ - Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); + Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); block->write_failed = true; dev->VolCatInfo.VolCatErrors++; dev->state |= (ST_EOF | ST_EOT | ST_WEOT); @@ -559,18 +563,18 @@ block->write_failed = true; if (weof_dev(dev, 1) != 0) { /* end the tape */ dev->VolCatInfo.VolCatErrors++; - Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); + Jmsg(jcr, M_FATAL, 0, "%s", dev->errmsg); + ok = false; } Dmsg0(100, "dir_update_volume_info\n"); dev->VolCatInfo.VolCatFiles = dev->file; dir_update_volume_info(jcr, dev, 0); - if (dev_cap(dev, CAP_TWOEOF) && weof_dev(dev, 1) != 0) { /* end the tape */ + if (ok && dev_cap(dev, CAP_TWOEOF) && weof_dev(dev, 1) != 0) { /* end the tape */ dev->VolCatInfo.VolCatErrors++; Jmsg(jcr, M_ERROR, 0, "%s", dev->errmsg); } dev->state |= (ST_EOF | ST_EOT | ST_WEOT); - ok = true; #define CHECK_LAST_BLOCK #ifdef CHECK_LAST_BLOCK /* @@ -580,7 +584,7 @@ * then re-read it and verify that the block number is * correct. */ - if (dev->state & ST_TAPE && dev_cap(dev, CAP_BSR)) { + if (ok && dev->state & ST_TAPE && dev_cap(dev, CAP_BSR)) { /* Now back up over what we wrote and read the last block */ if (!bsf_dev(dev, 1)) {