]> git.sur5r.net Git - bacula/bacula/commitdiff
- Comment out Multiple Connections in the document.
authorKern Sibbald <kern@sibbald.com>
Sat, 26 Mar 2005 07:58:50 +0000 (07:58 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 26 Mar 2005 07:58:50 +0000 (07:58 +0000)
- Move the P() and V() to subroutines so that they can be accessed
  from class methods. The reference to strerror() caused problems.
- Implement new DEVICE class methods block() and unblock() that
  do what was previously done in 3 lines of code.
- Implement wait_for_device(), which will wait for any device
  to be released then return. This requires a new global mutex
  and condition variable, and is implemented in src/stored/wait.c
- Change the code in reserve_device_for_read(), which previously
  failed the job to use the new device wait code.

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

18 files changed:
bacula/src/baconfig.h
bacula/src/lib/bsys.c
bacula/src/stored/Makefile.in
bacula/src/stored/acquire.c
bacula/src/stored/askdir.c
bacula/src/stored/bcopy.c
bacula/src/stored/bextract.c
bacula/src/stored/bls.c
bacula/src/stored/bscan.c
bacula/src/stored/btape.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/dircmd.c
bacula/src/stored/mount.c
bacula/src/stored/protos.h
bacula/src/stored/stored.c
bacula/src/stored/stored.h
bacula/src/version.h

index 2cf04806353de3d8481a92df6886e959d0dbf3da..d6e675bc90baa14b774b031254aa6b3e7d20ec97 100644 (file)
@@ -267,19 +267,11 @@ extern void _v(char *file, int line, pthread_mutex_t *m);
 #define V(x) _v(__FILE__, __LINE__, &(x))
 
 #else
+extern void _p(pthread_mutex_t *m);
+extern void _v(pthread_mutex_t *m);
 
-/* These probably should be subroutines */
-#define P(x) \
-   do { int errstat; if ((errstat=pthread_mutex_lock(&(x)))) \
-      e_msg(__FILE__, __LINE__, M_ABORT, 0, "Mutex lock failure. ERR=%s\n",\
-           strerror(errstat)); \
-   } while(0)
-
-#define V(x) \
-   do { int errstat; if ((errstat=pthread_mutex_unlock(&(x)))) \
-         e_msg(__FILE__, __LINE__, M_ABORT, 0, "Mutex unlock failure. ERR=%s\n",\
-           strerror(errstat)); \
-   } while(0)
+#define P(x) _p(&(x))
+#define V(x) _v(&(x))
 
 #endif /* DEBUG_MUTEX */
 
index a66914b08511dd247708c73e8eff8d4deec95722..f8e8435111e76b1f045fb1e83584a56a0d5b26c2 100644 (file)
@@ -307,8 +307,9 @@ void _p(char *file, int line, pthread_mutex_t *m)
       e_msg(file, line, M_ERROR, 0, _("Possible mutex deadlock.\n"));
       /* We didn't get the lock, so do it definitely now */
       if ((errstat=pthread_mutex_lock(m))) {
+        berrno be;
          e_msg(file, line, M_ABORT, 0, _("Mutex lock failure. ERR=%s\n"),
-              strerror(errstat));
+              be.strerror(errstat));
       } else {
          e_msg(file, line, M_ERROR, 0, _("Possible mutex deadlock resolved.\n"));
       }
@@ -321,14 +322,39 @@ void _v(char *file, int line, pthread_mutex_t *m)
    int errstat;
 
    if ((errstat=pthread_mutex_trylock(m)) == 0) {
+      berrno be;
       e_msg(file, line, M_ERROR, 0, _("Mutex unlock not locked. ERR=%s\n"),
-          strerror(errstat));
+          be.strerror(errstat));
     }
     if ((errstat=pthread_mutex_unlock(m))) {
+       berrno be;
        e_msg(file, line, M_ABORT, 0, _("Mutex unlock failure. ERR=%s\n"),
-             strerror(errstat));
+             be.strerror(errstat));
     }
 }
+
+#else
+
+void _p(pthread_mutex_t *m)
+{
+   int errstat;
+   if ((errstat=pthread_mutex_lock(m))) {
+      berrno be;
+      e_msg(__FILE__, __LINE__, M_ABORT, 0, _("Mutex lock failure. ERR=%s\n"),
+           be.strerror(errstat));
+   }
+}
+
+void _v(pthread_mutex_t *m)
+{
+   int errstat;
+   if ((errstat=pthread_mutex_unlock(m))) {
+      berrno be;
+      e_msg(__FILE__, __LINE__, M_ABORT, 0, _("Mutex unlock failure. ERR=%s\n"),
+           be.strerror(errstat));
+   }
+}
+
 #endif /* DEBUG_MUTEX */
 
 #ifdef DEBUG_MEMSET
