Kern's ToDo List
-                     24 July 2005
+                     04 August 2005
 
 Major development:      
 Project                     Developer
 Final items for 1.37 before release:
 1. Fix bugs
 - Tape xxx in drive 0, requested in drive 1
-- Multi-drive changer seems to only use drive 0
-  Multiple drives don't seem to be opened.
-- Why isn't the DEVICE structure defined when doing
-  a reservation?
 - The mount command does not work with drives other than 0.
+- Look at fixing restore status stats in SD.
 
 -  --without-openssl breaks at least on Solaris.
 9. Run the regression scripts on Solaris and FreeBSD
 -  Arno had to do -- to get update slots=x to work
    UPDATE Media SET InChanger=0,Slot=0 WHERE InChanger>0 AND Slot>0; (MySQL)
 
-
 Document:
 - Document cleaning up the spool files:
   db, pid, state, bsr, mail, conmsg, spool
 - Add better documentation on how restores can be done
 8. Take one more try at making DVD writing work (no go)
 7. Write a bacula-web document
+- Why isn't the DEVICE structure defined when doing
+  a reservation?
+- Multi-drive changer seems to only use drive 0
+  Multiple drives don't seem to be opened.
+
 
 General:
 
 Changes to 1.37.34:
+04Aug03
+- Make reservation system single threaded during the
+  search to avoid two threads competing for the same
+  resource.
+- Correct a return code in find_suitable_device_for_job()
+  Possibly cause of "busy writing to another volume".
 03Aug03
 - Modify open() for tape so nonblocking really works.  
 - Use fcntl() to reset blocking status rather than close()
 
             free_unused_volume(dcr);
          }
          if (dev->num_writers != 0 || dev->reserved_device) {
-            Jmsg(jcr, M_FATAL, 0, _("Wanted Volume \"%s\", but device %s is busy writing on \"%s\" .\n"), 
+            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);
             goto get_out;
          }
 
 
 static dlist *vol_list = NULL;
 static pthread_mutex_t vol_list_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t search_lock = PTHREAD_MUTEX_INITIALIZER;
 
 /* Forward referenced functions */
 static int can_reserve_drive(DCR *dcr, bool PerferMountedVols);
 bool find_suitable_device_for_job(JCR *jcr, RCTX &rctx)
 {
    bool first = true;
-   bool ok = false;
+   bool ok;
    DCR *dcr = NULL;
    DIRSTORE *store;
    char *device_name;
    init_jcr_device_wait_timers(jcr);
    for ( ;; ) {
       int need_wait = false;
+      ok = false;
+      P(search_lock);
       foreach_alist(store, jcr->dirstore) {
          rctx.store = store;
          foreach_alist(device_name, store->device) {
             /* otherwise error */
 //             rctx->errors.push(bstrdup(jcr->errmsg));
          }
+         if (ok) {
+            break;
+         }
       }
+      V(search_lock);
       /*
        * If there is some device for which we can wait, then
        *  wait and try again until the wait time expires
 
       now = time(NULL);
       jcr->rem_wait_sec -= (now - start);
 
+/* Not turned on yet */
 #ifdef needed
       /* Note, this always triggers the first time. We want that. */
       if (me->heartbeat_interval) {
 
 /* */
 #undef  VERSION
 #define VERSION "1.37.34"
-#define BDATE   "03 August 2005"
-#define LSMDATE "03Aug05"
+#define BDATE   "04 August 2005"
+#define LSMDATE "04Aug05"
 
 /* Debug flags */
 #undef  DEBUG