]> git.sur5r.net Git - bacula/bacula/commitdiff
New file
authorKern Sibbald <kern@sibbald.com>
Tue, 26 Jun 2007 14:41:57 +0000 (14:41 +0000)
committerKern Sibbald <kern@sibbald.com>
Tue, 26 Jun 2007 14:41:57 +0000 (14:41 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@5099 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/stored/Makefile.in
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/device.c
bacula/src/stored/locks.c [new file with mode: 0644]
bacula/src/stored/protos.h

index 6e9456ae3b460ff7fc3e7ac1ac780ad402dc310e..490cb2648324348189d8847cef1cc314512adaae 100644 (file)
@@ -25,40 +25,40 @@ SDOBJS =  stored.o ansi_label.o \
          askdir.o authenticate.o \
          block.o butil.o dev.o \
          device.o dircmd.o dvd.o ebcdic.o fd_cmds.o job.o \
-         label.o mac.o match_bsr.o mount.o parse_bsr.o \
+         label.o locks.o mac.o match_bsr.o mount.o parse_bsr.o \
          pythonsd.o read.o read_record.o record.o \
          reserve.o scan.o \
          spool.o status.o stored_conf.o wait.o
 
 # btape
 TAPEOBJS = btape.o block.o butil.o dev.o device.o label.o \
-          ansi_label.o dvd.o ebcdic.o \
+          locks.o ansi_label.o dvd.o ebcdic.o \
           autochanger.o acquire.o mount.o record.o read_record.o \
           reserve.o \
           stored_conf.o match_bsr.o parse_bsr.o scan.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 \
+         ansi_label.o dvd.o ebcdic.o locks.o \
          autochanger.o acquire.o mount.o parse_bsr.o record.o  \
          read_record.o reserve.o scan.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 \
+          ansi_label.o dvd.o ebcdic.o locks.o \
           autochanger.o acquire.o mount.o match_bsr.o parse_bsr.o butil.o \
           pythonsd.o read_record.o reserve.o \
           scan.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 \
+         ansi_label.o dvd.o ebcdic.o locks.o \
          autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \
          butil.o read_record.o scan.o reserve.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 \
+          ansi_label.o dvd.o ebcdic.o locks.o \
           autochanger.o acquire.o mount.o record.o match_bsr.o parse_bsr.o \
           butil.o read_record.o reserve.o \
           scan.o stored_conf.o spool.o wait.o
index 77f6cfd62d09f0c3869771c1a34ed44a187951b1..08dc97f67a4281b73ce888124d235b73742f2ec4 100644 (file)
@@ -781,44 +781,6 @@ bool DEVICE::rewind(DCR *dcr)
    return true;
 }
 
-void DEVICE::block(int why)
-{
-   r_dlock();              /* need recursive lock to block */
-   block_device(this, why);
-   r_dunlock();
-}
-
-void DEVICE::unblock(bool locked)
-{
-   if (!locked) {
-      dlock();
-   }
-   unblock_device(this);
-   dunlock();
-}
-
-
-const char *DEVICE::print_blocked() const 
-{
-   switch (m_blocked) {
-   case BST_NOT_BLOCKED:
-      return "BST_NOT_BLOCKED";
-   case BST_UNMOUNTED:
-      return "BST_UNMOUNTED";
-   case BST_WAITING_FOR_SYSOP:
-      return "BST_WAITING_FOR_SYSOP";
-   case BST_DOING_ACQUIRE:
-      return "BST_DOING_ACQUIRE";
-   case BST_WRITING_LABEL:
-      return "BST_WRITING_LABEL";
-   case BST_UNMOUNTED_WAITING_FOR_SYSOP:
-      return "BST_UNMOUNTED_WAITING_FOR_SYSOP";
-   case BST_MOUNT:
-      return "BST_MOUNT";
-   default:
-      return _("unknown blocked code");
-   }
-}
 
 /*
  * Called to indicate that we have just read an
index 91c421d81890f3418a68cb19e1fdb93120d34d27..bb8d33ed7d9fb419be3c2f3273ee9526e6b25e84 100644 (file)
@@ -393,8 +393,8 @@ public:
 #endif
 
    void clear_volhdr();          /* in dev.c */