index a5b0774dd8e09d05bd04217147ddf1c8b485a787..2862e8a4e1d7eb7c9af09bc80430295362733341 100644 (file)
@@ -45,31 +45,31 @@ TAPESRCS = btape.c block.c butil.c dev.c device.c label.c \
 TAPEOBJS = btape.o block.o butil.o dev.o device.o label.o \
           ansi_label.o dvd.o ebcdic.o \
           autochanger.o acquire.o mount.o record.o read_record.o \
-          stored_conf.o match_bsr.o parse_bsr.o spool.o
+          stored_conf.o match_bsr.o parse_bsr.o spool.o wait.o
 
 # bls
 BLSOBJS = bls.o block.o butil.o device.o dev.o label.o match_bsr.o \
          ansi_label.o dvd.o ebcdic.o \
          autochanger.o acquire.o mount.o parse_bsr.o record.o  \
-         read_record.o stored_conf.o spool.o
+         read_record.o stored_conf.o spool.o wait.o
 
 # bextract
 BEXTOBJS = bextract.o block.o device.o dev.o label.o record.o \
           ansi_label.o dvd.o ebcdic.o \
           autochanger.o acquire.o mount.o match_bsr.o parse_bsr.o butil.o \
-          read_record.o stored_conf.o spool.o
+          read_record.o stored_conf.o spool.o wait.o
 
 # bscan
 SCNOBJS = bscan.o block.o device.o dev.o label.o \
          ansi_label.o dvd.o ebcdic.o \
          autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \
-         butil.o read_record.o stored_conf.o spool.o
+         butil.o read_record.o stored_conf.o spool.o wait.o
 
 # bcopy
 COPYOBJS = bcopy.o block.o device.o dev.o label.o \
           ansi_label.o dvd.o ebcdic.o \
           autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \
-          butil.o read_record.o stored_conf.o spool.o
+          butil.o read_record.o stored_conf.o spool.o wait.o
 
 
 
index 8595dd5d4261aacba5dc9ca7c77e78bfb9db6d70..83ce8d80a677ec43cd63994d445a9866037aece0 100644 (file)
@@ -137,35 +137,36 @@ void free_dcr(DCR *dcr)
 bool reserve_device_for_read(JCR *jcr, DEVICE *dev)
 {
    DCR *dcr = jcr->dcr;
-   bool ok = false;
+   bool first;
 
    ASSERT(dcr);
-   if (device_is_unmounted(dev)) {
-      Jmsg(jcr, M_WARNING, 0, _("device %s is BLOCKED due to user unmount.\n"),
-        dev->print_name());
-      return false;
-   }
-   lock_device(dev);
-   block_device(dev, BST_DOING_ACQUIRE);
-   unlock_device(dev);
 
-   if (dev->is_busy()) {
-      Jmsg2(jcr, M_FATAL, 0, _("Device %s is busy. Job %d canceled.\n"),
-           dev->print_name(), jcr->JobId);
-      goto get_out;
+   dev->block(BST_DOING_ACQUIRE);
+
+   Mmsg(jcr->errmsg, _("Device %s is BLOCKED due to user unmount.\n"),
+       dev->print_name());
+   for (first=true; device_is_unmounted(dev); first=false) {
+      dev->unblock();
+      if (!wait_for_device(dcr, jcr->errmsg, first))  {
+        return false;
+      }
+     dev->block(BST_DOING_ACQUIRE);
    }
-   if (!dcr) {
-      dcr = new_dcr(jcr, dev);
+
+   Mmsg2(jcr->errmsg, _("Device %s is busy. Job %d canceled.\n"),
+        dev->print_name(), jcr->JobId);
+   for (first=true; dev->is_busy(); first=false) {
+      dev->unblock();
+      if (!wait_for_device(dcr, jcr->errmsg, first)) {
+        return false;
+      }
+      dev->block(BST_DOING_ACQUIRE);
    }
+
    dev->clear_append();
    dev->set_read();
-   ok = true;
-
-get_out:
-   P(dev->mutex);
-   unblock_device(dev);
-   V(dev->mutex);
-   return ok;
+   dev->unblock();
+   return true;
 }
 
 
@@ -189,11 +190,9 @@ DCR *acquire_device_for_read(JCR *jcr, DEVICE *dev)
    DCR *dcr = jcr->dcr;
    int vol_label_status;
    
-   lock_device(dev);
-   block_device(dev, BST_DOING_ACQUIRE);
-   unlock_device(dev);
+   dev->block(BST_DOING_ACQUIRE);
 
-   init_dev_wait_timers(dev);
+   init_device_wait_timers(dcr);
 
    tape_previously_mounted = dev->can_read() ||
                             dev->can_append() ||
@@ -333,9 +332,7 @@ default_path:
       dcr->VolumeName, dev->print_name());
 
 get_out:
-   P(dev->mutex);
-   unblock_device(dev);
-   V(dev->mutex);
+   dev->unblock();
    if (!vol_ok) {
       free_dcr(dcr);
       dcr = NULL;
@@ -365,9 +362,7 @@ bool reserve_device_for_append(JCR *jcr, DEVICE *dev)
 
    ASSERT(dcr);
 
-   lock_device(dev);
-   block_device(dev, BST_DOING_ACQUIRE);
-   unlock_device(dev);
+   dev->block(BST_DOING_ACQUIRE);
    if (dev->can_read()) {
       Jmsg(jcr, M_WARNING, 0, _("Device %s is busy reading.\n"), dev->print_name());
       goto bail_out;
@@ -427,9 +422,7 @@ do_reserve:
    ok = true;
 
 bail_out:
-   P(dev->mutex);
-   unblock_device(dev);
-   V(dev->mutex);
+   dev->unblock();
    return ok;
 }
 
@@ -452,9 +445,7 @@ DCR *acquire_device_for_append(JCR *jcr, DEVICE *dev)
    if (!dcr) {
       dcr = new_dcr(jcr, dev);
    }
-   lock_device(dev);
-   block_device(dev, BST_DOING_ACQUIRE);
-   unlock_device(dev);
+   dev->block(BST_DOING_ACQUIRE);
    Dmsg1(190, "acquire_append device is %s\n", dev_is_tape(dev)?"tape":"disk");
 
    if (dcr->reserved_device) {
@@ -545,9 +536,7 @@ get_out:
    free_dcr(dcr);
    dcr = NULL;
 ok_out:
-   P(dev->mutex);
-   unblock_device(dev);
-   V(dev->mutex);
+   dev->unblock();
    return dcr;
 }
 
@@ -644,5 +633,6 @@ bool release_device(DCR *dcr)
    unlock_device(dev);
    free_dcr(dcr);
    jcr->dcr = NULL;
+   pthread_cond_broadcast(&wait_device_release);
    return ok;
 }
index 3a2b41128f3ecfdc28ee4994ac7eb5d1b2e803fa..27e6a9fc3cac77dacd06043d5e009696cd9d2668 100644 (file)
@@ -524,7 +524,7 @@ bool dir_ask_sysop_to_create_appendable_volume(DCR *dcr)
 "Someone woke me up, but I cannot find any appendable\n"
 "volumes for Job=%s.\n"), jcr->Job);
         /* Restart wait counters after user interaction */
