]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/stored/acquire.c
Apply Joao's patch to SQLite tables to make chars work.
[bacula/bacula] / bacula / src / stored / acquire.c
index 37ff22cbee26f1d0a3c6a0acd405ade6b9d7083e..f4203cd3956f9f6ca5dd2ff5296d176f76bbb14d 100644 (file)
@@ -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,6 +38,7 @@
 
 /* Forward referenced functions */
 static void attach_dcr_to_dev(DCR *dcr);
+static void set_dcr_from_vol(DCR *dcr, VOL_LIST *vol);
 
 
 /*********************************************************************
@@ -88,15 +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; 
+   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
@@ -116,10 +111,10 @@ bool acquire_device_for_read(DCR *dcr)
       DIRSTORE *store;
       int stat;
 
-      Jmsg3(jcr, M_INFO, 0, _("Changing device. Want Media Type=\"%s\" have=\"%s\"\n"
+      Jmsg3(jcr, M_INFO, 0, _("Changing read device. Want Media Type=\"%s\" have=\"%s\"\n"
                               "  device=%s\n"), 
             dcr->media_type, dev->device->media_type, dev->print_name());
-      Dmsg3(50, "Changing device. Want Media Type=\"%s\" have=\"%s\"\n"
+      Dmsg3(50, "Changing read device. Want Media Type=\"%s\" have=\"%s\"\n"
                               "  device=%s\n", 
             dcr->media_type, dev->device->media_type, dev->print_name());
 
@@ -152,9 +147,9 @@ bool acquire_device_for_read(DCR *dcr)
          dev = dcr->dev;                     /* get new device pointer */
          dev->dblock(BST_DOING_ACQUIRE); 
          dcr->VolumeName[0] = 0;
-         Jmsg(jcr, M_INFO, 0, _("Media Type change.  New device %s chosen.\n"),
+         Jmsg(jcr, M_INFO, 0, _("Media Type change.  New read device %s chosen.\n"),
             dev->print_name());
-         Dmsg1(50, "Media Type change.  New device %s chosen.\n", dev->print_name());
+         Dmsg1(50, "Media Type change.  New read 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));
@@ -172,20 +167,14 @@ 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;
-   }
+   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);
 
    tape_previously_mounted = dev->can_read() || dev->can_append() ||
@@ -194,8 +183,10 @@ 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 */
@@ -213,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
@@ -235,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
@@ -249,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;
          
          /*
@@ -286,16 +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;
-            }
-            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 */
@@ -303,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());
@@ -331,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;
@@ -368,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.
@@ -442,11 +430,15 @@ bool release_device(DCR *dcr)
    dcr->clear_reserved();
 
    if (dev->can_read()) {
+      VOLUME_CAT_INFO *vol = &dev->VolCatInfo;
       dev->clear_read();              /* clear read bit */
-      Dmsg0(100, "dir_update_vol_info. Release0\n");
-      dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
-      volume_unused(dcr);
-
+      Dmsg2(150, "dir_update_vol_info. label=%d Vol=%s\n",
+         dev->is_labeled(), vol->VolCatName);
+      if (dev->is_labeled() && vol->VolCatName[0] != 0) {
+         dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
+         remove_read_volume(jcr, dcr->VolumeName);
+         volume_unused(dcr);
+      }
    } else if (dev->num_writers > 0) {
       /* 
        * Note if WEOT is set, we are at the end of the tape
@@ -642,7 +634,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);
@@ -686,3 +678,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; 
+}