]> git.sur5r.net Git - bacula/bacula/commitdiff
kes Move lock structures into new file lock.h
authorKern Sibbald <kern@sibbald.com>
Thu, 28 Jun 2007 11:57:03 +0000 (11:57 +0000)
committerKern Sibbald <kern@sibbald.com>
Thu, 28 Jun 2007 11:57:03 +0000 (11:57 +0000)
kes  Use jcr lock for locking reservations messages rather than
     the reservations lock.
kes  Rename a number of locking functions to make their sense a
     bit more logical (more to be done), also rename a few other
     methods in the DEVICE structure.
kes  Add a good bit of documentation of the SD locking mechanisms
     to src/stored/lock.c
kes  Convert a number of bnet_xx calls to use the new bsock class.

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

12 files changed:
bacula/src/stored/acquire.c
bacula/src/stored/append.c
bacula/src/stored/block.c
bacula/src/stored/dev.c
bacula/src/stored/dev.h
bacula/src/stored/label.c
bacula/src/stored/lock.c
bacula/src/stored/lock.h [new file with mode: 0644]
bacula/src/stored/protos.h
bacula/src/stored/reserve.c
bacula/src/stored/stored.h
bacula/src/version.h

index 0f6a89017af17a508002f34d024c32cd7d92770b..57e359da84afed3278a9696e4be8f6a0aeae243c 100644 (file)
@@ -63,7 +63,7 @@ bool acquire_device_for_read(DCR *dcr)
    int retry = 0;
    
    Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
-   dev->block(BST_DOING_ACQUIRE);
+   dev->dblock(BST_DOING_ACQUIRE);
 
    if (dev->num_writers > 0) {
       Jmsg2(jcr, M_FATAL, 0, _("Acquire read: num_writers=%d not zero. Job %d canceled.\n"), 
@@ -129,11 +129,11 @@ bool acquire_device_for_read(DCR *dcr)
        *  which we do not use except for the dev info.
        */
       stat = search_res_for_device(rctx);
-      release_msgs(jcr);              /* release queued messages */
+      release_reserve_messages(jcr);         /* release queued messages */
       unlock_reservations();
       if (stat == 1) {
          DCR *ndcr = jcr->read_dcr;
-         dev->unblock(dev_unlocked);
+         dev->dunblock(dev_unlocked);
          detach_dcr_from_dev(dcr);    /* release old device */
          /* Copy important info from the new dcr */
          dev = dcr->dev = ndcr->dev; 
@@ -143,7 +143,7 @@ bool acquire_device_for_read(DCR *dcr)
          attach_dcr_to_dev(dcr);
          ndcr->VolumeName[0] = 0;
          free_dcr(ndcr);
-         dev->block(BST_DOING_ACQUIRE); 
+         dev->dblock(BST_DOING_ACQUIRE); 
          Jmsg(jcr, M_INFO, 0, _("Media Type change.  New device %s chosen.\n"),
             dev->print_name());
          bstrncpy(dcr->VolumeName, vol->VolumeName, sizeof(dcr->VolumeName));
@@ -290,7 +290,7 @@ get_out:
       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
       dcr->reserved_device = false;
    }
-   dev->unblock(dev_locked);
+   dev->dunblock(dev_locked);
    Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
    return ok;
 }
@@ -315,7 +315,7 @@ DCR *acquire_device_for_append(DCR *dcr)
 
    init_device_wait_timers(dcr);
 
-   dev->block(BST_DOING_ACQUIRE);
+   dev->dblock(BST_DOING_ACQUIRE);
    Dmsg1(190, "acquire_append device is %s\n", dev->is_tape()?"tape":
         (dev->is_dvd()?"DVD":"disk"));
 
@@ -439,7 +439,7 @@ DCR *acquire_device_for_append(DCR *dcr)
       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
       dcr->reserved_device = false;
    }