-        init_dev_wait_timers(dev);
+        init_device_wait_timers(dcr);
         continue;
       }
       unmounted = (dev->dev_blocked == BST_UNMOUNTED) ||
index 47cf76219df96e7c9c600eece7bf2e485bf280e1..8a6b7bd35c6a33b444675bcd9d09f51db87f905a 100644 (file)
@@ -48,7 +48,10 @@ static DEV_BLOCK *out_block;
 
 #define CONFIG_FILE "bacula-sd.conf"
 char *configfile;
-bool forge_on = true;
+STORES *me = NULL;                   /* our Global resource */
+bool forge_on = false;               /* proceed inspite of I/O errors */
+pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
 
 
 static void usage()
index 2577094a7b6d02e4c2eb021b308d06f331d2d4a4..34e446022c9402a871ccc38e44b55feb66570804 100644 (file)
@@ -64,7 +64,10 @@ static uint64_t fileAddr = 0;              /* file write address */
 
 #define CONFIG_FILE "bacula-sd.conf"
 char *configfile;
+STORES *me = NULL;                   /* our Global resource */
 bool forge_on = false;
+pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
 
 static void usage()
 {
index 4bc1931b5859670483fd9367513db43614ea215a..4bf26f8ccffdb291d8442b1a0c91f2f0acc1e743 100644 (file)
@@ -55,7 +55,10 @@ static ATTR *attr;
 
 #define CONFIG_FILE "bacula-sd.conf"
 char *configfile;
+STORES *me = NULL;                   /* our Global resource */
 bool forge_on = false;
+pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
 
 
 static FF_PKT *ff;
index 3507ab4a177c9e7619035965c48072ba278cb131..cc40e5d23a804d029d2ea2949a45518804f9b488 100644 (file)
@@ -54,7 +54,6 @@ static int update_SIG_record(B_DB *db, char *SIGbuf, DEV_RECORD *rec, int type);
 
 
 /* Global variables */
-STORES *me;
 #if defined(HAVE_CYGWIN) || defined(HAVE_WIN32)
 int win32_client = 1;
 #else
@@ -100,7 +99,10 @@ static int num_files = 0;
 
 #define CONFIG_FILE "bacula-sd.conf"
 char *configfile;
-bool forge_on = false;
+STORES *me = NULL;                   /* our Global resource */
+bool forge_on = false;               /* proceed inspite of I/O errors */
+pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
 
 
 static void usage()
index 921fd55ac8824d019aa7cb45877e3162bb79847c..72baeb5ec58c6437237f894671692e0d86b31059 100644 (file)
@@ -45,7 +45,10 @@ int quit = 0;
 char buf[100000];
 int bsize = TAPE_BSIZE;
 char VolName[MAX_NAME_LENGTH];
-bool forge_on = false;
+STORES *me = NULL;                   /* our Global resource */
+bool forge_on = false;               /* proceed inspite of I/O errors */
+pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
 
 /*
  * If you change the format of the state file,
index 2d0362d180d01e18703137ff49b04b908da7c170..e7d2e1655dbebb2297234e576089c0e64ecb7f57 100644 (file)
@@ -508,6 +508,20 @@ bool rewind_dev(DEVICE *dev)
    return true;
 }
 
+void DEVICE::block(int why)
+{
+   lock_device(this);
+   block_device(this, why);
+   V(mutex);
+}
+
+void DEVICE::unblock()
+{  
+   P(mutex);
+   unblock_device(this);
+   V(mutex);
+}
+
 /*
  * Called to indicate that we have just read an
  *  EOF from the device.
@@ -1664,8 +1678,11 @@ term_dev(DEVICE *dev)
 /*
  * This routine initializes the device wait timers
  */
-void init_dev_wait_timers(DEVICE *dev)
+void init_device_wait_timers(DCR *dcr)
 {
+   DEVICE *dev = dcr->dev;
+   JCR *jcr = dcr->jcr;
+
    /* ******FIXME******* put these on config variables */
    dev->min_wait = 60 * 60;
    dev->max_wait = 24 * 60 * 60;
@@ -1675,9 +1692,19 @@ void init_dev_wait_timers(DEVICE *dev)
    dev->num_wait = 0;
    dev->poll = false;
    dev->BadVolName[0] = 0;
+
+   jcr->min_wait = 60 * 60;
+   jcr->max_wait = 24 * 60 * 60;
+   jcr->max_num_wait = 9;             /* 5 waits =~ 1 day, then 1 day at a time */
+   jcr->wait_sec = jcr->min_wait;
+   jcr->rem_wait_sec = jcr->wait_sec;
+   jcr->num_wait = 0;
+
 }
 
 /*
+ * The dev timers are used for waiting on a particular device 
+ *
  * Returns: true if time doubled
  *         false if max time expired
  */
@@ -1695,6 +1722,7 @@ bool double_dev_wait_time(DEVICE *dev)
    return true;
 }
 
