X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Facquire.c;h=2aba36809223d54a9cf23ea2b29688d2f05d3eec;hb=36b40d5c7f3ff90565ab73ac75f0dc4f6660ff37;hp=fc72f8a7c244adef04b47d028cf8df4048983c58;hpb=ba91e64a8bc84c321c0319bd45cb7175430e430b;p=bacula%2Fbacula diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index fc72f8a7c2..2aba368092 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -20,7 +20,7 @@ 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. @@ -38,7 +38,7 @@ /* Forward referenced functions */ static void attach_dcr_to_dev(DCR *dcr); -static bool is_tape_position_ok(JCR *jcr, DEVICE *dev); +static void set_dcr_from_vol(DCR *dcr, VOL_LIST *vol); /********************************************************************* @@ -89,27 +89,9 @@ bool acquire_device_for_read(DCR *dcr) jcr->NumReadVolumes, jcr->CurReadVolume); goto get_out; /* should not happen */ } - /* - * Note, if we want to be able to work from a .bsr file only - * for disaster recovery, we must "simulate" reading the catalog - */ - bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName)); - bstrncpy(dcr->VolCatInfo.VolCatName, vol->VolumeName, sizeof(dcr->VolCatInfo.VolCatName)); - bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type)); - dcr->VolCatInfo.Slot = vol->Slot; - dcr->VolCatInfo.InChanger = vol->Slot > 0; - if (reserve_volume(dcr, dcr->VolumeName) == NULL) { - Dmsg2(100, "Could not reserve volume %s on %s\n", dcr->VolumeName, - dcr->dev->print_name()); - Jmsg2(jcr, M_FATAL, 0, _("Could not reserve volume %s on %s\n"), dcr->VolumeName, - dcr->dev->print_name()); - goto get_out; - } - if (dev->vol && dev->vol->is_swapping()) { - dev->vol->set_slot(vol->Slot); - Dmsg3(100, "swapping: slot=%d Vol=%s dev=%s\n", dev->vol->get_slot(), - dev->vol->vol_name, dev->print_name()); - } + set_dcr_from_vol(dcr, vol); + + Dmsg2(100, "Want Vol=%s Slot=%d\n", vol->VolumeName, vol->Slot); /* * If the MediaType requested for this volume is not the @@ -170,8 +152,10 @@ bool acquire_device_for_read(DCR *dcr) Dmsg1(50, "Media Type change. New device %s chosen.\n", dev->print_name()); bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName)); + bstrncpy(dcr->VolCatInfo.VolCatName, vol->VolumeName, sizeof(dcr->VolCatInfo.VolCatName)); bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type)); dcr->VolCatInfo.Slot = vol->Slot; + dcr->VolCatInfo.InChanger = vol->Slot > 0; bstrncpy(dcr->pool_name, store->pool_name, sizeof(dcr->pool_name)); bstrncpy(dcr->pool_type, store->pool_type, sizeof(dcr->pool_type)); } else { @@ -183,6 +167,13 @@ bool acquire_device_for_read(DCR *dcr) } } + dev->clear_unload(); + + if (dev->vol && dev->vol->is_swapping()) { + dev->vol->set_slot(vol->Slot); + Dmsg3(100, "swapping: slot=%d Vol=%s dev=%s\n", dev->vol->get_slot(), + dev->vol->vol_name, dev->print_name()); + } init_device_wait_timers(dcr); @@ -192,10 +183,13 @@ bool acquire_device_for_read(DCR *dcr) /* Volume info is always needed because of VolParts */ - Dmsg0(200, "dir_get_volume_info\n"); + Dmsg1(150, "dir_get_volume_info vol=%s\n", dcr->VolumeName); if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) { + Dmsg2(150, "dir_get_vol_info failed for vol=%s: %s\n", + dcr->VolumeName, jcr->errmsg); Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg); } + dev->set_load(); /* set to load volume */ for ( ;; ) { /* If not polling limit retries */ @@ -210,7 +204,10 @@ bool acquire_device_for_read(DCR *dcr) goto get_out; /* error return */ } - dcr->do_swapping(false/*is_writing*/); + dcr->do_unload(); + dcr->do_swapping(false/*!is_writing*/); + dcr->do_load(false /*!is_writing*/); + set_dcr_from_vol(dcr, vol); /* refresh dcr with desired volume info */ /* * This code ensures that the device is ready for @@ -219,8 +216,10 @@ bool acquire_device_for_read(DCR *dcr) */ Dmsg1(100, "bstored: open vol=%s\n", dcr->VolumeName); if (dev->open(dcr, OPEN_READ_ONLY) < 0) { - Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"), - dev->print_name(), dcr->VolumeName, dev->bstrerror()); + if (!dev->poll) { + Jmsg3(jcr, M_WARNING, 0, _("Read open device %s Volume \"%s\" failed: ERR=%s\n"), + dev->print_name(), dcr->VolumeName, dev->bstrerror()); + } goto default_path; } Dmsg1(50, "opened dev %s OK\n", dev->print_name()); @@ -230,10 +229,12 @@ bool acquire_device_for_read(DCR *dcr) vol_label_status = read_dev_volume_label(dcr); switch (vol_label_status) { case VOL_OK: + Dmsg0(50, "Got correct volume.\n"); ok = true; - memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo)); + dev->VolCatInfo = dcr->VolCatInfo; /* structure assignment */ break; /* got it */ case VOL_IO_ERROR: + Dmsg0(50, "IO Error\n"); /* * Send error message generated by read_dev_volume_label() * only we really had a tape mounted. This supresses superfluous @@ -244,24 +245,21 @@ bool acquire_device_for_read(DCR *dcr) } goto default_path; case VOL_NAME_ERROR: - if (tape_initially_mounted) { - tape_initially_mounted = false; + Dmsg0(50, "Vol name error.\n"); + if (dev->is_volume_to_unload()) { goto default_path; } - /* If polling and got a previous bad name, ignore it */ - if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) { - goto default_path; - } else { - bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName)); - } + dev->set_unload(); /* force unload of unwanted tape */ if (!unload_autochanger(dcr, -1)) { /* at least free the device so we can re-open with correct volume */ dev->close(); } + dev->set_load(); /* Fall through */ default: Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg); default_path: + Dmsg0(50, "default path\n"); tape_previously_mounted = true; /* @@ -281,12 +279,6 @@ default_path: try_autochanger = false; continue; /* try reading volume mounted */ } - /* Try closing and re-opening */ - dev->close(); - dev->clear_unload(); - if (dev->open(dcr, OPEN_READ_ONLY) >= 0) { - continue; - } } /* Mount a specific volume and no other */ @@ -294,11 +286,12 @@ default_path: if (!dir_ask_sysop_to_mount_volume(dcr, ST_READ)) { goto get_out; /* error return */ } - try_autochanger = true; /* permit using autochanger again */ + try_autochanger = true; /* permit trying the autochanger again */ continue; /* try reading again */ } /* end switch */ break; } /* end for loop */ + if (!ok) { Jmsg1(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s for reading.\n"), dev->print_name()); @@ -322,6 +315,8 @@ get_out: */ if (dev->is_blocked()) { dev->dunblock(DEV_LOCKED); + } else { + dev->dunlock(); /* dunblock() unlock the device too */ } Dmsg1(950, "jcr->dcr=%p\n", jcr->dcr); return ok; @@ -342,6 +337,7 @@ DCR *acquire_device_for_append(DCR *dcr) DEVICE *dev = dcr->dev; JCR *jcr = dcr->jcr; bool ok = false; + bool have_vol = false; init_device_wait_timers(dcr); @@ -358,6 +354,8 @@ DCR *acquire_device_for_append(DCR *dcr) goto get_out; } + dev->clear_unload(); + /* * have_vol defines whether or not mount_next_write_volume should * ask the Director again about what Volume to use. @@ -373,10 +371,10 @@ DCR *acquire_device_for_append(DCR *dcr) if (dev->num_writers == 0) { memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo)); } - if (!is_tape_position_ok(jcr, dev)) { - goto get_out; - } - } else { + have_vol = dcr->is_tape_position_ok(); + } + + if (!have_vol) { Dmsg1(190, "jid=%u Do mount_next_write_vol\n", (uint32_t)jcr->JobId); if (!dcr->mount_next_write_volume()) { if (!job_canceled(jcr)) { @@ -406,34 +404,6 @@ get_out: return ok ? dcr : NULL; } -/* - * Insanity check - * - * Check to see if the tape position as defined by the OS is - * the same as our concept. If it is not, we bail out, because - * it means the user has probably manually rewound the tape. - * Note, we check only if num_writers == 0, but this code will - * also work fine for any number of writers. If num_writers > 0, - * we probably should cancel all jobs using this device, or - * perhaps even abort the SD, or at a minimum, mark the tape - * in error. Another strategy with num_writers == 0, would be - * to rewind the tape and do a new eod() request. - */ -static bool is_tape_position_ok(JCR *jcr, DEVICE *dev) -{ - if (dev->is_tape() && dev->num_writers == 0) { - int32_t file = dev->get_os_tape_file(); - if (file >= 0 && file != (int32_t)dev->get_file()) { - Jmsg(jcr, M_FATAL, 0, _("Invalid tape position on volume \"%s\"" - " on device %s. Expected %d, got %d\n"), - dev->VolHdr.VolumeName, dev->print_name(), dev->get_file(), file); - return false; - } - } - return true; -} - - /* * This job is done, so release the device. From a Unix standpoint, * the device remains open. @@ -494,7 +464,6 @@ bool release_device(DCR *dcr) dev->VolCatInfo.VolCatName, dev->print_name()); } if (dev->num_writers == 0) { /* if not being used */ -// if (!dev->is_busy()) { /* if not being used */ volume_unused(dcr); /* we obviously are not using the volume */ } } @@ -661,7 +630,7 @@ static void attach_dcr_to_dev(DCR *dcr) JCR *jcr = dcr->jcr; if (jcr) Dmsg1(500, "JobId=%u enter attach_dcr_to_dev\n", (uint32_t)jcr->JobId); - if (!dcr->attached_to_dev && dev->initiated && jcr && jcr->JobType != JT_SYSTEM) { + if (!dcr->attached_to_dev && dev->initiated && jcr && jcr->get_JobType() != JT_SYSTEM) { dev->attached_dcrs->append(dcr); /* attach dcr to device */ dcr->attached_to_dev = true; Dmsg1(500, "JobId=%u attach_dcr_to_dev\n", (uint32_t)jcr->JobId); @@ -705,3 +674,16 @@ void free_dcr(DCR *dcr) } free(dcr); } + +static void set_dcr_from_vol(DCR *dcr, VOL_LIST *vol) +{ + /* + * Note, if we want to be able to work from a .bsr file only + * for disaster recovery, we must "simulate" reading the catalog + */ + bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName)); + bstrncpy(dcr->VolCatInfo.VolCatName, vol->VolumeName, sizeof(dcr->VolCatInfo.VolCatName)); + bstrncpy(dcr->media_type, vol->MediaType, sizeof(dcr->media_type)); + dcr->VolCatInfo.Slot = vol->Slot; + dcr->VolCatInfo.InChanger = vol->Slot > 0; +}