]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Implement console 'wait mount' command. Doesn't yet work.
authorKern Sibbald <kern@sibbald.com>
Thu, 24 Jul 2008 14:17:06 +0000 (14:17 +0000)
committerKern Sibbald <kern@sibbald.com>
Thu, 24 Jul 2008 14:17:06 +0000 (14:17 +0000)
kes  Implement timeout=nn on console 'wait mount timeout=nn' command.
kes  Break the do_swapping into do_unload, do_swapping, and
     do_load.  It is much more logical that way.
kes  Implement a set_dcr_from_vol subroutine in acquire.c for
     reading volumes. This allows the dcr to be refreshed after being
     zapped when the wrong volume is mounted.
     This should fix bug #1126 -- During multiple tape restore, bacula
     does not ask for physical tape change, but rereads same tape

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

bacula/src/dird/ua_cmds.c
bacula/src/stored/acquire.c
bacula/src/stored/dev.h
bacula/src/stored/mount.c
bacula/src/stored/read_record.c
bacula/src/version.h
bacula/technotes-2.5

index 84b2b90fbdaf7679bea914c3a3f59a317f4c37c5..208d9095e8424b0b16f045437f9daf70333aa289 100644 (file)
@@ -1566,6 +1566,8 @@ static int status_handler(void *ctx, int num_fields, char **row)
 int wait_cmd(UAContext *ua, const char *cmd)
 {
    JCR *jcr;
+   int i;
+   time_t stop_time = 0;
 
    /*
     * no args
@@ -1590,6 +1592,11 @@ int wait_cmd(UAContext *ua, const char *cmd)
       return 1;
    }
 
+   i = find_arg_with_value(ua, NT_("timeout")); 
+   if (i > 0 && ua->argv[i]) {
+      stop_time = time(NULL) + str_to_int64(ua->argv[i]);
+   }
+
    /* we have jobid, jobname or ujobid argument */
 
    uint32_t jobid = 0 ;
@@ -1627,6 +1634,27 @@ int wait_cmd(UAContext *ua, const char *cmd)
             free_jcr(jcr);
          }
          break;
+      /* Wait for a mount request */
+      } else if (strcasecmp(ua->argk[i], "mount") == 0) {
+         for (bool waiting=false; !waiting; ) {
+            foreach_jcr(jcr) {
+               if (jcr->JobId != 0 && 
+                   (jcr->JobStatus == JS_WaitMedia || jcr->JobStatus == JS_WaitMount)) {
+                  waiting = true;
+                  break;
+               }
+            }
+            endeach_jcr(jcr);
+            if (waiting) {
+               break;
+            }
+            if (stop_time && (time(NULL) >= stop_time)) {
+               ua->warning_msg(_("Wait on mount timed out\n"));
+               return 1;
+            }
+            bmicrosleep(1, 0);
+         }
+         return 1;
       }
    }
 
index 15ce6391762a84da069019f1350deba613418d9f..2aba36809223d54a9cf23ea2b29688d2f05d3eec 100644 (file)
@@ -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
@@ -174,20 +169,12 @@ bool acquire_device_for_read(DCR *dcr)
 
    dev->clear_unload();
 
-   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);
 
    tape_previously_mounted = dev->can_read() || dev->can_append() ||
@@ -217,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
@@ -239,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;
          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
@@ -253,13 +245,10 @@ bool acquire_device_for_read(DCR *dcr)
          }
          goto default_path;
       case VOL_NAME_ERROR:
+         Dmsg0(50, "Vol name error.\n");
          if (dev->is_volume_to_unload()) {
             goto default_path;
          }
-//       if (tape_initially_mounted) {
-            tape_initially_mounted = false;
-//          goto default_path;
-//       }
          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 */
@@ -270,6 +259,7 @@ bool acquire_device_for_read(DCR *dcr)
       default:
          Jmsg1(jcr, M_WARNING, 0, "%s", jcr->errmsg);
 default_path:
+         Dmsg0(50, "default path\n");
          tape_previously_mounted = true;
          
          /*
@@ -289,15 +279,6 @@ default_path:
                try_autochanger = false;
                continue;              /* try reading volume mounted */
             }