+
 void set_os_device_parameters(DEVICE *dev)
 {
 #ifdef HAVE_LINUX_OS
index eef16d4d149d7a920315d46ed095fbe0e98b599d..eb7b38ea1ab3f4b2ee8d61c0dddafebc421b2c2f 100644 (file)
@@ -289,6 +289,8 @@ public:
    void clear_labeled() { state &= ~ST_LABEL; };
    void clear_offline() { state &= ~ST_OFFLINE; };
    void clear_eot() { state &= ~ST_EOT; };
+   void block(int why); /* in dev.c */
+   void unblock();      /* in dev.c */
 };
 
 /* Note, these return int not bool! */
index 6cb10436d25b6d129bf1a0159c32a0e0328c50bf..356f12d8836c808fa2b7cf5de9570a594b5d91e7 100644 (file)
@@ -272,6 +272,7 @@ static bool cancel_cmd(JCR *cjcr)
         /* If thread waiting on mount, wake him */
         if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->waiting_for_mount()) {
             pthread_cond_signal(&jcr->dcr->dev->wait_next_vol);
+            pthread_cond_broadcast(&wait_device_release);
         }
          bnet_fsend(dir, _("3000 Job %s marked to be canceled.\n"), jcr->Job);
         free_jcr(jcr);
@@ -553,6 +554,7 @@ static bool mount_cmd(JCR *jcr)
             bnet_fsend(dir, "3001 OK mount. Device=%s\n", 
               dev->print_name());
            pthread_cond_signal(&dev->wait_next_vol);
+           pthread_cond_broadcast(&wait_device_release);
            break;
 
         /* In both of these two cases, we (the user) unmounted the Volume */
@@ -583,6 +585,7 @@ static bool mount_cmd(JCR *jcr)
                          dev->print_name());
            }
            pthread_cond_signal(&dev->wait_next_vol);
+           pthread_cond_broadcast(&wait_device_release);
            break;
 
         case BST_DOING_ACQUIRE:
index f9390296dc05e495a46fd0371313a35e25dc0d6a..7b0c0e672d2bb369c64a1644b6a76a9a7a808d86 100644 (file)
@@ -54,7 +54,7 @@ bool mount_next_write_volume(DCR *dcr, bool release)
 
    Dmsg0(100, "Enter mount_next_volume()\n");
 
-   init_dev_wait_timers(dev);
+   init_device_wait_timers(dcr);
 
    /*
     * Attempt to mount the next volume. If something non-fatal goes
index 93b4ce1830b9919c460570d9d20c32b1ab2a40b5..fc3b9999e4a0e5a64afcb80a8f84cb6a68d9b982 100644 (file)
 uint32_t new_VolSessionId();
 
 /* From acquire.c */
