From: Kern Sibbald Date: Fri, 29 Jun 2007 12:12:26 +0000 (+0000) Subject: 29Jun07 X-Git-Tag: Release-7.0.0~6054 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=85b1d6be1b986dc81151814e2ded0c9e9d89b9d3;p=bacula%2Fbacula 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. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@5114 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index 57e359da84..6ff42474fb 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -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"); diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index db28aed9ed..447d57b5da 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -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; diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 5cc3f7ba16..37dc0ddc4f 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -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); } + }; /* diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index e864226b36..34fbc0cec7 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -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 */ } /* diff --git a/bacula/src/stored/lock.h b/bacula/src/stored/lock.h index c49a24292b..1880c72c58 100644 --- a/bacula/src/stored/lock.h +++ b/bacula/src/stored/lock.h @@ -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 diff --git a/bacula/src/stored/spool.c b/bacula/src/stored/spool.c index 62426a0c34..e86672efb2 100644 --- a/bacula/src/stored/spool.c +++ b/bacula/src/stored/spool.c @@ -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; } diff --git a/bacula/src/version.h b/bacula/src/version.h index 077c2ead8b..54839b0f67 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -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 */ diff --git a/bacula/technotes-2.1 b/bacula/technotes-2.1 index f58fd1356d..9b3026fe3d 100644 --- a/bacula/technotes-2.1 +++ b/bacula/technotes-2.1 @@ -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.