X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fmount.c;h=98c3b80b3eb7780810439dd0af747f52aed2414e;hb=5c358307600ad7cd6983b8773f8d7dc1e7346c56;hp=38db3c7e155db139a5abf260099e1955ea5f69af;hpb=356ad8deb8e101f49306eceb0ba687ca3f677f48;p=bacula%2Fbacula diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 38db3c7e15..98c3b80b3e 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -102,34 +102,12 @@ mount_next_vol: goto bail_out; } recycle = false; + if (dev->must_unload()) { - Dmsg0(150, "mount_next_volume release=1\n"); - unload_autochanger(dcr, -1); - release_volume(); - dev->clear_unload(); ask = true; /* ask operator to mount tape */ } - /* - * See if we are asked to swap the Volume from another device - * if so, unload the other device here, and attach the - * 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()) { - unload_dev(dcr, dev->swap_dev); - } - if (dev->vol) { - dev->vol->clear_swapping(); - dev->vol->set_in_use(); - dev->VolHdr.VolumeName[0] = 0; /* don't yet have right Volume */ - } - dev->swap_dev = NULL; - } - if (dev->must_load()) { - dev->clear_load(); - dev->clear_volhdr(); /* force "load" */ - } + do_swapping(true /*writing*/); + if (!is_suitable_volume_mounted()) { bool have_vol = false; /* Do we have a candidate volume? */ @@ -175,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 @@ -249,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"), @@ -492,6 +470,41 @@ bool DCR::is_suitable_volume_mounted() return dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE); } +void DCR::do_swapping(bool is_writing) +{ + if (dev->must_unload()) { + Dmsg1(100, "swapping: unloading %s\n", dev->print_name()); + release_volume(); + dev->clear_unload(); + } + /* + * See if we are asked to swap the Volume from another device + * if so, unload the other device here, and attach the + * volume to our drive. + */ + if (dev->swap_dev) { + 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) { + dev->vol->clear_swapping(); + dev->vol->set_in_use(); + dev->VolHdr.VolumeName[0] = 0; /* don't yet have right Volume */ + } + dev->swap_dev = NULL; + } + if (dev->must_load()) { + Dmsg1(100, "swapping: must load %s\n", dev->print_name()); + if (autoload_device(this, is_writing, NULL) > 0) { + dev->clear_load(); + } + } +} /* @@ -625,11 +638,12 @@ void DCR::mark_volume_in_error() { Jmsg(jcr, M_INFO, 0, _("Marking Volume \"%s\" in Error in Catalog.\n"), VolumeName); - dev->VolCatInfo = VolCatInfo; /* structure assignment */ + dev->VolCatInfo = VolCatInfo; /* structure assignment */ bstrncpy(dev->VolCatInfo.VolCatStatus, "Error", sizeof(dev->VolCatInfo.VolCatStatus)); Dmsg0(150, "dir_update_vol_info. Set Error.\n"); dir_update_volume_info(this, false, false); volume_unused(this); + dev->set_unload(); /* must get a new volume */ } /* @@ -654,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"); @@ -665,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(); @@ -682,9 +698,48 @@ void DCR::release_volume() if (dev->is_open()) { dev->offline_or_rewind(); } + dev->set_unload(); 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.