-bool    reserve_device_for_append(JCR *jcr, DEVICE *dev);
-DCR    *acquire_device_for_append(JCR *jcr, DEVICE *dev);
-bool    reserve_device_for_read(JCR *jcr, DEVICE *dev);
-DCR    *acquire_device_for_read(JCR *jcr, DEVICE *dev);
-bool    release_device(DCR *dcr);
-DCR    *new_dcr(JCR *jcr, DEVICE *dev);
-void    free_dcr(DCR *dcr);
+bool     reserve_device_for_append(JCR *jcr, DEVICE *dev);
+DCR     *acquire_device_for_append(JCR *jcr, DEVICE *dev);
+bool     reserve_device_for_read(JCR *jcr, DEVICE *dev);
+DCR     *acquire_device_for_read(JCR *jcr, DEVICE *dev);
+bool     release_device(DCR *dcr);
+DCR     *new_dcr(JCR *jcr, DEVICE *dev);
+void     free_dcr(DCR *dcr);
 
 /* From askdir.c */
 enum get_vol_info_rw {
    GET_VOL_INFO_FOR_WRITE,
    GET_VOL_INFO_FOR_READ
 };
-bool   dir_get_volume_info(DCR *dcr, enum get_vol_info_rw);
-bool   dir_find_next_appendable_volume(DCR *dcr);
-bool   dir_update_volume_info(DCR *dcr, bool label);
-bool   dir_ask_sysop_to_create_appendable_volume(DCR *dcr);
-bool   dir_ask_sysop_to_mount_volume(DCR *dcr);
-bool   dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec);
-bool   dir_send_job_status(JCR *jcr);
-bool   dir_create_jobmedia_record(DCR *dcr);
-bool   dir_update_device(JCR *jcr, DEVICE *dev);
-bool   dir_update_changer(JCR *jcr, AUTOCHANGER *changer);
+bool    dir_get_volume_info(DCR *dcr, enum get_vol_info_rw);
+bool    dir_find_next_appendable_volume(DCR *dcr);
+bool    dir_update_volume_info(DCR *dcr, bool label);
+bool    dir_ask_sysop_to_create_appendable_volume(DCR *dcr);
+bool    dir_ask_sysop_to_mount_volume(DCR *dcr);
+bool    dir_update_file_attributes(DCR *dcr, DEV_RECORD *rec);
+bool    dir_send_job_status(JCR *jcr);
+bool    dir_create_jobmedia_record(DCR *dcr);
+bool    dir_update_device(JCR *jcr, DEVICE *dev);
+bool    dir_update_changer(JCR *jcr, AUTOCHANGER *changer);
 
 /* authenticate.c */
-int    authenticate_director(JCR *jcr);
-int    authenticate_filed(JCR *jcr);
+int     authenticate_director(JCR *jcr);
+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);
-void    mark_volume_not_inchanger(DCR *dcr);
-char   *edit_device_codes(DCR *dcr, char *omsg, const char *cmd);
+int      autoload_device(DCR *dcr, int writing, BSOCK *dir);
+bool     autochanger_cmd(DCR *dcr, BSOCK *dir, const char *cmd);
+void     mark_volume_not_inchanger(DCR *dcr);
+char    *edit_device_codes(DCR *dcr, char *omsg, const char *cmd);
 
 /* From block.c */
-void   dump_block(DEV_BLOCK *b, const char *msg);
+void    dump_block(DEV_BLOCK *b, const char *msg);
 DEV_BLOCK *new_block(DEVICE *dev);
 DEV_BLOCK *dup_block(DEV_BLOCK *eblock);
-void   init_block_write(DEV_BLOCK *block);
-void   empty_block(DEV_BLOCK *block);
-void   free_block(DEV_BLOCK *block);
-bool   write_block_to_device(DCR *dcr);
-bool   write_block_to_dev(DCR *dcr);
-void   print_block_read_errors(JCR *jcr, DEV_BLOCK *block);
-void   ser_block_header(DEV_BLOCK *block);
+void    init_block_write(DEV_BLOCK *block);
+void    empty_block(DEV_BLOCK *block);
+void    free_block(DEV_BLOCK *block);
+bool    write_block_to_device(DCR *dcr);
+bool    write_block_to_dev(DCR *dcr);
+void    print_block_read_errors(JCR *jcr, DEV_BLOCK *block);
+void    ser_block_header(DEV_BLOCK *block);
 
 #define CHECK_BLOCK_NUMBERS    true
 #define NO_BLOCK_NUMBER_CHECK  false
-bool   read_block_from_device(DCR *dcr, bool check_block_numbers);
-bool   read_block_from_dev(DCR *dcr, bool check_block_numbers);
+bool    read_block_from_device(DCR *dcr, bool check_block_numbers);
+bool    read_block_from_dev(DCR *dcr, bool check_block_numbers);
 
 /* From butil.c -- utilities for SD tool programs */
-void   print_ls_output(const char *fname, const char *link, int type, struct stat *statp);
+void    print_ls_output(const char *fname, const char *link, int type, struct stat *statp);
 JCR    *setup_jcr(const char *name, char *dev_name, BSR *bsr,
-                 const char *VolumeName, int mode);
-void   display_tape_error_status(JCR *jcr, DEVICE *dev);
+                  const char *VolumeName, int mode);
+void    display_tape_error_status(JCR *jcr, DEVICE *dev);
 
 
 /* From dev.c */
