]> git.sur5r.net Git - bacula/bacula/commitdiff
Move main SD locking code into lock.c (new file).
authorKern Sibbald <kern@sibbald.com>
Tue, 26 Jun 2007 14:43:32 +0000 (14:43 +0000)
committerKern Sibbald <kern@sibbald.com>
Tue, 26 Jun 2007 14:43:32 +0000 (14:43 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@5100 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/kernstodo
bacula/src/stored/Makefile.in
bacula/src/stored/lock.c [new file with mode: 0644]
bacula/src/stored/locks.c [deleted file]
bacula/src/version.h
bacula/technotes-2.1

index 068b7019bcf011075b03381f6891efc389629cfc..3fd15134324de4aa0e1526359d554b86785c5208 100644 (file)
@@ -58,6 +58,9 @@ Professional Needs:
   http://www.microsoft.com/technet/itshowcase/content/exchbkup.mspx
 
 Priority:
+- Performance: multiple spool files for a single job.
+- Performance: despool attributes when despooling data (problem
+  multiplexing Dir connection).
 - Make restore use the in-use volume reservation algorithm.
 - Look at mincore: http://insights.oetiker.ch/linux/fadvise.html
 - Unicode input http://en.wikipedia.org/wiki/Byte_Order_Mark
index 490cb2648324348189d8847cef1cc314512adaae..9c7a8eafd072caac69d0b7682eec425b93d784f9 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 locks.o mac.o match_bsr.o mount.o parse_bsr.o \
+         label.o lock.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 \
-          locks.o ansi_label.o dvd.o ebcdic.o \
+          lock.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 locks.o \
+         ansi_label.o dvd.o ebcdic.o lock.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 locks.o \
+          ansi_label.o dvd.o ebcdic.o lock.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 locks.o \
+         ansi_label.o dvd.o ebcdic.o lock.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 locks.o \
+          ansi_label.o dvd.o ebcdic.o lock.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
diff --git a/bacula/src/stored/lock.c b/bacula/src/stored/lock.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;
+}
+
diff --git a/bacula/src/stored/locks.c b/bacula/src/stored/locks.c
deleted file mode 100644 (file)
index c57559d..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
-   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 2bce5f5292387ab796f6757324535c9781d4a10a..4a72952153f3f4caca9ef58e8c08f2f9834c9dbd 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 #undef  VERSION
-#define VERSION "2.1.22"
+#define VERSION "2.1.23"
 #define BDATE   "26 June 2007"
 #define LSMDATE "26Jun07"
 
index 93230e409cf2f4eb682568e8f6d879b66e64fc88..8da5e9fe6b45ecdd6b0ad741741268bc0c809969 100644 (file)
@@ -2,6 +2,9 @@
 
 General:
 
+26Jun07
+kes  Move main SD locking code into lock.c (new file).
+
 Release 2.1.22 beta
 26Jun07
 kes  Dirk committed the qwt library code for drawing graphs in bat.