/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2009 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.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- Bacula® is a registered trademark of John Walker.
+ Bacula® is a registered trademark of Kern Sibbald.
The licensor of Bacula is the Free Software Foundation Europe
(FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
Switzerland, email:ftf@fsfeurope.org.
* Returns: true on success
* false on failure
*/
-bool fixup_device_block_write_error(DCR *dcr)
+bool fixup_device_block_write_error(DCR *dcr, int retries)
{
char PrevVolName[MAX_NAME_LENGTH];
DEV_BLOCK *label_blk;
char dt[MAX_TIME_LENGTH];
JCR *jcr = dcr->jcr;
DEVICE *dev = dcr->dev;
+ int blocked = dev->blocked(); /* save any previous blocked status */
+ bool ok = false;
wait_time = time(NULL);
- Dmsg0(100, "Enter fixup_device_block_write_error\n");
+ Dmsg0(100, "=== Enter fixup_device_block_write_error\n");
+ /*
+ * If we are blocked at entry, unblock it, and set our own block status
+ */
+ if (blocked != BST_NOT_BLOCKED) {
+ unblock_device(dev);
+ }
block_device(dev, BST_DOING_ACQUIRE);
- /* Unlock, but leave BLOCKED */
+
+ /* Continue unlocked, but leave BLOCKED */
dev->dunlock();
bstrncpy(PrevVolName, dev->VolCatInfo.VolCatName, sizeof(PrevVolName));
edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
bstrftime(dt, sizeof(dt), time(NULL)));
- if (!mount_next_write_volume(dcr, 1)) {
+ Dmsg0(050, "set_unload\n");
+ dev->set_unload();
+ if (!dcr->mount_next_write_volume()) {
free_block(label_blk);
dcr->block = block;
dev->dlock();
- unblock_device(dev);
- return false; /* device locked */
+ goto bail_out;
}
+ Dmsg1(050, "must_unload=%d\n", dev->must_unload());
dev->dlock(); /* lock again */
dev->VolCatInfo.VolCatJobs++; /* increment number of jobs on vol */
- dir_update_volume_info(dcr, false); /* send Volume info to Director */
+ dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"),
dcr->VolumeName, dev->print_name(), bstrftime(dt, sizeof(dt), time(NULL)));
be.bstrerror(dev->dev_errno));
free_block(label_blk);
dcr->block = block;
- unblock_device(dev);
- return false; /* device locked */
+ goto bail_out;
}
free_block(label_blk);
dcr->block = block;
/*
* Walk through all attached jcrs indicating the volume has changed
*/
- Dmsg1(100, "Walk attached dcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
+ Dmsg1(100, "Notify vol change. Volume=%s\n", dev->VolCatInfo.VolCatName);
DCR *mdcr;
foreach_dlist(mdcr, dev->attached_dcrs) {
JCR *mjcr = mdcr->jcr;
Dmsg0(190, "Write overflow block to dev\n");
if (!write_block_to_dev(dcr)) {
berrno be;
- Pmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"),
+ Dmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"),
be.bstrerror(dev->dev_errno));
- unblock_device(dev);
- return false; /* device locked */
+ /* Note: recursive call */
+ if (retries-- <= 0 || !fixup_device_block_write_error(dcr, retries)) {
+ Jmsg2(jcr, M_FATAL, 0,
+ _("Catastrophic error. Cannot write overflow block to device %s. ERR=%s"),
+ dev->print_name(), be.bstrerror(dev->dev_errno));
+ goto bail_out;
+ }
}
+ ok = true;
+bail_out:
+ /*
+ * At this point, the device is locked and blocked.
+ * Unblock the device, restore any entry blocked condition, then
+ * return leaving the device locked (as it was on entry).
+ */
unblock_device(dev);
- return true; /* device locked */
+ if (blocked != BST_NOT_BLOCKED) {
+ block_device(dev, blocked);
+ }
+ return ok; /* device locked */
+}
+
+void set_start_vol_position(DCR *dcr)
+{
+ DEVICE *dev = dcr->dev;
+ /* Set new start position */
+ if (dev->is_tape()) {
+ dcr->StartBlock = dev->block_num;
+ dcr->StartFile = dev->file;
+ } else {
+ dcr->StartBlock = (uint32_t)dev->file_addr;
+ dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
+ }
}
/*
void set_new_volume_parameters(DCR *dcr)
{
JCR *jcr = dcr->jcr;
- DEVICE *dev = dcr->dev;
if (dcr->NewVol && !dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
Jmsg1(jcr, M_ERROR, 0, "%s", jcr->errmsg);
}
- /* Set new start/end positions */
- if (dev->is_tape()) {
- dcr->StartBlock = dev->block_num;
- dcr->StartFile = dev->file;
- } else {
- dcr->StartBlock = (uint32_t)dev->file_addr;
- dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
- }
- /* Reset indicies */
- dcr->VolFirstIndex = 0;
- dcr->VolLastIndex = 0;
+ set_new_file_parameters(dcr);
jcr->NumWriteVolumes++;
dcr->NewVol = false;
- dcr->WroteVol = false;
}
/*
*/
void set_new_file_parameters(DCR *dcr)
{
- DEVICE *dev = dcr->dev;
+ set_start_vol_position(dcr);
- /* Set new start/end positions */
- if (dev->is_tape()) {
- dcr->StartBlock = dev->block_num;
- dcr->StartFile = dev->file;
- } else {
- dcr->StartBlock = (uint32_t)dev->file_addr;
- dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
- }
/* Reset indicies */
dcr->VolFirstIndex = 0;
dcr->VolLastIndex = 0;