-DEVICE *init_dev(JCR *jcr, DEVICE *dev, DEVRES *device);
-int     open_dev(DEVICE *dev, char *VolName, int mode);
-off_t   lseek_dev(DEVICE *dev, off_t offset, int whence);
-int     open_first_part(DEVICE *dev);
-int     open_next_part(DEVICE *dev);
-int     open_guess_name_dev(DEVICE *dev);
-void    close_dev(DEVICE *dev);
-void    force_close_dev(DEVICE *dev);
-bool    truncate_dev(DEVICE *dev);
-void    term_dev(DEVICE *dev);
-char *  strerror_dev(DEVICE *dev);
-void    clrerror_dev(DEVICE *dev, int func);
-bool    update_pos_dev(DEVICE *dev);
-bool    rewind_dev(DEVICE *dev);
-bool    load_dev(DEVICE *dev);
-bool    offline_dev(DEVICE *dev);
-int     flush_dev(DEVICE *dev);
-int     weof_dev(DEVICE *dev, int num);
-int     write_block(DEVICE *dev);
+DEVICE  *init_dev(JCR *jcr, DEVICE *dev, DEVRES *device);
+int      open_dev(DEVICE *dev, char *VolName, int mode);
+off_t    lseek_dev(DEVICE *dev, off_t offset, int whence);
+int      open_first_part(DEVICE *dev);
+int      open_next_part(DEVICE *dev);
+int      open_guess_name_dev(DEVICE *dev);
+void     close_dev(DEVICE *dev);
+void     force_close_dev(DEVICE *dev);
+bool     truncate_dev(DEVICE *dev);
+void     term_dev(DEVICE *dev);
+char *   strerror_dev(DEVICE *dev);
+void     clrerror_dev(DEVICE *dev, int func);
+bool     update_pos_dev(DEVICE *dev);
+bool     rewind_dev(DEVICE *dev);
+bool     load_dev(DEVICE *dev);
+bool     offline_dev(DEVICE *dev);
+int      flush_dev(DEVICE *dev);
+int      weof_dev(DEVICE *dev, int num);
+int      write_block(DEVICE *dev);
 uint32_t status_dev(DEVICE *dev);
-bool    eod_dev(DEVICE *dev);
-bool    fsf_dev(DEVICE *dev, int num);
-bool    fsr_dev(DEVICE *dev, int num);
-bool    bsf_dev(DEVICE *dev, int num);
-bool    bsr_dev(DEVICE *dev, int num);
-void    attach_jcr_to_device(DEVICE *dev, JCR *jcr);
-void    detach_jcr_from_device(DEVICE *dev, JCR *jcr);
-JCR    *next_attached_jcr(DEVICE *dev, JCR *jcr);
-bool    dev_can_write(DEVICE *dev);
-bool    offline_or_rewind_dev(DEVICE *dev);
-bool    reposition_dev(DEVICE *dev, uint32_t file, uint32_t block);
-void    init_dev_wait_timers(DEVICE *dev);
-bool    double_dev_wait_time(DEVICE *dev);
+bool     eod_dev(DEVICE *dev);
+bool     fsf_dev(DEVICE *dev, int num);
+bool     fsr_dev(DEVICE *dev, int num);
+bool     bsf_dev(DEVICE *dev, int num);
+bool     bsr_dev(DEVICE *dev, int num);
+void     attach_jcr_to_device(DEVICE *dev, JCR *jcr);
+void     detach_jcr_from_device(DEVICE *dev, JCR *jcr);
+JCR     *next_attached_jcr(DEVICE *dev, JCR *jcr);
+bool     dev_can_write(DEVICE *dev);
+bool     offline_or_rewind_dev(DEVICE *dev);
+bool     reposition_dev(DEVICE *dev, uint32_t file, uint32_t block);
+void     init_device_wait_timers(DCR *dcr);
+bool     double_dev_wait_time(DEVICE *dev);
 
 /* Get info about device */
-char *  dev_vol_name(DEVICE *dev);
+char *   dev_vol_name(DEVICE *dev);
 uint32_t dev_block(DEVICE *dev);
 uint32_t dev_file(DEVICE *dev);
-bool    dev_is_tape(DEVICE *dev);
+bool     dev_is_tape(DEVICE *dev);
 
 /* From device.c */
