]> git.sur5r.net Git - bacula/bacula/commitdiff
29Jun07
authorKern Sibbald <kern@sibbald.com>
Fri, 29 Jun 2007 12:12:26 +0000 (12:12 +0000)
committerKern Sibbald <kern@sibbald.com>
Fri, 29 Jun 2007 12:12:26 +0000 (12:12 +0000)
kes  Implement new BST_DESPOOLING blocked state. Change from locking
     during despooling in SD to blocking. This means that other threads
     can work with the device structure, in particular the reservations
     system while despooling.
28Jun07
kes  Fix return in reservation message queue that missed clearing
     the jcr lock (implemented 26Jun07 below).
kes  Rename a number of dev methods to make locking function names
     a bit clearer.
kes  Document locking in lock.c. Move lock structures to new file
     lock.h.

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

bacula/src/stored/acquire.c
bacula/src/stored/block.c
bacula/src/stored/dev.h
bacula/src/stored/device.c
bacula/src/stored/lock.h
bacula/src/stored/spool.c
bacula/src/version.h
bacula/technotes-2.1

index 57e359da84afed3278a9696e4be8f6a0aeae243c..6ff42474fb4fc107233ead7a7e4296a528ff83e8 100644 (file)
@@ -133,7 +133,7 @@ bool acquire_device_for_read(DCR *dcr)
       unlock_reservations();
       if (stat == 1) {
          DCR *ndcr = jcr->read_dcr;
-         dev->dunblock(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; 
@@ -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->dunblock(dev_locked);
+   dev->dunblock(DEV_LOCKED);
    Dmsg1(50, "jcr->dcr=%p\n", jcr->dcr);
    return ok;
 }
@@ -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->dunblock(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->dunblock(dev_locked);
+   dev->dunblock(DEV_LOCKED);
    return NULL;
 }
 
@@ -472,7 +472,7 @@ bool release_device(DCR *dcr)
    bool ok = true;
 
    /* lock only if not already locked by this thread */
-   if (!dcr->dev_locked) {
+   if (!dcr->is_dev_locked()) {
       dev->r_dlock();
    }
    Dmsg2(100, "release_device device %s is %s\n", dev->print_name(), dev->is_tape()?"tape":"disk");
index db28aed9ed79e8ac5eacfe25b4d90b3a4ea5b4a1..447d57b5da765401833384c4d0bb500363887cb7 100644 (file)
@@ -345,7 +345,8 @@ bool write_block_to_device(DCR *dcr)
       return stat;
    }
 
-   if (!dcr->dev_locked) {            /* device already locked? */
+   if (!dcr->is_dev_locked()) {        /* device already locked? */
+      /* note, do not change this to dcr->r_dlock */
       dev->r_dlock();                  /* no, lock it */
    }
 
@@ -387,7 +388,8 @@ bool write_block_to_device(DCR *dcr)
    }
 
 bail_out:
-   if (!dcr->dev_locked) {            /* did we lock dev above? */
+   if (!dcr->is_dev_locked()) {        /* did we lock dev above? */
+      /* note, do not change this to dcr->dunlock */
       dev->dunlock();                  /* unlock it now */
    }
    return stat;
index 5cc3f7ba16e7a901843c6667c2f884fefce63ba2..37dc0ddc4f930b3418ba724543873b44cae001ca 100644 (file)
@@ -430,7 +430,7 @@ public:
    bool spooling;                     /* set when actually spooling */
    bool despooling;                   /* set when despooling */
    bool despool_wait;                 /* waiting for despooling */
-   bool dev_locked;                   /* set if dev already locked */
+   bool m_dev_locked;                 /* set if dev already locked */
    bool NewVol;                       /* set if new Volume mounted */
    bool WroteVol;                     /* set if Volume written */
    bool NewFile;                      /* set when EOF written */
@@ -455,6 +455,13 @@ public:
    int Copy;                          /* identical copy number */
    int Stripe;                        /* RAIT stripe */
    VOLUME_CAT_INFO VolCatInfo;        /* Catalog info for desired volume */
+
+   /* Methods */
+   bool is_dev_locked() { return m_dev_locked; }
+   void dlock() { dev->dlock(); m_dev_locked = true; }
+   void dunlock() { dev->dunlock(); m_dev_locked = false;}
+   void dblock(int why) { dev->dblock(why); }
+
 };
 
 /*
index e864226b3656661270a414f6a2db74e33c3b0275..34fbc0cec7f03570b23573992eb098067286edc0 100644 (file)
@@ -92,13 +92,22 @@ bool fixup_device_block_write_error(DCR *dcr)
    char dt[MAX_TIME_LENGTH];
    JCR *jcr = dcr->jcr;
    DEVICE *dev = dcr->dev;
+   int blocked = dev->blocked();         /* save any previous blocked status */
+   bool ok = false;
 
    wait_time = time(NULL);
 
    Dmsg0(100, "Enter fixup_device_block_write_error\n");
 
+   /*
+    * If we are blocked at entry, unblock it, and set our own block status
+    */
+   if (blocked != BST_NOT_BLOCKED) {
+      unblock_device(dev);
+   }
    block_device(dev, BST_DOING_ACQUIRE);
-   /* Unlock, but leave BLOCKED */
+
+   /* Continue unlocked, but leave BLOCKED */
    dev->dunlock();
 
    bstrncpy(PrevVolName, dev->VolCatInfo.VolCatName, sizeof(PrevVolName));
@@ -117,8 +126,7 @@ bool fixup_device_block_write_error(DCR *dcr)
       free_block(label_blk);
       dcr->block = block;
       dev->dlock();  
-      unblock_device(dev);
-      return false;                /* device locked */
+      goto bail_out;
    }
    dev->dlock();                    /* lock again */
 