-   void block(int why);          /* in dev.c */
-   void unblock(bool locked=false); /* in dev.c */
+   void block(int why);          /* in locks.c */
+   void unblock(bool locked=false); /* in locks.c */
    void close();                 /* in dev.c */
    void close_part(DCR *dcr);    /* in dev.c */
    bool truncate(DCR *dcr);      /* in dev.c */
index c57b9151dc24ecb0e04952b1b27632bbf7e01a84..e864226b3656661270a414f6a2db74e33c3b0275 100644 (file)
 #include "bacula.h"                   /* pull in global headers */
 #include "stored.h"                   /* pull in Storage Deamon headers */
 
-#ifdef SD_DEBUG_LOCK
-const int dbglvl = 0;
-#else
-const int dbglvl = 500;
-#endif
-
-
 /* Forward referenced functions */
 
 /*
@@ -322,155 +315,3 @@ bool open_device(DCR *dcr)
    }
    return true;
 }
-
-
-/*
- * Check if the device is blocked or not
- */
-bool is_device_unmounted(DEVICE *dev)
-{
-   bool stat;
-   int blocked = dev->blocked();
-   stat = (blocked == BST_UNMOUNTED) ||
-          (blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
-   return stat;
-}
-
-#ifdef SD_DEBUG_LOCK
-void DEVICE::_dlock(const char *file, int line)
-{
-   Dmsg4(sd_dbglvl, "dlock from %s:%d precnt=%d JobId=%u\n", file, line,
-         m_count, get_jobid_from_tid()); 
-   /* Note, this *really* should be protected by a mutex, but
-    *  since it is only debug code we don't worry too much.  
-    */
-   if (m_count > 0 && pthread_equal(m_pid, pthread_self())) {
-      Dmsg5(sd_dbglvl, "Possible DEADLOCK!! lock held by JobId=%u from %s:%d m_count=%d JobId=%u\n", 
-            get_jobid_from_tid(m_pid),
-            file, line, m_count, get_jobid_from_tid());
-   }
-   P(m_mutex);
-   m_pid = pthread_self();
-   m_count++; 
-}
-
-void DEVICE::_dunlock(const char *file, int line)
-{
-   m_count--; 
-   Dmsg4(sd_dbglvl+1, "dunlock from %s:%d postcnt=%d JobId=%u\n", file, line,
-         m_count, get_jobid_from_tid()); 
-   V(m_mutex);   
-}
-
-void DEVICE::_r_dunlock(const char *file, int line)
-{
-   this->_dunlock(file, line);
-}
-
-#endif
-
-
-/*
- * This is a recursive lock that checks if the device is blocked.
- *
- * When blocked is set, all threads EXCEPT thread with id no_wait_id
- * must wait. The no_wait_id thread is out obtaining a new volume
- * and preparing the label.
- */
-#ifdef SD_DEBUG_LOCK
-void DEVICE::_r_dlock(const char *file, int line)
-#else
-void DEVICE::r_dlock()
-#endif
-{
-   int stat;
-#ifdef SD_DEBUG_LOCK
-   Dmsg4(sd_dbglvl+1, "r_dlock blked=%s from %s:%d JobId=%u\n", this->print_blocked(),
-         file, line, get_jobid_from_tid());
-#else
-   Dmsg1(sd_dbglvl, "reclock blked=%s\n", this->print_blocked());
-#endif
-   this->dlock();   
-   if (this->blocked() && !pthread_equal(this->no_wait_id, pthread_self())) {
-      this->num_waiting++;             /* indicate that I am waiting */
-      while (this->blocked()) {
-         Dmsg3(sd_dbglvl, "r_dlock blked=%s no_wait=%p me=%p\n", this->print_blocked(),
-               this->no_wait_id, pthread_self());
-         if ((stat = pthread_cond_wait(&this->wait, &m_mutex)) != 0) {
-            berrno be;
-            this->dunlock();
-            Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
-               be.bstrerror(stat));
-         }
-      }
-      this->num_waiting--;             /* no longer waiting */
-   }
-}
-
-/*
- * Block all other threads from using the device
- *  Device must already be locked.  After this call,
- *  the device is blocked to any thread calling dev->r_lock(),
- *  but the device is not locked (i.e. no P on device).  Also,
- *  the current thread can do slip through the dev->r_lock()
- *  calls without blocking.
- */
-void _block_device(const char *file, int line, DEVICE *dev, int state)
-{
-   ASSERT(dev->blocked() == BST_NOT_BLOCKED);
-   dev->set_blocked(state);           /* make other threads wait */
-   dev->no_wait_id = pthread_self();  /* allow us to continue */
-   Dmsg3(sd_dbglvl, "set blocked=%s from %s:%d\n", dev->print_blocked(), file, line);
-}
-
-/*
- * Unblock the device, and wake up anyone who went to sleep.
- * Enter: device locked
- * Exit:  device locked
- */
-void _unblock_device(const char *file, int line, DEVICE *dev)
-{
-   Dmsg3(sd_dbglvl, "unblock %s from %s:%d\n", dev->print_blocked(), file, line);
-   ASSERT(dev->blocked());
-   dev->set_blocked(BST_NOT_BLOCKED);
-   dev->no_wait_id = 0;
-   if (dev->num_waiting > 0) {
-      pthread_cond_broadcast(&dev->wait); /* wake them up */
-   }
-}
-
-/*
- * Enter with device locked and blocked
- * Exit with device unlocked and blocked by us.
- */
-void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state)
-{
-
-   Dmsg3(sd_dbglvl, "steal lock. old=%s from %s:%d\n", dev->print_blocked(),
-      file, line);
-   hold->dev_blocked = dev->blocked();
-   hold->dev_prev_blocked = dev->dev_prev_blocked;
-   hold->no_wait_id = dev->no_wait_id;
-   dev->set_blocked(state);
-   Dmsg1(sd_dbglvl, "steal lock. new=%s\n", dev->print_blocked());
-   dev->no_wait_id = pthread_self();
-   dev->dunlock();
-}
-
-/*
- * Enter with device blocked by us but not locked
- * Exit with device locked, and blocked by previous owner
- */
-void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold)
-{
-   Dmsg3(sd_dbglvl, "return lock. old=%s from %s:%d\n",
-      dev->print_blocked(), file, line);
-   dev->dlock();
-   dev->set_blocked(hold->dev_blocked);
-   dev->dev_prev_blocked = hold->dev_prev_blocked;
-   dev->no_wait_id = hold->no_wait_id;
-   Dmsg1(sd_dbglvl, "return lock. new=%s\n", dev->print_blocked());
-   if (dev->num_waiting > 0) {
-      pthread_cond_broadcast(&dev->wait); /* wake them up */
-   }
-}
diff --git a/bacula/src/stored/locks.c b/bacula/src/stored/locks.c
new file mode 100644 (file)
index 0000000..c57559d
--- /dev/null
@@ -0,0 +1,236 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
+
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version two of the GNU General Public
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula® is a registered trademark of John Walker.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
+/*
+ * Collection of Bacula Storage daemon locking software
+ *
+ *  Kern Sibbald, 2000-2007.  June 2007
+ *
+ *   Version $Id$
+ */
+
+#include "bacula.h"                   /* pull in global headers */
+#include "stored.h"                   /* pull in Storage Deamon headers */
+
+#ifdef SD_DEBUG_LOCK
+const int dbglvl = 0;
+#else
+const int dbglvl = 500;
+#endif
+
+
+void DEVICE::block(int why)
+{
+   r_dlock();              /* need recursive lock to block */
+   block_device(this, why);
+   r_dunlock();
+}
+
+void DEVICE::unblock(bool locked)
+{
+   if (!locked) {
+      dlock();
+   }
+   unblock_device(this);
+   dunlock();
+}
+
+
+#ifdef SD_DEBUG_LOCK
+void DEVICE::_dlock(const char *file, int line)
+{
+   Dmsg4(sd_dbglvl, "dlock from %s:%d precnt=%d JobId=%u\n", file, line,
+         m_count, get_jobid_from_tid()); 
+   /* Note, this *really* should be protected by a mutex, but
+    *  since it is only debug code we don't worry too much.  
+    */
+   if (m_count > 0 && pthread_equal(m_pid, pthread_self())) {
+      Dmsg5(sd_dbglvl, "Possible DEADLOCK!! lock held by JobId=%u from %s:%d m_count=%d JobId=%u\n", 
+            get_jobid_from_tid(m_pid),
+            file, line, m_count, get_jobid_from_tid());
+   }
+   P(m_mutex);
+   m_pid = pthread_self();
+   m_count++; 
+}
+
+void DEVICE::_dunlock(const char *file, int line)
+{
+   m_count--; 
+   Dmsg4(sd_dbglvl+1, "dunlock from %s:%d postcnt=%d JobId=%u\n", file, line,
+         m_count, get_jobid_from_tid()); 
+   V(m_mutex);   
+}
+
+void DEVICE::_r_dunlock(const char *file, int line)
+{
+   this->_dunlock(file, line);
+}
+
+#endif
+
+
+/*
+ * This is a recursive lock that checks if the device is blocked.
+ *
+ * When blocked is set, all threads EXCEPT thread with id no_wait_id
+ * must wait. The no_wait_id thread is out obtaining a new volume
+ * and preparing the label.
+ */
+#ifdef SD_DEBUG_LOCK
+void DEVICE::_r_dlock(const char *file, int line)
+#else
+void DEVICE::r_dlock()
+#endif
+{
+   int stat;
+#ifdef SD_DEBUG_LOCK
+   Dmsg4(sd_dbglvl+1, "r_dlock blked=%s from %s:%d JobId=%u\n", this->print_blocked(),
+         file, line, get_jobid_from_tid());
+#else
+   Dmsg1(sd_dbglvl, "reclock blked=%s\n", this->print_blocked());
+#endif
+   this->dlock();   
+   if (this->blocked() && !pthread_equal(this->no_wait_id, pthread_self())) {
+      this->num_waiting++;             /* indicate that I am waiting */
+      while (this->blocked()) {
+         Dmsg3(sd_dbglvl, "r_dlock blked=%s no_wait=%p me=%p\n", this->print_blocked(),
+               this->no_wait_id, pthread_self());
+         if ((stat = pthread_cond_wait(&this->wait, &m_mutex)) != 0) {
+            berrno be;
+            this->dunlock();
+            Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
+               be.bstrerror(stat));
+         }
+      }
+      this->num_waiting--;             /* no longer waiting */
+   }
+}
+
+/*
+ * Block all other threads from using the device
+ *  Device must already be locked.  After this call,
+ *  the device is blocked to any thread calling dev->r_lock(),
+ *  but the device is not locked (i.e. no P on device).  Also,
+ *  the current thread can do slip through the dev->r_lock()
+ *  calls without blocking.
+ */
+void _block_device(const char *file, int line, DEVICE *dev, int state)
+{
+   ASSERT(dev->blocked() == BST_NOT_BLOCKED);
+   dev->set_blocked(state);           /* make other threads wait */
+   dev->no_wait_id = pthread_self();  /* allow us to continue */
+   Dmsg3(sd_dbglvl, "set blocked=%s from %s:%d\n", dev->print_blocked(), file, line);
+}
+
+/*
+ * Unblock the device, and wake up anyone who went to sleep.
+ * Enter: device locked
+ * Exit:  device locked
+ */
+void _unblock_device(const char *file, int line, DEVICE *dev)
+{
+   Dmsg3(sd_dbglvl, "unblock %s from %s:%d\n", dev->print_blocked(), file, line);
+   ASSERT(dev->blocked());
+   dev->set_blocked(BST_NOT_BLOCKED);
+   dev->no_wait_id = 0;
+   if (dev->num_waiting > 0) {
+      pthread_cond_broadcast(&dev->wait); /* wake them up */
+   }
+}
+
+/*
+ * Enter with device locked and blocked
+ * Exit with device unlocked and blocked by us.
+ */
+void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state)
+{
+
+   Dmsg3(sd_dbglvl, "steal lock. old=%s from %s:%d\n", dev->print_blocked(),
+      file, line);
+   hold->dev_blocked = dev->blocked();
+   hold->dev_prev_blocked = dev->dev_prev_blocked;
+   hold->no_wait_id = dev->no_wait_id;
+   dev->set_blocked(state);
+   Dmsg1(sd_dbglvl, "steal lock. new=%s\n", dev->print_blocked());
+   dev->no_wait_id = pthread_self();
+   dev->dunlock();
+}
+
+/*
+ * Enter with device blocked by us but not locked
+ * Exit with device locked, and blocked by previous owner
+ */
+void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold)
+{
+   Dmsg3(sd_dbglvl, "return lock. old=%s from %s:%d\n",
+      dev->print_blocked(), file, line);
+   dev->dlock();
+   dev->set_blocked(hold->dev_blocked);
+   dev->dev_prev_blocked = hold->dev_prev_blocked;
+   dev->no_wait_id = hold->no_wait_id;
+   Dmsg1(sd_dbglvl, "return lock. new=%s\n", dev->print_blocked());
+   if (dev->num_waiting > 0) {
+      pthread_cond_broadcast(&dev->wait); /* wake them up */
+   }
+}
+
+const char *DEVICE::print_blocked() const 
+{
+   switch (m_blocked) {
+   case BST_NOT_BLOCKED:
+      return "BST_NOT_BLOCKED";
+   case BST_UNMOUNTED:
+      return "BST_UNMOUNTED";
+   case BST_WAITING_FOR_SYSOP:
+      return "BST_WAITING_FOR_SYSOP";
+   case BST_DOING_ACQUIRE:
+      return "BST_DOING_ACQUIRE";
+   case BST_WRITING_LABEL:
+      return "BST_WRITING_LABEL";
+   case BST_UNMOUNTED_WAITING_FOR_SYSOP:
+      return "BST_UNMOUNTED_WAITING_FOR_SYSOP";
+   case BST_MOUNT:
+      return "BST_MOUNT";
+   default:
+      return _("unknown blocked code");
+   }
+}
+
+
+/*
+ * Check if the device is blocked or not
+ */
+bool is_device_unmounted(DEVICE *dev)
+{
+   bool stat;
+   int blocked = dev->blocked();
+   stat = (blocked == BST_UNMOUNTED) ||
+          (blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
+   return stat;
+}
+
index 1fd5355f14be8223cbc586d12af4ccfe513c91e1..bbdf17b53625b22a077221e2d09a40b60561557e 100644 (file)
@@ -126,12 +126,6 @@ void    dvd_remove_empty_part(DCR *dcr);
 bool     open_device(DCR *dcr);
 bool     first_open_device(DCR *dcr);
 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     is_device_unmounted(DEVICE *dev);
@@ -170,6 +164,15 @@ 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 locks.c */
+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);
+
+
 /* From match_bsr.c */
 int      match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec,
               SESSION_LABEL *sesrec);