-bool    open_device(DCR *dcr);
-bool    first_open_device(DEVICE *dev);
-bool    fixup_device_block_write_error(DCR *dcr);
-void    _lock_device(const char *file, int line, DEVICE *dev);
-void    _unlock_device(const char *file, int line, DEVICE *dev);
-void    _block_device(const char *file, int line, DEVICE *dev, int state);
-void    _unblock_device(const char *file, int line, DEVICE *dev);
-void    _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state);
-void    _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold);
-void    set_new_volume_parameters(DCR *dcr);
-void    set_new_file_parameters(DCR *dcr);
-bool    device_is_unmounted(DEVICE *dev);
-void    dev_lock(DEVICE *dev);
-void    dev_unlock(DEVICE *dev);
+bool     open_device(DCR *dcr);
+bool     first_open_device(DEVICE *dev);
+bool     fixup_device_block_write_error(DCR *dcr);
+void     _lock_device(const char *file, int line, DEVICE *dev);
+void     _unlock_device(const char *file, int line, DEVICE *dev);
+void     _block_device(const char *file, int line, DEVICE *dev, int state);
+void     _unblock_device(const char *file, int line, DEVICE *dev);
+void     _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state);
+void     _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold);
+void     set_new_volume_parameters(DCR *dcr);
+void     set_new_file_parameters(DCR *dcr);
+bool     device_is_unmounted(DEVICE *dev);
+void     dev_lock(DEVICE *dev);
+void     dev_unlock(DEVICE *dev);
 const char *edit_blocked_reason(DEVICE *dev);
 
 /* From dircmd.c */
-void    *handle_connection_request(void *arg);
+void     *handle_connection_request(void *arg);
 
 
 /* From fd_cmds.c */
-void    run_job(JCR *jcr);
-bool    bootstrap_cmd(JCR *jcr);
+void     run_job(JCR *jcr);
+bool     bootstrap_cmd(JCR *jcr);
 
 /* From job.c */
-void    stored_free_jcr(JCR *jcr);
-void    connection_from_filed(void *arg);
-void    handle_filed_connection(BSOCK *fd, char *job_name);
+void     stored_free_jcr(JCR *jcr);
+void     connection_from_filed(void *arg);
+void     handle_filed_connection(BSOCK *fd, char *job_name);
 
 /* From label.c */
-int     read_dev_volume_label(DCR *dcr);
-int     read_dev_volume_label_guess(DCR *dcr, bool write);
-void    create_session_label(DCR *dcr, DEV_RECORD *rec, int label);
-void    create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName);
-bool    write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName);
+int      read_dev_volume_label(DCR *dcr);
+int      read_dev_volume_label_guess(DCR *dcr, bool write);
+void     create_session_label(DCR *dcr, DEV_RECORD *rec, int label);
+void     create_volume_label(DEVICE *dev, const char *VolName, const char *PoolName);
+bool     write_new_volume_label_to_dev(DCR *dcr, const char *VolName, const char *PoolName);
 #define ANSI_VOL_LABEL 0
 #define ANSI_EOF_LABEL 1
 #define ANSI_EOV_LABEL 2
-bool    write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName);
-int     read_ansi_ibm_label(DCR *dcr);
-bool    write_session_label(DCR *dcr, int label);
-bool    write_volume_label_to_block(DCR *dcr);
-bool    rewrite_volume_label(DCR *dcr, bool recycle);
-void    dump_volume_label(DEVICE *dev);
-void    dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
-bool    unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
-bool    unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
+bool     write_ansi_ibm_labels(DCR *dcr, int type, const char *VolName);
+int      read_ansi_ibm_label(DCR *dcr);
+bool     write_session_label(DCR *dcr, int label);
+bool     write_volume_label_to_block(DCR *dcr);
+bool     rewrite_volume_label(DCR *dcr, bool recycle);
+void     dump_volume_label(DEVICE *dev);
+void     dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose);
+bool     unser_volume_label(DEVICE *dev, DEV_RECORD *rec);
+bool     unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec);
 
 /* From match_bsr.c */
-int     match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
-             SESSION_LABEL *sesrec);
-int     match_bsr_block(BSR *bsr, DEV_BLOCK *block);
-void    position_bsr_block(BSR *bsr, DEV_BLOCK *block);
-BSR    *find_next_bsr(BSR *root_bsr, DEVICE *dev);
-bool    match_set_eof(BSR *bsr, DEV_RECORD *rec);
+int      match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
+              SESSION_LABEL *sesrec);
+int      match_bsr_block(BSR *bsr, DEV_BLOCK *block);
+void     position_bsr_block(BSR *bsr, DEV_BLOCK *block);
+BSR     *find_next_bsr(BSR *root_bsr, DEVICE *dev);
+bool     match_set_eof(BSR *bsr, DEV_RECORD *rec);
 
 /* From mount.c */
-bool    mount_next_write_volume(DCR *dcr, bool release);
-bool    mount_next_read_volume(DCR *dcr);
-void    release_volume(DCR *ddr);
-void    mark_volume_in_error(DCR *dcr);
+bool     mount_next_write_volume(DCR *dcr, bool release);
+bool     mount_next_read_volume(DCR *dcr);
+void     release_volume(DCR *ddr);
+void     mark_volume_in_error(DCR *dcr);
 
 /* From parse_bsr.c */