-            /* Try closing and re-opening */
-            dev->close();
-            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 */
@@ -305,7 +286,7 @@ 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;
@@ -693,3 +674,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; 
+}
index 8e015497b57c7d6f552784eebf27d1f7071d1435..399b453efb7f4fee3957a2c03b74efe20b847149 100644 (file)
@@ -552,6 +552,8 @@ public:
    int check_volume_label(bool &ask, bool &autochanger);
    void release_volume();
    void do_swapping(bool is_writing);
+   bool do_unload();
+   bool do_load(bool is_writing);
    bool is_tape_position_ok();
 };
 
index 8b8b27bded16206ad2b5440e58ca10e6de13be78..efb76029d654fc00e9150ee54c23ea5754589972 100644 (file)
@@ -113,7 +113,9 @@ mount_next_vol:
       ask = true;                     /* ask operator to mount tape */
       do_find = true;                 /* re-find a volume after unload */
    }
-   do_swapping(true /*writing*/);
+   do_unload();
+   do_swapping(true /*is_writing*/);
+   do_load(true /*is_writing*/);
 
    if (do_find && !find_a_volume()) {
       goto no_lock_bail_out;
@@ -500,12 +502,30 @@ bool DCR::is_suitable_volume_mounted()
    return dir_get_volume_info(this, GET_VOL_INFO_FOR_WRITE);
 }
 
-void DCR::do_swapping(bool is_writing)
+bool DCR::do_unload()
 {
    if (dev->must_unload()) {
       Dmsg1(100, "must_unload release %s\n", dev->print_name());
       release_volume();
    }
+   return false;
+}
+
+bool DCR::do_load(bool is_writing)
+{
+   if (dev->must_load()) {
+      Dmsg1(100, "Must load %s\n", dev->print_name());
+      if (autoload_device(this, is_writing, NULL) > 0) {
+         dev->clear_load();
+         return true;
+      }
+      return false;
+   }
+   return true;
+}
+
+void DCR::do_swapping(bool is_writing)
+{
    /*
     * See if we are asked to swap the Volume from another device
     *  if so, unload the other device here, and attach the
@@ -528,12 +548,6 @@ void DCR::do_swapping(bool is_writing)
       }
       dev->swap_dev = NULL;
    }
-   if (dev->must_load()) {
-      Dmsg1(100, "Must load %s\n", dev->print_name());
-      if (autoload_device(this, is_writing, NULL) > 0) {
-         dev->clear_load();
-      }
-   }
 }
 
 
index 1ca911aa8345d18ba6d94381ecf4ac7789608ca3..2072dbcefa755001b37ae14cc60818c7134347f9 100644 (file)
@@ -52,7 +52,7 @@ static bool try_repositioning(JCR *jcr, DEV_RECORD *rec, DCR *dcr);
 static char *rec_state_to_str(DEV_RECORD *rec);
 #endif
 
-static const int dbglvl = 200;
+static const int dbglvl = 500;
 
 bool read_records(DCR *dcr,
        bool record_cb(DCR *dcr, DEV_RECORD *rec),
index da8c98e24103c293336c304fbe16f685b933b89e..1c17e8af350ed33fe65af567d0d61b077f4d294d 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "2.5.2"
-#define BDATE   "22 July 2008"
-#define LSMDATE "22Jul08"
+#define BDATE   "24 July 2008"
+#define LSMDATE "24Jul08"
 
 #define PROG_COPYRIGHT "Copyright (C) %d-2008 Free Software Foundation Europe e.V.\n"
 #define BYEAR "2008"       /* year for copyright messages in progs */
index 4c3ac71b837f0f06b8ba3f2248932221bdd6cd63..556c585fa2a1a16adbb43dde791e84c47b578255 100644 (file)
@@ -32,6 +32,16 @@ separator in console (!$%&'()*+,-/:;<>?[]^`{|}~)
 
 
 General:
+24Jul08
+kes  Implement console 'wait mount' command. Doesn't yet work.
+kes  Implement timeout=nn on console 'wait mount timeout=nn' command.
+kes  Break the do_swapping into do_unload, do_swapping, and
+     do_load.  It is much more logical that way.
+kes  Implement a set_dcr_from_vol subroutine in acquire.c for
+     reading volumes. This allows the dcr to be refreshed after being
+     zapped when the wrong volume is mounted.
+     This should fix bug #1126 -- During multiple tape restore, bacula 
+     does not ask for physical tape change, but rereads same tape
 23Jul08
 kes  Apply patch submitted for bug #1107 with a small modification.
      This fixes a bug where bcopy copied too many records.