]> git.sur5r.net Git - bacula/bacula/commitdiff
Fix lock race conditions in bug #1675
authorKern Sibbald <kern@sibbald.com>
Thu, 24 Feb 2011 11:56:22 +0000 (12:56 +0100)
committerKern Sibbald <kern@sibbald.com>
Sat, 20 Apr 2013 12:43:27 +0000 (14:43 +0200)
bacula/src/stored/autochanger.c
bacula/src/stored/stored_conf.c
bacula/src/stored/stored_conf.h
bacula/src/stored/vol_mgr.c

index b01f4cfd529f244acd035241261e9b740ce0d373..b32656e8e7a904e6b88d8c8497c03a02bde33eab 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2002-2010 Free Software Foundation Europe e.V.
+   Copyright (C) 2002-2011 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.
@@ -321,8 +321,13 @@ static void lock_changer(DCR *dcr)
 {
    AUTOCHANGER *changer_res = dcr->device->changer_res;
    if (changer_res) {
+      int errstat;
       Dmsg1(200, "Locking changer %s\n", changer_res->hdr.name);
-      P(changer_res->changer_mutex);  /* Lock changer script */
+      if ((errstat=rwl_writelock(&changer_res->changer_lock)) != 0) {
+         berrno be;
+         Jmsg(dcr->jcr, M_ERROR_TERM, 0, _("Lock failure on autochanger. ERR=%s\n"),
+              be.bstrerror(errstat));
+      }
    }
 }
 
@@ -330,8 +335,13 @@ static void unlock_changer(DCR *dcr)
 {
    AUTOCHANGER *changer_res = dcr->device->changer_res;
    if (changer_res) {
+      int errstat;
       Dmsg1(200, "Unlocking changer %s\n", changer_res->hdr.name);
-      V(changer_res->changer_mutex);  /* Unlock changer script */
+      if ((errstat=rwl_writeunlock(&changer_res->changer_lock)) != 0) {
+         berrno be;
+         Jmsg(dcr->jcr, M_ERROR_TERM, 0, _("Unlock failure on autochanger. ERR=%s\n"),
+              be.bstrerror(errstat));
+      }
    }
 }
 
@@ -364,6 +374,7 @@ bool unload_autochanger(DCR *dcr, int loaded)
       return true;
    }
 
+   lock_changer(dcr);
    if (loaded < 0) {
       loaded = get_autochanger_loaded_slot(dcr);
    }
@@ -371,7 +382,6 @@ bool unload_autochanger(DCR *dcr, int loaded)
    if (loaded > 0) {
       POOL_MEM results(PM_MESSAGE);
       POOLMEM *changer = get_pool_memory(PM_FNAME);
-      lock_changer(dcr);
       Jmsg(jcr, M_INFO, 0,
            _("3307 Issuing autochanger \"unload slot %d, drive %d\" command.\n"),
            loaded, dev->drive_index);
@@ -394,11 +404,11 @@ bool unload_autochanger(DCR *dcr, int loaded)
       } else {
          dev->set_slot(0);         /* nothing loaded */
       }
-      unlock_changer(dcr);
 
       free_volume(dev);            /* Free any volume associated with this drive */
       free_pool_memory(changer);
    }
+   unlock_changer(dcr);
    if (ok) {
       dev->clear_unload();
    }
index 11abee2a4625e38fcaef80aad3126b1072ce834c..a9fc44da5df02288e5bee45849b790a2694c0e6f 100644 (file)
@@ -457,6 +457,7 @@ void free_resource(RES *sres, int type)
       if (res->res_changer.device) {
          delete res->res_changer.device;
       }
+      rwl_destroy(&res->res_changer.changer_lock);
       break; 
    case R_STORAGE:
       if (res->res_store.sdaddrs) {
@@ -629,9 +630,9 @@ void save_resource(int type, RES_ITEM *items, int pass)
          foreach_alist(dev, res->res_changer.device) {
             dev->changer_res = (AUTOCHANGER *)&res->res_changer;
          }
-         if ((errstat = pthread_mutex_init(&res->res_changer.changer_mutex, NULL)) != 0) {
+         if ((errstat = rwl_init(&res->res_changer.changer_lock)) != 0) {
             berrno be;
-            Jmsg1(NULL, M_ERROR_TERM, 0, _("Unable to init mutex: ERR=%s\n"), 
+            Jmsg1(NULL, M_ERROR_TERM, 0, _("Unable to init lock: ERR=%s\n"), 
                   be.bstrerror(errstat));
          }
          break;
index 7597ff04f53bec8b405d514e1543483f2b2dab4c..13d8c74bf54a1821550430b67722bce5fa6071dc 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2011 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.
@@ -28,7 +28,6 @@
 /*
  * Resource codes -- they must be sequential for indexing
  *
- *   Version $Id$
  */
 
 enum {
@@ -110,7 +109,7 @@ public:
    alist *device;                     /* List of DEVRES device pointers */
    char *changer_name;                /* Changer device name */
    char *changer_command;             /* Changer command  -- external program */
-   pthread_mutex_t changer_mutex;     /* One changer operation at a time */
+   brwlock_t changer_lock;            /* One changer operation at a time */
 };
 
 /* Device specific definitions */
index 788d644d8eccc63c7280eae39e1be72c59e76497..e16e433471745be855e20854becdad54f35c3fac 100644 (file)
@@ -1,7 +1,7 @@
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2011 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.
@@ -32,8 +32,6 @@
  *
  *   Split from reserve.c October 2008
  *
- *   Version $Id: reserve.c 7380 2008-07-14 10:42:59Z kerns $
- *
  */
 
 #include "bacula.h"
@@ -611,12 +609,13 @@ bool free_volume(DEVICE *dev)
 {
    VOLRES *vol;
 
-   if (dev->vol == NULL) {
+   lock_volumes();
+   vol = dev->vol;
+   if (vol == NULL) {
       Dmsg1(dbglvl, "No vol on dev %s\n", dev->print_name());
+      unlock_volumes();
       return false;
    }
-   lock_volumes();
-   vol = dev->vol;
    /* Don't free a volume while it is being swapped */
    if (!vol->is_swapping()) {
       Dmsg1(dbglvl, "=== clear in_use vol=%s\n", vol->vol_name);