@@ -141,8 +149,7 @@ bool fixup_device_block_write_error(DCR *dcr)
         be.bstrerror(dev->dev_errno));
       free_block(label_blk);
       dcr->block = block;
-      unblock_device(dev);
-      return false;                /* device locked */
+      goto bail_out;
    }
    free_block(label_blk);
    dcr->block = block;
@@ -175,12 +182,21 @@ bool fixup_device_block_write_error(DCR *dcr)
       berrno be;
       Pmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"),
         be.bstrerror(dev->dev_errno));
-      unblock_device(dev);
-      return false;                /* device locked */
+      goto bail_out;
    }
+   ok = true;
 
+bail_out:
+   /*
+    * At this point, the device is locked and blocked.
+    * Unblock the device, restore any entry blocked condition, then
+    *   return leaving the device locked (as it was on entry).
+    */
    unblock_device(dev);
-   return true;                             /* device locked */
+   if (blocked != BST_NOT_BLOCKED) {
+      block_device(dev, blocked);
+   }
+   return ok;                               /* device locked */
 }
 
 /*
index c49a24292bca16b3c43b53fa8181c2bd3d724852..1880c72c58dcb855f1057c15a586e9e410e3fdf3 100644 (file)
@@ -72,8 +72,8 @@ typedef struct s_steal_lock {
  * Used in unblock() call
  */
 enum {
-   dev_locked = true,
-   dev_unlocked = false
+   DEV_LOCKED = true,
+   DEV_UNLOCKED = false
 };
 
 #endif
index 62426a0c34c13947a23327364ba5607e808869a4..e86672efb2ee66e27a4cb64807962cc713c6bcd7 100644 (file)
@@ -238,10 +238,14 @@ static bool despool_data(DCR *dcr, bool commit)
    }
    dcr->despool_wait = true;
    dcr->spooling = false;
-   dcr->dev->r_dlock();
+   /*
+    * We work with device blocked, but not locked so that
+    *  other threads -- e.g. reservations can lock the device
+    *  structure.
+    */
+   dcr->dblock(BST_DESPOOLING);
    dcr->despool_wait = false;
    dcr->despooling = true;
-   dcr->dev_locked = true;
 
    /*
     * This is really quite kludgy and should be fixed some time.
@@ -333,10 +337,16 @@ static bool despool_data(DCR *dcr, bool commit)
    free(rdev);
    dcr->spooling = true;           /* turn on spooling again */
    dcr->despooling = false;
+   /* 
+    * We are done, so unblock the device, but if we have done a 
+    *  commit, leave it locked so that the job cleanup does not
+    *  need to wait to release the device (no re-acquire of the lock).
+    */
+   dcr->dlock();
+   unblock_device(dcr->dev);
    /* If doing a commit, leave the device locked -- unlocked in release_device() */
    if (!commit) {
-      dcr->dev_locked = false;
-      dcr->dev->dunlock();
+      dcr->dunlock();
    }
    return ok;
 }
index 077c2ead8ba33e43a172d524d53f360f90c4d764..54839b0f678f15f5768585c93dfcf1e96cfcae6f 100644 (file)
@@ -4,8 +4,8 @@
 
 #undef  VERSION
 #define VERSION "2.1.23"
-#define BDATE   "28 June 2007"
-#define LSMDATE "28Jun07"
+#define BDATE   "29 June 2007"
+#define LSMDATE "29Jun07"
 
 #define PROG_COPYRIGHT "Copyright (C) %d-2007 Free Software Foundation Europe e.V.\n"
 #define BYEAR "2007"       /* year for copyright messages in progs */
index f58fd1356d3c52dc83f65d8e54094f267cde40d9..9b3026fe3d275f9d6f288fdf7e6ef6a6456ed92a 100644 (file)
@@ -1,7 +1,18 @@
               Technical notes on version 2.1
 
 General:
-
+29Jun07
+kes  Implement new BST_DESPOOLING blocked state. Change from locking
+     during despooling in SD to blocking. This means that other threads
+     can work with the device structure, in particular the reservations
+     system while despooling.
+28Jun07
+kes  Fix return in reservation message queue that missed clearing
+     the jcr lock (implemented 26Jun07 below).
+kes  Rename a number of dev methods to make locking function names
+     a bit clearer.
+kes  Document locking in lock.c. Move lock structures to new file
+     lock.h.
 26Jun07
 kes  Move reservations message lock to lock jcr only this
      fixes bug #861.