summaryrefslogtreecommitdiff
path: root/lib/tdb2/lock.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2011-09-14 08:12:13 +0930
committerRusty Russell <rusty@rustcorp.com.au>2011-09-14 08:12:13 +0930
commitd26908846a84bcff7860ebdb384bbff030206675 (patch)
tree6589b8a22fa0fab916600683a36fccb06e7c3282 /lib/tdb2/lock.c
parent85fe9cffe529fd6a8c76ca5f0e3c68c090ce25bf (diff)
downloadsamba-d26908846a84bcff7860ebdb384bbff030206675.tar.gz
samba-d26908846a84bcff7860ebdb384bbff030206675.tar.bz2
samba-d26908846a84bcff7860ebdb384bbff030206675.zip
tdb2: check lock owner in tdb1 backend.
This reports errors if we fork() while holding a lock, or misuse a tdb which we have dual-opened. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (Imported from CCAN commit bef6f1b02e95370ecb2cb44be87c82afc9cb74b2)
Diffstat (limited to 'lib/tdb2/lock.c')
-rw-r--r--lib/tdb2/lock.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/lib/tdb2/lock.c b/lib/tdb2/lock.c
index 7d4311c8e5..bf62d9719e 100644
--- a/lib/tdb2/lock.c
+++ b/lib/tdb2/lock.c
@@ -30,7 +30,7 @@
#include <ccan/build_assert/build_assert.h>
/* If we were threaded, we could wait for unlock, but we're not, so fail. */
-static enum TDB_ERROR owner_conflict(struct tdb_context *tdb, const char *call)
+enum TDB_ERROR owner_conflict(struct tdb_context *tdb, const char *call)
{
return tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_USE_ERROR,
"%s: lock owned by another tdb in this process.",
@@ -38,8 +38,7 @@ static enum TDB_ERROR owner_conflict(struct tdb_context *tdb, const char *call)
}
/* If we fork, we no longer really own locks. */
-static bool check_lock_pid(struct tdb_context *tdb,
- const char *call, bool log)
+bool check_lock_pid(struct tdb_context *tdb, const char *call, bool log)
{
/* No locks? No problem! */
if (tdb->file->allrecord_lock.count == 0
@@ -787,6 +786,11 @@ enum TDB_ERROR tdb_unlock_hashes(struct tdb_context *tdb,
return tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR,
"tdb_unlock_hashes RO allrecord!");
}
+ if (tdb->file->allrecord_lock.owner != tdb) {
+ return tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_USE_ERROR,
+ "tdb_unlock_hashes:"
+ " not locked by us!");
+ }
return TDB_SUCCESS;
}
@@ -817,6 +821,10 @@ enum TDB_ERROR tdb_lock_free_bucket(struct tdb_context *tdb, tdb_off_t b_off,
if (!check_lock_pid(tdb, "tdb_lock_free_bucket", true))
return TDB_ERR_LOCK;
+ if (tdb->file->allrecord_lock.owner != tdb) {
+ return owner_conflict(tdb, "tdb_lock_free_bucket");
+ }
+
if (tdb->file->allrecord_lock.ltype == F_WRLCK)
return 0;
return tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR,