]> git.sur5r.net Git - bacula/bacula/commitdiff
- Create unload_autochanger() subroutine, and unload
authorKern Sibbald <kern@sibbald.com>
Wed, 17 Aug 2005 13:48:38 +0000 (13:48 +0000)
committerKern Sibbald <kern@sibbald.com>
Wed, 17 Aug 2005 13:48:38 +0000 (13:48 +0000)
  any drive that changes pool during reservation.
- Improve the logic of the reservation.
- Add more debug code for autochangers.
- Apply fix from Stephan Leemburg <sleemburg@jvc.nl> for
  improper scanning of schedule resource:
  Run = Level=Full Pool=Catalog daily at 1:20

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2321 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/kernstodo
bacula/kes-1.37
bacula/src/dird/run_conf.c
bacula/src/stored/acquire.c
bacula/src/stored/autochanger.c
bacula/src/stored/protos.h
bacula/src/stored/reserve.c

index b136ea1eceffe464c145210a0d667eea53133de9..0927e1e83ab3fb5238a1649ffeb7ca21a10cdd03 100644 (file)
@@ -18,6 +18,8 @@ Final items for 1.37 before release:
   chaos.
 - Look at fixing restore status stats in SD.
 - My database is growing
+- Call GetLastError() in the berrno constructor rather
+  than delaying until strerror.
 
 -  --without-openssl breaks at least on Solaris.
 9. Run the regression scripts on Solaris and FreeBSD
index 1eee8477fac65f089147357b5e7816ea70daea46..75f9aa96e640c0b5def4a11a917d7e017c15459b 100644 (file)
@@ -5,6 +5,10 @@ General:
 
 Changes to 1.37.36:
 17Aug05
+- Add more debug code for autochangers.
+- Apply fix from Stephan Leemburg <sleemburg@jvc.nl> for
+  improper scanning of schedule resource:
+  Run = Level=Full Pool=Catalog daily at 1:20
 - Apply patch from Chris Lee <labmonkey42@gmail.com> for 
   adding --enable-build-dird --enable-build-stored.
 - Tweak datadir definition in configure.in
index 2a06fc5afff931f782ef294aa0216957889432b8..6a9946feb8eb62740991b7035533b711654c7079 100644 (file)
@@ -297,12 +297,14 @@ void store_run(LEX *lc, RES_ITEM *item, int index, int pass)
       /* At this point, it is not a keyword. Check for old syle
        * Job Levels without keyword. This form is depreciated!!!
        */
-      for (j=0; joblevels[j].level_name; j++) {
-         if (strcasecmp(lc->str, joblevels[j].level_name) == 0) {
-            lrun.level = joblevels[j].level;
-            lrun.job_type = joblevels[j].job_type;
-            found = true;
-            break;
+      if (!found) {
+         for (j=0; joblevels[j].level_name; j++) {
+            if (strcasecmp(lc->str, joblevels[j].level_name) == 0) {
+               lrun.level = joblevels[j].level;
+               lrun.job_type = joblevels[j].job_type;
+               found = true;
+               break;
+            }
          }
       }
    } /* end for found */
index f0ceb6d6a5d8e5fcc6fc41ce65f36dd20b074d18..a581828fc866205bc44d2a56ae112499827293b4 100644 (file)
@@ -326,6 +326,7 @@ DCR *acquire_device_for_append(DCR *dcr)
     */
    if (dev->can_read()) {
       Jmsg1(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev->print_name());
+      Dmsg1(200, "Device %s is busy reading.\n", dev->print_name());
       goto get_out;
    }
 
@@ -356,6 +357,8 @@ DCR *acquire_device_for_append(DCR *dcr)
          if (dev->num_writers != 0 || dev->reserved_device) {
             Jmsg3(jcr, M_FATAL, 0, _("Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n"), 
                  dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
+            Dmsg3(200, "Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n",  
+                 dcr->VolumeName, dev->print_name(), dev->VolHdr.VolumeName);
             goto get_out;
          }
          /* Wrong tape mounted, release it, then fall through to get correct one */
@@ -395,6 +398,8 @@ DCR *acquire_device_for_append(DCR *dcr)
             /* Reduce "noise" -- don't print if job canceled */
             Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"),
                dev->print_name());
+            Dmsg1(200, "Could not ready device %s for append.\n", 
+               dev->print_name());
          }
          goto get_out;
       }
index 689965d4287b13972a5a2eb0852e7924e8f6733e..49505dd4f8d8f1bb0943373cb8bcf56d89c50249 100644 (file)
@@ -77,29 +77,8 @@ int autoload_device(DCR *dcr, int writing, BSOCK *dir)
 
       /* If tape we want is not loaded, load it. */
       if (loaded != slot) {
-         offline_or_rewind_dev(dev);
-         /* We are going to load a new tape, so close the device */
-         force_close_device(dev);
-         lock_changer(dcr);
-         if (loaded != 0 && loaded != -1) {        /* must unload drive */
-            Dmsg0(400, "Doing changer unload.\n");
-            Jmsg(jcr, M_INFO, 0,
-                 _("3303 Issuing autochanger \"unload slot %d, drive %d\" command.\n"),
-                 loaded, drive);
-            dcr->VolCatInfo.Slot = loaded;   /* slot to be unloaded */
-            changer = edit_device_codes(dcr, changer, 
-                        dcr->device->changer_command, "unload");
-            status = run_program(changer, timeout, NULL);
-            if (status != 0) {
-               berrno be;
-               be.set_errno(status);
-               Jmsg(jcr, M_FATAL, 0, _("3992 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"),
-                    slot, drive, be.strerror());
-               goto bail_out;
-            } else {
-               dev->Slot = 0;            /* nothing loaded now */
-            }
-            Dmsg1(400, "unload status=%d\n", status);
+         if (!unload_autochanger(dcr, loaded)) {
+            goto bail_out;
          }
          /*
           * Load the desired cassette
@@ -212,6 +191,56 @@ static void unlock_changer(DCR *dcr)
    }
 }
 
+/*
+ * Unload the volume, if any, in this drive
+ */
+bool unload_autochanger(DCR *dcr, int loaded)
+{
+   DEVICE *dev = dcr->dev;
+   JCR *jcr = dcr->jcr;
+   int slot;
+   uint32_t timeout = dcr->device->max_changer_wait;
+
+   if (!dev->is_autochanger() || !dcr->device->changer_name ||
+       !dcr->device->changer_command) {
+      return false;
+   }
+
+   offline_or_rewind_dev(dev);
+   /* We are going to load a new tape, so close the device */
+   force_close_device(dev);
+
+   if (loaded <= 0) {
+      loaded = get_autochanger_loaded_slot(dcr);
+   }
+   if (loaded > 0) {
+      POOLMEM *changer = get_pool_memory(PM_FNAME);
+      Jmsg(jcr, M_INFO, 0,
+           _("3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n"),
+           loaded, dev->drive_index);
+      slot = dcr->VolCatInfo.Slot;
+      dcr->VolCatInfo.Slot = loaded;
+      changer = edit_device_codes(dcr, changer, 
+                   dcr->device->changer_command, "unload");
+      lock_changer(dcr);
+      int stat = run_program(changer, timeout, NULL);
+      unlock_changer(dcr);
+      dcr->VolCatInfo.Slot = slot;
+      if (stat != 0) {
+         berrno be;
+         be.set_errno(stat);
+         Jmsg(jcr, M_INFO, 0, _("3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"),
+                 slot, dev->drive_index, be.strerror());
+         free_pool_memory(changer);
+         return false;
+      } else {
+         dev->Slot = 0;            /* nothing loaded */
+      }
+      free_pool_memory(changer);
+   }
+   return true;
+}
+
 
 /*
  * List the Volumes that are in the autoloader possibly
@@ -221,11 +250,9 @@ static void unlock_changer(DCR *dcr)
 bool autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd)  
 {
    DEVICE *dev = dcr->dev;
-   JCR *jcr = dcr->jcr;
    uint32_t timeout = dcr->device->max_changer_wait;
    POOLMEM *changer;
    BPIPE *bpipe;
-   int slot, loaded;
    int len = sizeof_pool_memory(dir->msg) - 1;
    bool ok = false;
    int stat;
@@ -240,35 +267,7 @@ bool autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd)
    changer = get_pool_memory(PM_FNAME);
    /* List command? */
    if (strcmp(cmd, "list") == 0) {
-      int drive = dev->device->drive_index;
-      /* Yes, to get a good listing, we unload any volumes */
-      offline_or_rewind_dev(dev);
-      /* We are going to load a new tape, so close the device */
-      force_close_device(dev);
-
-      /* First unload any tape */
-      loaded = get_autochanger_loaded_slot(dcr);
-      if (loaded > 0) {
-         bnet_fsend(dir,
-            _("3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n"),
-            loaded, drive);
-         slot = dcr->VolCatInfo.Slot;
-         dcr->VolCatInfo.Slot = loaded;
-         changer = edit_device_codes(dcr, changer, 
-                      dcr->device->changer_command, "unload");
-         lock_changer(dcr);
-         int stat = run_program(changer, timeout, NULL);
-         unlock_changer(dcr);
-         if (stat != 0) {
-            berrno be;
-            be.set_errno(stat);
-            Jmsg(jcr, M_INFO, 0, _("3995 Bad autochanger \"unload slot %d, drive %d\": ERR=%s.\n"),
-                    slot, drive, be.strerror());
-         } else {
-            dev->Slot = 0;            /* nothing loaded */
-         }
-         dcr->VolCatInfo.Slot = slot;
-      }
+      unload_autochanger(dcr, 0);
    }
 
    /* Now issue the command */
index a7f40440917db73506219013a2598dd8d6f8f1ea..85443ad3be8f20d9a22f45e7ddf9d33692b23ae0 100644 (file)
@@ -51,6 +51,7 @@ int     authenticate_filed(JCR *jcr);
 /* From autochanger.c */
 int      autoload_device(DCR *dcr, int writing, BSOCK *dir);
 bool     autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd);
+bool     unload_autochanger(DCR *dcr, int loaded);
 char    *edit_device_codes(DCR *dcr, char *omsg, const char *imsg, const char *cmd);
 int      get_autochanger_loaded_slot(DCR *dcr);
 
index 48f3d76b3d53a7a2166de93757c5a4f3e56df699..e72d9a29f3e3e3312002157d13f774989e307c09 100644 (file)
@@ -109,6 +109,8 @@ static int my_compare(void *item1, void *item2)
 VOLRES *new_volume(DCR *dcr, const char *VolumeName)
 {
    VOLRES *vol, *nvol;
+
+   Dmsg1(400, "new_volume %s\n", VolumeName);
    vol = (VOLRES *)malloc(sizeof(VOLRES));
    memset(vol, 0, sizeof(VOLRES));
    vol->vol_name = bstrdup(VolumeName);
@@ -158,6 +160,7 @@ bool free_volume(DEVICE *dev)
    if (dev->VolHdr.VolumeName[0] == 0) {
       return false;
    }
+   Dmsg1(400, "free_volume %s\n", dev->VolHdr.VolumeName);
    vol.vol_name = bstrdup(dev->VolHdr.VolumeName);
    P(vol_list_lock);
    fvol = (VOLRES *)vol_list->binary_search(&vol, my_compare);
@@ -353,7 +356,7 @@ static bool use_storage_cmd(JCR *jcr)
          Jmsg(jcr, M_INFO, 0, "%s", error);
       }
 #endif
-      Dmsg1(100, ">dird: %s\n", dir->msg);
+      Dmsg1(100, ">dird: %s", dir->msg);
    } else {
       unbash_spaces(dir->msg);
       pm_strcpy(jcr->errmsg, dir->msg);
@@ -361,7 +364,7 @@ static bool use_storage_cmd(JCR *jcr)
          Jmsg(jcr, M_INFO, 0, _("Failed command: %s\n"), jcr->errmsg);
       }
       bnet_fsend(dir, BAD_use, jcr->errmsg);
-      Dmsg1(100, ">dird: %s\n", dir->msg);
+      Dmsg1(100, ">dird: %s", dir->msg);
    }
 
 done:
@@ -462,7 +465,7 @@ static int search_res_for_device(RCTX &rctx)
          Dmsg1(220, "Got: %s", dir->msg);
          bash_spaces(rctx.device_name);
          ok = bnet_fsend(dir, OK_device, rctx.device_name);
-         Dmsg1(100, ">dird: %s\n", dir->msg);
+         Dmsg1(100, ">dird dev: %s", dir->msg);
          return ok ? 1 : -1;
       }
    }
@@ -485,7 +488,7 @@ static int search_res_for_device(RCTX &rctx)
             pm_strcpy(dev_name, rctx.device->hdr.name);
             bash_spaces(dev_name);
             ok = bnet_fsend(dir, OK_device, dev_name.c_str());  /* Return real device name */
-            Dmsg1(100, ">dird: %s\n", dir->msg);
+            Dmsg1(100, ">dird changer: %s", dir->msg);
             return ok ? 1 : -1;
          }
       }
@@ -531,7 +534,7 @@ static int reserve_device(RCTX &rctx)
    if (!dcr) {
       BSOCK *dir = rctx.jcr->dir_bsock;
       bnet_fsend(dir, _("3926 Could not get dcr for device: %s\n"), rctx.device_name);
-      Dmsg1(100, ">dird: %s\n", dir->msg);
+      Dmsg1(100, ">dird: %s", dir->msg);
       return -1;
    }
    rctx.jcr->dcr = dcr;
