]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/acquire.c
ebl rename faketape to vtape
[bacula/bacula] / bacula / src / stored / acquire.c
index 207e3415dc54e68cc8abebb05068156d4ae648a9..9823d4bb2c36ddbee23440b7eb5257bc7098e7de 100644 (file)
@@ -38,7 +38,6 @@
 
 /* Forward referenced functions */
 static void attach_dcr_to_dev(DCR *dcr);
-static bool is_tape_position_ok(JCR *jcr, DEVICE *dev);
 
 
 /*********************************************************************
@@ -89,9 +88,15 @@ 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 the MediaType requested for this volume is not the
@@ -152,8 +157,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 {
@@ -165,6 +172,19 @@ bool acquire_device_for_read(DCR *dcr)
       }
    }
 
+   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());
+   }
+
 
    init_device_wait_timers(dcr);
 
@@ -174,10 +194,11 @@ 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)) {
       Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
    }
+   dev->set_load();                /* set to load volume */
    
    for ( ;; ) {
       /* If not polling limit retries */
@@ -192,9 +213,7 @@ bool acquire_device_for_read(DCR *dcr)
          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
@@ -203,8 +222,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());
@@ -271,6 +292,10 @@ default_path:
             if (dev->open(dcr, OPEN_READ_ONLY) >= 0) {
                continue;
             }
+            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());
+            }
          }
          
          /* Mount a specific volume and no other */
@@ -326,6 +351,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);
 
@@ -357,10 +383,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)) {
@@ -390,34 +416,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.
@@ -431,6 +429,7 @@ bool release_device(DCR *dcr)
    JCR *jcr = dcr->jcr;
    DEVICE *dev = dcr->dev;
    bool ok = true;
+   char tbuf[100];
 
    /* lock only if not already locked by this thread */
    if (!dcr->is_dev_locked()) {
@@ -476,7 +475,7 @@ bool release_device(DCR *dcr)
             Dmsg2(200, "dir_update_vol_info. Release vol=%s dev=%s\n", 
                   dev->VolCatInfo.VolCatName, dev->print_name());
          }
-         if (!dev->is_busy()) {               /* if not being used */
+         if (dev->num_writers == 0) {         /* if not being used */
             volume_unused(dcr);               /*  we obviously are not using the volume */
          }
       }
@@ -490,6 +489,10 @@ bool release_device(DCR *dcr)
       volume_unused(dcr);
    }
    unlock_volumes();
+   Dmsg3(100, "%d writers, %d reserve, dev=%s\n", dev->num_writers, dev->num_reserved(),
+         dev->print_name());
+   debug_list_volumes("acquire:release_device()");
+
 
    /* If no writers, close if file or !CAP_ALWAYS_OPEN */
    if (dev->num_writers == 0 && (!dev->is_tape() || !dev->has_cap(CAP_ALWAYSOPEN))) {
@@ -524,7 +527,8 @@ bool release_device(DCR *dcr)
       free_pool_memory(alert);
    }
    pthread_cond_broadcast(&dev->wait_next_vol);
-   Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
+   Dmsg2(100, "JobId=%u broadcast wait_device_release at %s\n", 
+         (uint32_t)jcr->JobId, bstrftimes(tbuf, sizeof(tbuf), (utime_t)time(NULL)));
    pthread_cond_broadcast(&wait_device_release);
    dev->dunlock();
    if (dcr->keep_dcr) {