-   dev->unblock(dev_locked);
+   dev->dunblock(dev_locked);
    return dcr;
 
 /*
@@ -452,7 +452,7 @@ get_out:
       Dmsg2(100, "Dec reserve=%d dev=%s\n", dev->reserved_device, dev->print_name());
       dcr->reserved_device = false;
    }
-   dev->unblock(dev_locked);
+   dev->dunblock(dev_locked);
    return NULL;
 }
 
@@ -560,7 +560,6 @@ bool release_device(DCR *dcr)
    pthread_cond_broadcast(&dev->wait_next_vol);
    Dmsg1(100, "JobId=%u broadcast wait_device_release\n", (uint32_t)jcr->JobId);
    pthread_cond_broadcast(&wait_device_release);
-   dcr->dev_locked = false;              /* set no longer locked */
    dev->dunlock();
    if (jcr->read_dcr == dcr) {
       jcr->read_dcr = NULL;
index 1bda34c632c1eeb22aa03c5ced91d4795bc1bb0d..6519c7012366f10c05c41af6f3bc347895625b72 100644 (file)
@@ -1,9 +1,3 @@
-/*
- * Append code for Storage daemon
- *  Kern Sibbald, May MM
- *
- *  Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ * Append code for Storage daemon
+ *  Kern Sibbald, May MM
+ *
+ *  Version $Id$
+ */
 
 #include "bacula.h"
 #include "stored.h"
@@ -76,7 +76,7 @@ bool do_append_data(JCR *jcr)
 
    ds = fd_sock;
 
-   if (!bnet_set_buffer_size(ds, dcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) {
+   if (!ds->set_buffer_size(dcr->device->max_network_buffer_size, BNET_SETBUF_WRITE)) {
       set_jcr_job_status(jcr, JS_ErrorTerminated);
       Jmsg0(jcr, M_FATAL, 0, _("Unable to set network buffer size.\n"));
       return false;
@@ -116,7 +116,7 @@ bool do_append_data(JCR *jcr)
    }
 
    /* Tell File daemon to send data */
-   if (!bnet_fsend(fd_sock, OK_data)) {
+   if (!fd_sock->fsend(OK_data)) {
       berrno be;
       Jmsg1(jcr, M_FATAL, 0, _("Network send error to FD. ERR=%s\n"),
             be.bstrerror(fd_sock->b_errno));
@@ -156,7 +156,7 @@ bool do_append_data(JCR *jcr)
             break;                    /* end of data */
          }
          Jmsg1(jcr, M_FATAL, 0, _("Error reading data header from FD. ERR=%s\n"),
-               bnet_strerror(ds));
+               ds->bstrerror());
          ok = false;
          break;
       }
@@ -242,7 +242,7 @@ bool do_append_data(JCR *jcr)
                if (!dir_update_file_attributes(dcr, &rec)) {
                   jcr->dir_bsock->clear_spooling();
                   Jmsg(jcr, M_FATAL, 0, _("Error updating file attributes. ERR=%s\n"),
-                     bnet_strerror(jcr->dir_bsock));
+                     jcr->dir_bsock->bstrerror());
                   ok = false;
                   break;
                }
@@ -254,9 +254,9 @@ bool do_append_data(JCR *jcr)
       Dmsg1(650, "End read loop with FD. Stat=%d\n", n);
 
       if (is_bnet_error(ds)) {
-         Dmsg1(350, "Network read error from FD. ERR=%s\n", bnet_strerror(ds));
+         Dmsg1(350, "Network read error from FD. ERR=%s\n", ds->bstrerror());
          Jmsg1(jcr, M_FATAL, 0, _("Network error on data channel. ERR=%s\n"),
-               bnet_strerror(ds));
+               ds->bstrerror());
          ok = false;
          break;
       }
@@ -266,7 +266,7 @@ bool do_append_data(JCR *jcr)
    set_jcr_job_status(jcr, ok?JS_Terminated:JS_ErrorTerminated);
 
    /* Terminate connection with FD */
-   bnet_fsend(ds, OK_append);
+   ds->fsend(OK_append);
    do_fd_commands(jcr);               /* finish dialog with FD */
 
 
index 0ab2c033b834e090017f39086a218d936be6caa1..db28aed9ed79e8ac5eacfe25b4d90b3a4ea5b4a1 100644 (file)
@@ -1,13 +1,3 @@
-/*
- *
- *   block.c -- tape block handling functions
- *
- *              Kern Sibbald, March MMI
- *                 added BB02 format October MMII
- *
- *   Version $Id$
- *
- */
 /*
    Bacula® - The Network Backup Solution
 
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
+/*
+ *
+ *   block.c -- tape block handling functions
+ *
+ *              Kern Sibbald, March MMI
+ *                 added BB02 format October MMII
+ *
+ *   Version $Id$
+ *
+ */
 
 
 #include "bacula.h"
index 08dc97f67a4281b73ce888124d235b73742f2ec4..2e2f39088bf03d150995b1ba22e9156650b305dc 100644 (file)
  *     daemon. More complicated coding (double buffering, writer
  *     thread, ...) is left for a later version.
  *
- *     Unfortunately, I have had to add more and more complication
- *     to this code. This was not foreseen as noted above, and as
- *     a consequence has lead to something more contorted than is
- *     really necessary -- KES.  Note, this contortion has been
- *     corrected to a large extent by a rewrite (Apr MMI).
- *
  *   Version $Id$
  */
 
index bb8d33ed7d9fb419be3c2f3273ee9526e6b25e84..5cc3f7ba16e7a901843c6667c2f884fefce63ba2 100644 (file)
 #ifndef __DEV_H
 #define __DEV_H 1
 
-#ifdef SD_DEBUG_LOCK
-#define r_dlock() _r_dlock(__FILE__, __LINE__);      /* in device.c */
-#define r_dunlock() _r_dunlock(__FILE__, __LINE__);  /* in device.c */
-#define dlock() _dlock(__FILE__, __LINE__);          /* in device.c */
-#define dunlock() _dunlock(__FILE__, __LINE__);     /* in device.c */
-#endif
-
 #undef DCR                            /* used by Bacula */
 