@@ -663,9 +666,9 @@ static int can_reserve_drive(DCR *dcr, bool PreferMountedVols)
    }
 
    /*
-    * Handle the case that the drive is not yet in append mode
+    * Handle the case that there are no writers
     */
-   if (!dev->can_append() && dev->num_writers == 0) {
+   if (dev->num_writers == 0) {
       /* Now check if there are any reservations on the drive */
       if (dev->reserved_device) {           
          /* Yes, now check if we want the same Pool and pool type */
@@ -676,23 +679,22 @@ static int can_reserve_drive(DCR *dcr, bool PreferMountedVols)
             /* Drive not suitable for us */
             return 0;                 /* wait */
          }
-      } else {
-         /* Device is available but not yet reserved, reserve it for us */
-         bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
-         bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
+      } else if (dev->can_append()) {
+         /* Device in append mode, check if changing pool */
+         if (strcmp(dev->pool_name, dcr->pool_name) == 0 &&
+             strcmp(dev->pool_type, dcr->pool_type) == 0) {
+            /* OK, compatible device */
+         } else {
+            /* Changing pool, unload old tape if any in drive */
+            unload_autochanger(dcr, 0);
+         }
       }
-      return 1;                       /* reserve drive */
-   }
-
-   /*
-    * Check if device in append mode with no writers (i.e. available)
-    */
-   if (dev->can_append() && dev->num_writers == 0) {
       /* Device is available but not yet reserved, reserve it for us */
       bstrncpy(dev->pool_name, dcr->pool_name, sizeof(dev->pool_name));
       bstrncpy(dev->pool_type, dcr->pool_type, sizeof(dev->pool_type));
-      return 1;
+      return 1;                       /* reserve drive */
    }
+
    /*
     * Check if the device is in append mode with writers (i.e.
     *  available if pool is the same).