-BSR    *parse_bsr(JCR *jcr, char *lf);
-void    dump_bsr(BSR *bsr, bool recurse);
-void    free_bsr(BSR *bsr);
+BSR     *parse_bsr(JCR *jcr, char *lf);
+void     dump_bsr(BSR *bsr, bool recurse);
+void     free_bsr(BSR *bsr);
 VOL_LIST *new_vol();
-int     add_vol(JCR *jcr, VOL_LIST *vol);
-void    free_vol_list(JCR *jcr);
-void    create_vol_list(JCR *jcr);
+int      add_vol(JCR *jcr, VOL_LIST *vol);
+void     free_vol_list(JCR *jcr);
+void     create_vol_list(JCR *jcr);
 
 /* From record.c */
 const char *FI_to_ascii(int fi);
 const char *stream_to_ascii(int stream, int fi);
-bool       write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-bool       can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
-bool       read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool        write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool        can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec);
+bool        read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec);
 DEV_RECORD *new_record();
-void       free_record(DEV_RECORD *rec);
-void       empty_record(DEV_RECORD *rec);
+void        free_record(DEV_RECORD *rec);
+void        empty_record(DEV_RECORD *rec);
 
 /* From read_record.c */
 bool read_records(DCR *dcr,
@@ -215,15 +215,16 @@ bool read_records(DCR *dcr,
        bool mount_cb(DCR *dcr));
 
 /* From spool.c */
-bool   begin_data_spool          (DCR *dcr);
-bool   discard_data_spool        (DCR *dcr);
-bool   commit_data_spool         (DCR *dcr);
-bool   are_attributes_spooled    (JCR *jcr);
-bool   begin_attribute_spool     (JCR *jcr);
-bool   discard_attribute_spool   (JCR *jcr);
-bool   commit_attribute_spool    (JCR *jcr);
-bool   write_block_to_spool_file (DCR *dcr);
-void   list_spool_stats          (BSOCK *bs);
+bool    begin_data_spool          (DCR *dcr);
+bool    discard_data_spool        (DCR *dcr);
+bool    commit_data_spool         (DCR *dcr);
+bool    are_attributes_spooled    (JCR *jcr);
+bool    begin_attribute_spool     (JCR *jcr);
+bool    discard_attribute_spool   (JCR *jcr);
+bool    commit_attribute_spool    (JCR *jcr);
+bool    write_block_to_spool_file (DCR *dcr);
+void    list_spool_stats          (BSOCK *bs);
 
 /* From wait.c */
 int wait_for_sysop(DCR *dcr);
+bool wait_for_device(DCR *dcr, const char *msg, bool first);
index 206a8c82072384751e054f5f4ed8995913100a24..818cfe9a704fa55911efe279953466d0edcb93cc 100644 (file)
@@ -41,16 +41,16 @@ static void check_config();
 
 extern "C" void *device_allocation(void *arg);
 
-
-
 #define CONFIG_FILE "bacula-sd.conf"  /* Default config file */
 
-
 /* Global variables exported */
 char OK_msg[]   = "3000 OK\n";
 char TERM_msg[] = "3999 Terminate\n";
 STORES *me = NULL;                   /* our Global resource */
 bool forge_on = false;               /* proceed inspite of I/O errors */
+pthread_mutex_t device_release_mutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t wait_device_release = PTHREAD_COND_INITIALIZER;
+
 
 static uint32_t VolSessionId = 0;
 uint32_t VolSessionTime;
@@ -413,7 +413,8 @@ void terminate_stored(int sig)
            pthread_kill(jcr->my_thread_id, TIMEOUT_SIGNAL);
            /* ***FIXME*** wiffle through all dcrs */
            if (jcr->dcr && jcr->dcr->dev && jcr->dcr->dev->dev_blocked) {
-              pthread_cond_signal(&jcr->dcr->dev->wait_next_vol);
+              pthread_cond_broadcast(&jcr->dcr->dev->wait_next_vol);
+              pthread_cond_broadcast(&wait_device_release);
            }
            bmicrosleep(0, 50000);
          }
index cfd68b0e834861c74f075df13766fdf171991e83..e9859f92502a056deb4fa5a0eb687bd404e85cf6 100644 (file)
 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result);
 #endif
 
+/* Daemon globals from stored.c */
 extern STORES *me;                    /* "Global" daemon resource */
 extern bool forge_on;                /* proceed inspite of I/O errors */
+extern pthread_mutex_t device_release_mutex;
+extern pthread_cond_t wait_device_release; /* wait for any device to be released */                          
 
 #ifdef debug_tracing
 extern int _rewind_dev(char *file, int line, DEVICE *dev);
index 679fe13677cca5def4df3ee04d4e275503e211f4..c855e405c7cbed27956cf92e4469c0b9d0d9326b 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #undef  VERSION
 #define VERSION "1.37.8"
-#define BDATE   "22 March 2005"
-#define LSMDATE "22Mar05"
+#define BDATE   "25 March 2005"
+#define LSMDATE "25Mar05"
 
 /* Debug flags */
 #undef  DEBUG