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());
+   }
     
    /*
     * If the MediaType requested for this volume is not the
          goto get_out;                /* error return */
       }
 
-      dcr->do_swapping();
-
-      autoload_device(dcr, 0, NULL);
+      dcr->do_swapping(false/*is_writing*/);
 
       /*
        * This code ensures that the device is ready for
 
           bstrncpy(lastVolume, dcr->VolumeName, sizeof(lastVolume));
           if (dcr->can_i_use_volume()) {
              Dmsg1(100, "Call reserve_volume. Vol=%s\n", dcr->VolumeName);
-             if (reserve_volume(dcr, dcr->VolumeName) == 0) {
+             if (reserve_volume(dcr, dcr->VolumeName) == NULL) {
                 Dmsg2(100, "Could not reserve volume %s on %s\n", dcr->VolumeName,
                     dcr->dev->print_name());
                 continue;
 
    POOLMEM *changer;
 
    if (!dev->is_autochanger()) {
-      Dmsg1(200, "Device %s is not an autochanger\n", dev->print_name());
+      Dmsg1(Dmsg0(100, "ChangerCommand=0, virtual disk changer\n");
       return 0;
    }
 
    }
 
    slot = dcr->VolCatInfo.InChanger ? dcr->VolCatInfo.Slot : 0;
+   Dmsg3(100, "autoload: slot=%d InChgr=%d Vol=%s\n", dcr->VolCatInfo.Slot,
+         dcr->VolCatInfo.InChanger, dcr->VolCatInfo.VolCatName);
    /*
     * Handle autoloaders here.  If we cannot autoload it, we
     *  will return 0 so that the sysop will be asked to load it.
       return -1;
    }
    if (!dcr->device->changer_command) {
-      Jmsg(jcr, M_FATAL, 0, _("3992 Missing Changer command.\n"));
+//    Jmsg(jcr, M_FATAL, 0, _("3992 Missing Changer command.\n"));
       return -1;
    }
    if (dev->Slot > 0) {
 
  *  the Volume parts multiple times without losing track of what the    
  *  main Volume parameters are.
  */
-void DEVICE::close_part(DCR *dcr)
+void DEVICE::close_part(DCR * /*dcr*/)
 {
    VOLUME_LABEL saveVolHdr;
    VOLUME_CAT_INFO saveVolCatInfo;     /* Volume Catalog Information */
    close();                           /* close current part */
    VolHdr = saveVolHdr;               /* structure assignment */
    VolCatInfo = saveVolCatInfo;       /* structure assignment */
-   dcr->VolCatInfo = saveVolCatInfo;  /* structure assignment */
 }
 
 boffset_t DEVICE::lseek(DCR *dcr, boffset_t offset, int whence)
 
    bool is_eod_valid();
    int check_volume_label(bool &ask, bool &autochanger);
    void release_volume();
-   void do_swapping();
+   void do_swapping(bool is_writing);
 };
 
 /*
 
          } else if (dev->is_busy()) {
             send_dir_busy_message(dir, dev);
          } else {                     /* device not being used */
-            Dmsg0(90, "Device not in use, releaseing\n");
+            Dmsg0(90, "Device not in use, releasing\n");
             unload_autochanger(dcr, -1);
             dcr->release_volume();
             dir->fsend(_("3022 Device %s released.\n"), 
 
    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;
     * 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 {
    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()) {
       Dmsg1(100, "swapping: unloading %s\n", dev->print_name());
    }
    if (dev->must_load()) {
       Dmsg1(100, "swapping: must load %s\n", dev->print_name());
-      dev->clear_load();
-      dev->clear_volhdr();               /* force "load" */
+      if (autoload_device(this, is_writing, NULL) > 0) {
+         dev->clear_load();
+      }
    }
 }
 
    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();
 
             /* Changing pool, unload old tape if any in drive */
             Dmsg1(dbglvl, "jid=%u OK dev: num_writers=0, not reserved, pool change, unload changer\n", (int)jcr->JobId);
             /* ***FIXME*** use set_unload() */
-            unload_autochanger(dcr, 0);
+            unload_autochanger(dcr, -1);
          }
       }
       /* Device is available but not yet reserved, reserve it for us */
 
 
 General:
 03May08
+kes  Rework SD acquire for read to handle autochanger Volume
+     swapping.
 kes  Implement regression that explicitly tests swapping a Volume
      from one drive to another.
 kes  Enhance disk-changer to detect most error conditions.