summaryrefslogtreecommitdiff
path: root/source3/lib/dbwrap/dbwrap_ctdb.c
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2012-03-27 14:31:04 +0200
committerVolker Lendecke <vl@samba.org>2012-04-17 10:21:00 +0200
commit94cf5cc284ba908675ed5fd573dd101d7b9bad02 (patch)
treefa3cbe066f5400c31cfa13ea149e13bada59fbdc /source3/lib/dbwrap/dbwrap_ctdb.c
parentbd9178506ed8796a0aa7e4e757f2adc20dcae4f8 (diff)
downloadsamba-94cf5cc284ba908675ed5fd573dd101d7b9bad02.tar.gz
samba-94cf5cc284ba908675ed5fd573dd101d7b9bad02.tar.bz2
samba-94cf5cc284ba908675ed5fd573dd101d7b9bad02.zip
s3: Add dbwrap_try_fetch_locked
This is designed to spread the load on individual ctdb records to allow upper layers to do backoff mechanisms. In the ctdb case, do not get the record if a local lock is already taken. If we are not dmaster, do at most one migrate attempt. For the tdb case, this is a nonblocking fetch_locked. If someone else has the lock, give up.
Diffstat (limited to 'source3/lib/dbwrap/dbwrap_ctdb.c')
-rw-r--r--source3/lib/dbwrap/dbwrap_ctdb.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c
index 47d5dc6929..fe2af3609c 100644
--- a/source3/lib/dbwrap/dbwrap_ctdb.c
+++ b/source3/lib/dbwrap/dbwrap_ctdb.c
@@ -1028,13 +1028,15 @@ static bool db_ctdb_own_record(TDB_DATA ctdb_data, bool read_only)
static struct db_record *fetch_locked_internal(struct db_ctdb_ctx *ctx,
TALLOC_CTX *mem_ctx,
- TDB_DATA key)
+ TDB_DATA key,
+ bool tryonly)
{
struct db_record *result;
struct db_ctdb_rec *crec;
NTSTATUS status;
TDB_DATA ctdb_data;
int migrate_attempts = 0;
+ int lockret;
if (!(result = talloc(mem_ctx, struct db_record))) {
DEBUG(0, ("talloc failed\n"));
@@ -1072,7 +1074,10 @@ again:
TALLOC_FREE(keystr);
}
- if (tdb_chainlock(ctx->wtdb->tdb, key) != 0) {
+ lockret = tryonly
+ ? tdb_chainlock_nonblock(ctx->wtdb->tdb, key)
+ : tdb_chainlock(ctx->wtdb->tdb, key);
+ if (lockret != 0) {
DEBUG(3, ("tdb_chainlock failed\n"));
TALLOC_FREE(result);
return NULL;
@@ -1098,6 +1103,12 @@ again:
tdb_chainunlock(ctx->wtdb->tdb, key);
talloc_set_destructor(result, NULL);
+ if (tryonly && (migrate_attempts != 0)) {
+ DEBUG(5, ("record migrated away again\n"));
+ TALLOC_FREE(result);
+ return NULL;
+ }
+
migrate_attempts += 1;
DEBUG(10, ("ctdb_data.dptr = %p, dmaster = %u (%u) %u\n",
@@ -1163,7 +1174,25 @@ static struct db_record *db_ctdb_fetch_locked(struct db_context *db,
return db_ctdb_fetch_locked_persistent(ctx, mem_ctx, key);
}
- return fetch_locked_internal(ctx, mem_ctx, key);
+ return fetch_locked_internal(ctx, mem_ctx, key, false);
+}
+
+static struct db_record *db_ctdb_try_fetch_locked(struct db_context *db,
+ TALLOC_CTX *mem_ctx,
+ TDB_DATA key)
+{
+ struct db_ctdb_ctx *ctx = talloc_get_type_abort(db->private_data,
+ struct db_ctdb_ctx);
+
+ if (ctx->transaction != NULL) {
+ return db_ctdb_fetch_locked_transaction(ctx, mem_ctx, key);
+ }
+
+ if (db->persistent) {
+ return db_ctdb_fetch_locked_persistent(ctx, mem_ctx, key);
+ }
+
+ return fetch_locked_internal(ctx, mem_ctx, key, true);
}
/*
@@ -1559,6 +1588,7 @@ struct db_context *db_open_ctdb(TALLOC_CTX *mem_ctx,
result->private_data = (void *)db_ctdb;
result->fetch_locked = db_ctdb_fetch_locked;
+ result->try_fetch_locked = db_ctdb_try_fetch_locked;
result->parse_record = db_ctdb_parse_record;
result->traverse = db_ctdb_traverse;
result->traverse_read = db_ctdb_traverse_read;