X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fmount.c;h=98c3b80b3eb7780810439dd0af747f52aed2414e;hb=5c358307600ad7cd6983b8773f8d7dc1e7346c56;hp=f0d0baf8ee287a6f9435b3ecac1f3ccbc7c534a9;hpb=fa5bc79dbae75f82e4b0a1a132132b6603e4748d;p=bacula%2Fbacula diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index f0d0baf8ee..98c3b80b3e 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -106,7 +106,7 @@ mount_next_vol: if (dev->must_unload()) { ask = true; /* ask operator to mount tape */ } - do_swapping(); + do_swapping(true /*writing*/); if (!is_suitable_volume_mounted()) { bool have_vol = false; @@ -153,14 +153,14 @@ mount_next_vol: * and move the tape to the end of data. * */ - if (autoload_device(dcr, 1, NULL) > 0) { + if (autoload_device(dcr, true/*writing*/, NULL) > 0) { autochanger = true; ask = false; } else { autochanger = false; VolCatInfo.Slot = 0; } - Dmsg1(200, "autoload_dev returns %d\n", autochanger); + Dmsg1(150, "autoload_dev returns %d\n", autochanger); /* * If we autochanged to correct Volume or (we have not just * released the Volume AND we can automount) we go ahead @@ -227,7 +227,7 @@ mount_next_vol: } /* If DVD, ignore the error, very often you cannot open the device * (when there is no DVD, or when the one inserted is a wrong one) */ - if (dev->poll || dev->is_dvd() || dev->is_removable()) { + if (dev->poll || dev->is_dvd()) { goto mount_next_vol; } else { Jmsg(jcr, M_ERROR, 0, _("Could not open device %s: ERR=%s\n"), @@ -470,11 +470,10 @@ bool DCR::is_suitable_volume_mounted() return dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE); } -void DCR::do_swapping() +void DCR::do_swapping(bool is_writing) { if (dev->must_unload()) { - Dmsg0(150, "mount_next_volume release=1\n"); - unload_autochanger(this, -1); + Dmsg1(100, "swapping: unloading %s\n", dev->print_name()); release_volume(); dev->clear_unload(); } @@ -484,8 +483,12 @@ void DCR::do_swapping() * volume to our drive. */ if (dev->swap_dev) { - Dmsg1(100, "Swap unloading %s\n", dev->swap_dev->print_name()); if (dev->swap_dev->must_unload()) { + if (dev->vol) { + dev->swap_dev->set_slot(dev->vol->get_slot()); + } + Dmsg2(100, "Swap unloading slot=%d %s\n", dev->swap_dev->get_slot(), + dev->swap_dev->print_name()); unload_dev(this, dev->swap_dev); } if (dev->vol) { @@ -496,8 +499,10 @@ void DCR::do_swapping() dev->swap_dev = NULL; } if (dev->must_load()) { - dev->clear_load(); - dev->clear_volhdr(); /* force "load" */ + Dmsg1(100, "swapping: must load %s\n", dev->print_name()); + if (autoload_device(this, is_writing, NULL) > 0) { + dev->clear_load(); + } } } @@ -663,6 +668,8 @@ void DCR::mark_volume_not_inchanger() */ void DCR::release_volume() { + unload_autochanger(this, -1); + if (WroteVol) { Jmsg0(jcr, M_ERROR, 0, _("Hey!!!!! WroteVol non-zero !!!!!\n")); Dmsg0(190, "Hey!!!!! WroteVol non-zero !!!!!\n"); @@ -674,7 +681,7 @@ void DCR::release_volume() dev->block_num = dev->file = 0; dev->EndBlock = dev->EndFile = 0; memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo)); - memset(&VolCatInfo, 0, sizeof(VolCatInfo)); +// memset(&VolCatInfo, 0, sizeof(VolCatInfo)); dev->clear_volhdr(); /* Force re-read of label */ dev->clear_labeled(); @@ -695,6 +702,44 @@ void DCR::release_volume() Dmsg0(190, "release_volume\n"); } +/* + * Insanity check + * + * Check to see if the tape position as defined by the OS is + * the same as our concept. If it is not, + * 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. + */ +bool DCR::is_tape_position_ok() +{ + 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_ERROR, 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); + /* + * If the current file is greater than zero, it means we probably + * have some bad count of EOF marks, so mark tape in error. Otherwise + * the operator might have moved the tape, so we just release it + * and try again. + */ + if (file > 0) { + mark_volume_in_error(); + } + release_volume(); + return false; + } + } + return true; +} + + /* * If we are reading, we come here at the end of the tape * and see if there are more volumes to be mounted.