-#define block_device(d, s) _block_device(__FILE__, __LINE__, (d), s)
-#define unblock_device(d) _unblock_device(__FILE__, __LINE__, (d))
-#define steal_device_lock(d, p, s) _steal_device_lock(__FILE__, __LINE__, (d), (p), s)
-#define give_back_device_lock(d, p) _give_back_device_lock(__FILE__, __LINE__, (d), (p))
-
 /* Return values from wait_for_sysop() */
 enum {
    W_ERROR = 1,
@@ -143,16 +131,6 @@ enum {
 #define ST_PART_SPOOLED    (1<<18)    /* spooling part */
 #define ST_FREESPACE_OK    (1<<19)    /* Have valid freespace for DVD */
 
-/* m_blocked states (mutually exclusive) */
-enum {
-   BST_NOT_BLOCKED = 0,               /* not blocked */
-   BST_UNMOUNTED,                     /* User unmounted device */
-   BST_WAITING_FOR_SYSOP,             /* Waiting for operator to mount tape */
-   BST_DOING_ACQUIRE,                 /* Opening/validating/moving tape */
-   BST_WRITING_LABEL,                 /* Labeling a tape */
-   BST_UNMOUNTED_WAITING_FOR_SYSOP,   /* User unmounted during wait for op */
-   BST_MOUNT                          /* Mount request */
-};
 
 /* Volume Catalog Information structure definition */
 struct VOLUME_CAT_INFO {
@@ -186,24 +164,11 @@ struct VOLUME_CAT_INFO {
 };
 
 
-typedef struct s_steal_lock {
-   pthread_t  no_wait_id;             /* id of no wait thread */
-   int        dev_blocked;            /* state */
-   int        dev_prev_blocked;       /* previous blocked state */
-} bsteal_lock_t;
-
 class DEVRES;                        /* Device resource defined in stored_conf.h */
 
 class DCR; /* forward reference */
 class VOLRES; /* forward reference */
 
-/*
- * Used in unblock() call
- */
-enum {
-   dev_locked = true,
-   dev_unlocked = false
-};
 
 /*
  * Device structure definition. There is one of these for
@@ -227,10 +192,6 @@ public:
    int num_waiting;                   /* number of threads waiting */
    int num_writers;                   /* number of writing threads */
    int reserved_device;               /* number of device reservations */
-
-   /* New access control in process of being implemented */
-// brwlock_t xlock;                   /* New mutual exclusion lock */
-
    int capabilities;                  /* capabilities mask */
    int state;                         /* state mask */
    int dev_errno;                     /* Our own errno */
@@ -380,21 +341,8 @@ public:
    char *bstrerror(void) { return errmsg; };
    char *print_errmsg() { return errmsg; };
 
-#ifdef  SD_DEBUG_LOCK
-   void _r_dlock(const char *, int);      /* in device.c */
-   void _r_dunlock(const char *, int);    /* in device.c */
-   void _dlock(const char *, int);        /* in device.c */
-   void _dunlock(const char *, int);      /* in device.c */
-#else
-   void r_dlock();                        /* in device.c */
-   void r_dunlock() { dunlock(); }
-   void dlock() { P(m_mutex); } 
-   void dunlock() { V(m_mutex); } 
-#endif
 
    void clear_volhdr();          /* 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 */
@@ -424,14 +372,31 @@ public:
    bool update_pos(DCR *dcr);    /* in dev.c */
    bool update_freespace();      /* in dvd.c */
 
-   void set_blocked(int block) { m_blocked = block; };
-   int  blocked() const { return m_blocked; };
    uint32_t get_file() const { return file; };
-   uint32_t get_block() const { return block_num; };
-   const char *print_blocked() const; /* in dev.c */
-   bool is_blocked() const { return m_blocked != BST_NOT_BLOCKED; };
+   uint32_t get_block_num() const { return block_num; };
    int fd() const { return m_fd; };
 
+   /* 
+    * Locking and blocking calls
+    */
+#ifdef  SD_DEBUG_LOCK
+   void _r_dlock(const char *, int);      /* in lock.c */
+   void _r_dunlock(const char *, int);    /* in lock.c */
+   void _dlock(const char *, int);        /* in lock.c */
+   void _dunlock(const char *, int);      /* in lock.c */
+#else
+   void r_dlock();                        /* in lock.c */
+   void r_dunlock() { dunlock(); }
+   void dlock() { P(m_mutex); } 
+   void dunlock() { V(m_mutex); } 
+#endif
+   void dblock(int why);                  /* in lock.c */
+   void dunblock(bool locked=false);      /* in lock.c */
+   void set_blocked(int block) { m_blocked = block; };
+   int blocked() const { return m_blocked; };
+   bool is_blocked() const { return m_blocked != BST_NOT_BLOCKED; };
+   const char *print_blocked() const;     /* in dev.c */
+
 private:
    bool do_mount(int mount, int timeout);      /* in dev.c */
    void set_mode(int omode);                   /* in dev.c */
index b52d77318a55e0a673ba0904a375fae3d40dcab5..19ca8badcdc1a868c3d4583c8f157f6b83ea83e4 100644 (file)
@@ -755,7 +755,7 @@ bool write_session_label(DCR *dcr, int label)
 
    free_record(rec);
    Dmsg2(150, "Leave write_session_label Block=%ud File=%ud\n",
-      dev->get_block(), dev->get_file());
+      dev->get_block_num(), dev->get_file());
    return true;
 }
 
index c57559dbf48ec357cd9f36d3ce9ff4f57bef46ae..9b2a4ca1f8a80b4e97a0afaa7e53083275f1d75a 100644 (file)
@@ -43,14 +43,107 @@ const int dbglvl = 500;
 #endif
 
 
-void DEVICE::block(int why)
+/*
+ *
+ * The Storage daemon has three locking concepts that must be
+ *   understood:
+ *
+ *  1. dblock    blocking the device, which means that the device
+ *               is "marked" in use.  When setting and removing the
+                 block, the device is locked, but after dblock is
+                 called the device is unlocked.
+ *  2. dlock()   simple mutex that locks the device structure. A dlock
+ *               can be acquired while a device is blocked if it is not
+ *               locked.      
+ *  3. r_dlock   "recursive" dlock, when means that a dlock (mutex)
+ *               will be acquired on the device if it is not blocked
+ *               by some other thread. If the device was blocked by
+ *               the current thread, it will acquire the lock.
+ *               If some other thread has set a block on the device,
+ *               this call will wait until the device is unblocked.
+ *
+ *  A lock is normally set when modifying the device structure.
+ *  A r_lock is normally acquired when you want to block the device
+ *    i.e. it will wait until the device is not blocked.
+ *  A block is normally set during long operations like writing to
+ *    the device.
+ *  If you are writing the device, you will normally block and 
+ *    lock it.
+ *  A lock cannot be violated. No other thread can touch the
+ *    device while a lock is set.  
+ *  When a block is set, every thread accept the thread that set
+ *    the block will block if r_dlock is called.
+ *  A device can be blocked for multiple reasons, labeling, writing,
+ *    acquiring (opening) the device, waiting for the operator, unmounted,
+ *    ...
+ *  Under certain conditions the block that is set on a device can be    
+ *    stolen and the device can be used by another thread. For example,
+ *    a device is blocked because it is waiting for the operator to  
+ *    mount a tape.  The operator can then unmount the device, and label
+ *    a tape, re-mount it, give back the block, and the job will continue.
+ *
+ *
+ * Functions:
+ *
+ *   DEVICE::dlock()   does P(m_mutex)     (in dev.h)
+ *   DEVICE::dunlock() does V(m_mutex)
+ *
+ *   DEVICE::dblock(why)  does 
+ *                    r_dlock();         (recursive device lock)
+ *                    block_device(this, why) 
+ *                    r_dunlock()
+ *
+ *   DEVICE::dunblock does
+ *                    dlock()
+ *                    unblock_device()
+ *                    dunlock()
+ *
+ *   DEVICE::r_dlock() does recursive locking
+ *                    dlock()
+ *                    if blocked and not same thread that locked
+ *                       pthread_cond_wait
+ *                    leaves device locked 
+ *
+ *   DEVICE::r_dunlock()
+ *                    same as dunlock();
+ *
+ *   block_device() does  (must be locked and not blocked at entry)  
+ *                    set blocked status
+ *                    set our pid
+ *
+ *   unblock_device() does (must be blocked at entry)
+ *                        (locked on entry)
+ *                        (locked on exit)
+ *                    set unblocked status
+ *                    clear pid
+ *                    if waiting threads
+ *                       pthread_cond_broadcast
+ *
+ *   steal_device_lock() does (must be locked and blocked at entry)
+ *                    save status
+ *                    set new blocked status
+ *                    set new pid
+ *                    unlock()
+ *
+ *   give_back_device_lock() does (must be blocked but not locked)
+ *                    dlock()
+ *                    reset blocked status
+ *                    save previous blocked
+ *                    reset pid
+ *                    if waiting threads
+ *                       pthread_cond_broadcast
+ *
+ */
+
+
+void DEVICE::dblock(int why)
 {
    r_dlock();              /* need recursive lock to block */
    block_device(this, why);
    r_dunlock();
 }
 
-void DEVICE::unblock(bool locked)
+void DEVICE::dunblock(bool locked)
 {
    if (!locked) {
       dlock();
@@ -103,17 +196,14 @@ void DEVICE::_r_dunlock(const char *file, int line)
  */
 #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());
+void DEVICE::r_dlock()
+{
 #endif
+   int stat;
    this->dlock();   
    if (this->blocked() && !pthread_equal(this->no_wait_id, pthread_self())) {
       this->num_waiting++;             /* indicate that I am waiting */
@@ -216,6 +306,8 @@ const char *DEVICE::print_blocked() const
       return "BST_UNMOUNTED_WAITING_FOR_SYSOP";
    case BST_MOUNT:
       return "BST_MOUNT";
+   case BST_DESPOOLING:
+      return "BST_DESPOOLING";
    default:
       return _("unknown blocked code");
    }
@@ -233,4 +325,3 @@ bool is_device_unmounted(DEVICE *dev)
           (blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
    return stat;
 }
-
diff --git a/bacula/src/stored/lock.h b/bacula/src/stored/lock.h
new file mode 100644 (file)
index 0000000..c49a242
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+   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.
+*/
+/*
+ * Definitions for locking and blocking functions in the SD
+ *
+ * Kern Sibbald, pulled out of dev.h June 2007
+ *
+ *   Version $Id$
+ *
+ */
+
+
+#ifndef __LOCK_H
+#define __LOCK_H 1
+
+#ifdef SD_DEBUG_LOCK
+#define r_dlock()   _r_dlock(__FILE__, __LINE__);    /* in lock.c */
+#define r_dunlock() _r_dunlock(__FILE__, __LINE__);  /* in lock.c */
+#define dlock()     _dlock(__FILE__, __LINE__);      /* in lock.c */
+#define dunlock()   _dunlock(__FILE__, __LINE__);    /* in lock.c */
+#endif
+
+#define block_device(d, s)          _block_device(__FILE__, __LINE__, (d), s)
+#define unblock_device(d)           _unblock_device(__FILE__, __LINE__, (d))
+#define steal_device_lock(d, p, s)  _steal_device_lock(__FILE__, __LINE__, (d), (p), s)
+#define give_back_device_lock(d, p) _give_back_device_lock(__FILE__, __LINE__, (d), (p))
+
+/* m_blocked states (mutually exclusive) */
+enum {
+   BST_NOT_BLOCKED = 0,               /* not blocked */
+   BST_UNMOUNTED,                     /* User unmounted device */
+   BST_WAITING_FOR_SYSOP,             /* Waiting for operator to mount tape */
+   BST_DOING_ACQUIRE,                 /* Opening/validating/moving tape */
+   BST_WRITING_LABEL,                 /* Labeling a tape */
+   BST_UNMOUNTED_WAITING_FOR_SYSOP,   /* User unmounted during wait for op */
+   BST_MOUNT,                         /* Mount request */
+   BST_DESPOOLING                     /* Despooling -- i.e. multiple writes */
+};
+
+typedef struct s_steal_lock {
+   pthread_t  no_wait_id;             /* id of no wait thread */
+   int        dev_blocked;            /* state */
+   int        dev_prev_blocked;       /* previous blocked state */
+} bsteal_lock_t;
+
+/*
+ * Used in unblock() call
+ */
+enum {
+   dev_locked = true,
+   dev_unlocked = false
+};
+
+#endif
index bbdf17b53625b22a077221e2d09a40b60561557e..783241d30ba6ab3e5286390b550bdb32f1cf8d8e 100644 (file)
@@ -230,7 +230,7 @@ bool    is_volume_in_use(DCR *dcr);
 void    send_drive_reserve_messages(JCR *jcr, void sendit(const char *msg, int len, void *sarg), void *arg);
 bool    find_suitable_device_for_job(JCR *jcr, RCTX &rctx);
 int     search_res_for_device(RCTX &rctx);
-void    release_msgs(JCR *jcr);
+void    release_reserve_messages(JCR *jcr);
 
 extern int reservations_lock_count;
 extern int vol_list_lock_count;
index 1485111ca8325ec263701786c64d8e1d32681c97..797a85c263ca3114b0f166e8c8325589a1d020dd 100644 (file)
@@ -54,6 +54,7 @@ static bool reserve_device_for_read(DCR *dcr);
 static bool reserve_device_for_append(DCR *dcr, RCTX &rctx);
 static bool use_storage_cmd(JCR *jcr);
 static void queue_reserve_message(JCR *jcr);
+static void pop_reserve_messages(JCR *jcr);
 
 /* Requests from the Director daemon */
 static char use_storage[]  = "use storage=%127s media_type=%127s "
@@ -573,8 +574,6 @@ static bool use_storage_cmd(JCR *jcr)
    int Copy, Stripe;
    DIRSTORE *store;
    RCTX rctx;
-   char *msg;
-   alist *msgs;
    alist *dirstore;
 
    memset(&rctx, 0, sizeof(RCTX));
@@ -584,7 +583,7 @@ static bool use_storage_cmd(JCR *jcr)
     *   use_device for each device that it wants to use.
     */
    dirstore = New(alist(10, not_owned_by_alist));
-   msgs = jcr->reserve_msgs = New(alist(10, not_owned_by_alist));  
+   jcr->reserve_msgs = New(alist(10, not_owned_by_alist));  
    do {
       Dmsg2(dbglvl, "jid=%u <dird: %s", jid(), dir->msg);
       ok = sscanf(dir->msg, use_storage, store_name.c_str(), 
@@ -664,9 +663,7 @@ static bool use_storage_cmd(JCR *jcr)
 
       lock_reservations();
       for ( ; !fail && !job_canceled(jcr); ) {
-         while ((msg = (char *)msgs->pop())) {
-            free(msg);
-         }
+         pop_reserve_messages(jcr);
          rctx.suitable_device = false;
          rctx.have_volume = false;
          rctx.VolumeName[0] = 0;
@@ -784,7 +781,7 @@ static bool use_storage_cmd(JCR *jcr)
       Dmsg2(dbglvl, "jid=%u >dird: %s", jid(), dir->msg);
    }
 
-   release_msgs(jcr);
+   release_reserve_messages(jcr);
    return ok;
 }
 
@@ -1522,7 +1519,10 @@ bail_out:
    jcr->unlock();
 }
 
-void release_msgs(JCR *jcr)
+/*
+ * Pop and release any reservations messages
+ */
+static void pop_reserve_messages(JCR *jcr)
 {
    alist *msgs;
    char *msg;
@@ -1535,7 +1535,21 @@ void release_msgs(JCR *jcr)
    while ((msg = (char *)msgs->pop())) {
       free(msg);
    }
-   delete msgs;
+bail_out:
+   jcr->unlock();
+}
+
+/*
+ * Also called from acquire.c 
+ */
+void release_reserve_messages(JCR *jcr)
+{
+   pop_reserve_messages(jcr);
+   jcr->lock();
+   if (!jcr->reserve_msgs) {
+      goto bail_out;
+   }
+   delete jcr->reserve_msgs;
    jcr->reserve_msgs = NULL;
 
 bail_out:
index 03e067d0feb8ef2ca534f883a362544c98d18d89..d29f34cd5e11226e76b3ce65395c188c92a58d76 100644 (file)
@@ -51,6 +51,7 @@ const int sd_dbglvl = 300;
 #   endif
 # endif
 #endif
+#include "lock.h"
 #include "block.h"
 #include "record.h"
 #include "dev.h"
index 4a72952153f3f4caca9ef58e8c08f2f9834c9dbd..077c2ead8ba33e43a172d524d53f360f90c4d764 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "2.1.23"
-#define BDATE   "26 June 2007"
-#define LSMDATE "26Jun07"
+#define BDATE   "28 June 2007"
+#define LSMDATE "28Jun07"
 
 #define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n"
 #define BYEAR "2007"       /* year for copyright messages in progs */