[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Mon Aug 4 12:24:04 MDT 2014


The branch, master has been updated
       via  88f6a6c ctdb-locking: Add per database queues for pending and active lock requests
       via  f73adff ctdb-locking: Update a comment
       via  a890e76 ctdb-locking: Simplify check for locks on record or database
       via  aa1ff30 ctdb-locking: Decrement pending statistics when lock is scheduled
       via  dce68a2 ctdb-locking: Update ctdb statistics for all lock types
       via  7189437 ctdb-locking: Add DB lock requests to head of the pending queue
       via  3aa96c3 ctdb-locking: Remove unused variable lock_num_pending
       via  3ff8ec0 ctdb-locking: Increase number of lock processes per database to 200
       via  59d45ea ctdb-locking: Add new tunable LockProcessesPerDB
       via  e0d5459 ctdb-locking: Allocate lock request soon after allocating lock context
       via  97a5c57 ctdb-locking: Remove unused function find_lock_context()
       via  c9664b4 ctdb-locking: Schedule the next possible lock based on per-db limit
       via  19b3810 ctdb-locking: Remove multiple lock requests per lock context (part 2)
       via  a89f350 ctdb-locking: Remove multiple lock requests per lock context (part 1)
       via  b93d9c0 ctdb-locking: Remove unused structure members
       via  8aa6c03 ctdb-locking: Fix the lock_type_str corresponding to LOCK_ALLDB
      from  eb2637c selftest: Improve check to detect if nmbd is working.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 88f6a6c188b8e43f710c50a9c1f88af660772e3d
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Thu Jul 24 15:56:41 2014 +1000

    ctdb-locking: Add per database queues for pending and active lock requests
    
    This avoids traversing a single pending queue which is quite expensive
    when there are lots of pending lock requests.  This seems to happen
    quite a lot on a loaded cluster for notify_index.tdb.
    
    Adding per database queues avoids the need to traverse pending queue
    for that database if there are already the maximum number of active
    lock requests.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    Autobuild-User(master): Volker Lendecke <vl at samba.org>
    Autobuild-Date(master): Mon Aug  4 20:23:45 CEST 2014 on sn-devel-104

commit f73adff737c8fd3ab797de35bf1463359ce801cd
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Wed Jul 23 12:52:03 2014 +1000

    ctdb-locking: Update a comment
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit a890e760bbcb2d0f384aff285d1282de2a42d313
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Jul 15 14:49:44 2014 +1000

    ctdb-locking: Simplify check for locks on record or database
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit aa1ff305f9bdd97675ceb4ce2b18f4cd623b8a38
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Jul 15 14:38:52 2014 +1000

    ctdb-locking: Decrement pending statistics when lock is scheduled
    
    and not when the lock is obtained.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit dce68a21416dd3dc016ed6a7c884b1314ffca121
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Jul 15 14:38:12 2014 +1000

    ctdb-locking: Update ctdb statistics for all lock types
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 7189437be447d33038eb26bca055b1025cebacd3
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Jul 15 14:13:25 2014 +1000

    ctdb-locking: Add DB lock requests to head of the pending queue
    
    This allows to schedule DB locks quickly without having to scan through
    the pending lock requests.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 3aa96c3a3eb87fc6a1ad94c983e363b402b48ff5
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Jul 15 12:59:57 2014 +1000

    ctdb-locking: Remove unused variable lock_num_pending
    
    The number of pending locks displayed in ctdb statistics are stored in
    ctdb_statistics structure and not ctdb_context.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 3ff8ec02830b5fd2f88e33748a2bfd9f066a1285
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Jul 15 16:41:31 2014 +1000

    ctdb-locking: Increase number of lock processes per database to 200
    
    This was the original limit in the older versions of CTDB.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 59d45ea307fd460953a3b4924dfa60f5ab6dea4a
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Jul 15 12:13:53 2014 +1000

    ctdb-locking: Add new tunable LockProcessesPerDB
    
    This allows to change the maximum number of lock processes that can
    be active.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit e0d54594519de67b6f0d0ec003bc0327f70f026b
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri May 30 15:49:46 2014 +1000

    ctdb-locking: Allocate lock request soon after allocating lock context
    
    This avoids extra work in case lock request allocation fails.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 97a5c579574fb5702a743e07b896c9a0ec0acc4f
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Jul 15 14:44:55 2014 +1000

    ctdb-locking: Remove unused function find_lock_context()
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit c9664b4b17660c03ed96072a9f5392dbb0800f2c
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Thu May 29 17:27:32 2014 +1000

    ctdb-locking: Schedule the next possible lock based on per-db limit
    
    This prevents searching through active lock requests for every pending
    lock request to check if the pending lock request can be scheduled or not.
    The locks are scheduled in strict first-in-first-out order.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 19b3810b61e4856dc5ab6b8a5a785b836172f01e
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri May 30 15:36:03 2014 +1000

    ctdb-locking: Remove multiple lock requests per lock context (part 2)
    
    Store only a single request instead of storing a queue in lock context.
    Lock request structure does not need to be a linked list any more.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit a89f3508796d6be8efe45ccc1f9ffee7e4d3f4f3
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri May 30 15:36:28 2014 +1000

    ctdb-locking: Remove multiple lock requests per lock context (part 1)
    
    This was a bad idea and caused out of order scheduling of lock requests.
    
    The logic to append lock requests to existing lock context is already
    commented.  Remove the commented code and there is no need to check if
    lock_ctx is NULL, since we are always creating a new one.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit b93d9c062229252a78a4497fba402ec968be9713
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri May 30 13:57:44 2014 +1000

    ctdb-locking: Remove unused structure members
    
    block_child was used to keep track of a process which was created to debug
    why a lock process has blocked.  That logic was replaced to execute an
    external debug script.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

commit 8aa6c039ae8f2bfd99515999e1ce647f0e4028d7
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri May 30 13:48:45 2014 +1000

    ctdb-locking: Fix the lock_type_str corresponding to LOCK_ALLDB
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 ctdb/include/ctdb_private.h |    4 +-
 ctdb/server/ctdb_lock.c     |  276 +++++++++++++++++++------------------------
 ctdb/server/ctdb_tunables.c |    1 +
 3 files changed, 123 insertions(+), 158 deletions(-)


Changeset truncated at 500 lines:

diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h
index e94d2c8..416cf56 100644
--- a/ctdb/include/ctdb_private.h
+++ b/ctdb/include/ctdb_private.h
@@ -127,6 +127,7 @@ struct ctdb_tunable {
 	uint32_t no_ip_host_on_all_disabled;
 	uint32_t samba3_hack;
 	uint32_t mutex_enabled;
+	uint32_t lock_processes_per_db;
 };
 
 /*
@@ -557,7 +558,6 @@ struct ctdb_context {
 	struct trbt_tree *child_processes; 
 
 	/* Used for locking record/db/alldb */
-	int lock_num_pending;
 	struct lock_context *lock_current;
 	struct lock_context *lock_pending;
 };
@@ -597,6 +597,8 @@ struct ctdb_db_context {
 
 	struct ctdb_db_statistics statistics;
 
+	struct lock_context *lock_current;
+	struct lock_context *lock_pending;
 	int lock_num_current;
 };
 
diff --git a/ctdb/server/ctdb_lock.c b/ctdb/server/ctdb_lock.c
index 90f74e4..a403e25 100644
--- a/ctdb/server/ctdb_lock.c
+++ b/ctdb/server/ctdb_lock.c
@@ -33,7 +33,7 @@
  * 2. Once the locks are obtained, signal parent process via fd.
  * 3. Invoke registered callback routine with locking status.
  * 4. If the child process cannot get locks within certain time,
- *    diagnose using /proc/locks and log warning message
+ *    execute an external script to debug.
  *
  * ctdb_lock_record()      - get a lock on a record
  * ctdb_lock_db()          - get a lock on a DB
@@ -43,9 +43,6 @@
  *  auto_mark              - whether to mark/unmark DBs in before/after callback
  */
 
-/* FIXME: Add a tunable max_lock_processes_per_db */
-#define MAX_LOCK_PROCESSES_PER_DB		(100)
-
 enum lock_type {
 	LOCK_RECORD,
 	LOCK_DB,
@@ -57,7 +54,7 @@ static const char * const lock_type_str[] = {
 	"lock_record",
 	"lock_db",
 	"lock_alldb_prio",
-	"lock_db",
+	"lock_alldb",
 };
 
 struct lock_request;
@@ -71,20 +68,18 @@ struct lock_context {
 	TDB_DATA key;
 	uint32_t priority;
 	bool auto_mark;
-	struct lock_request *req_queue;
+	struct lock_request *request;
 	pid_t child;
 	int fd[2];
 	struct tevent_fd *tfd;
 	struct tevent_timer *ttimer;
-	pid_t block_child;
-	int block_fd[2];
 	struct timeval start_time;
 	uint32_t key_hash;
+	bool can_schedule;
 };
 
 /* lock_request is the client specific part for a lock request */
 struct lock_request {
-	struct lock_request *next, *prev;
 	struct lock_context *lctx;
 	void (*callback)(void *, bool);
 	void *private_data;
@@ -279,19 +274,26 @@ static int ctdb_lock_context_destructor(struct lock_context *lock_ctx)
 {
 	if (lock_ctx->child > 0) {
 		ctdb_kill(lock_ctx->ctdb, lock_ctx->child, SIGKILL);
-		DLIST_REMOVE(lock_ctx->ctdb->lock_current, lock_ctx);
+		if (lock_ctx->type == LOCK_RECORD) {
+			DLIST_REMOVE(lock_ctx->ctdb_db->lock_current, lock_ctx);
+		} else {
+			DLIST_REMOVE(lock_ctx->ctdb->lock_current, lock_ctx);
+		}
 		if (lock_ctx->ctdb_db) {
 			lock_ctx->ctdb_db->lock_num_current--;
 		}
 		CTDB_DECREMENT_STAT(lock_ctx->ctdb, locks.num_current);
-		if (lock_ctx->type == LOCK_RECORD || lock_ctx->type == LOCK_DB) {
+		if (lock_ctx->ctdb_db) {
 			CTDB_DECREMENT_DB_STAT(lock_ctx->ctdb_db, locks.num_current);
 		}
 	} else {
-		DLIST_REMOVE(lock_ctx->ctdb->lock_pending, lock_ctx);
-		lock_ctx->ctdb->lock_num_pending--;
+		if (lock_ctx->type == LOCK_RECORD) {
+			DLIST_REMOVE(lock_ctx->ctdb_db->lock_pending, lock_ctx);
+		} else {
+			DLIST_REMOVE(lock_ctx->ctdb->lock_pending, lock_ctx);
+		}
 		CTDB_DECREMENT_STAT(lock_ctx->ctdb, locks.num_pending);
-		if (lock_ctx->type == LOCK_RECORD || lock_ctx->type == LOCK_DB) {
+		if (lock_ctx->ctdb_db) {
 			CTDB_DECREMENT_DB_STAT(lock_ctx->ctdb_db, locks.num_pending);
 		}
 	}
@@ -307,11 +309,10 @@ static int ctdb_lock_context_destructor(struct lock_context *lock_ctx)
  */
 static int ctdb_lock_request_destructor(struct lock_request *lock_request)
 {
-	DLIST_REMOVE(lock_request->lctx->req_queue, lock_request);
+	lock_request->lctx->request = NULL;
 	return 0;
 }
 
-
 void ctdb_lock_free_request_context(struct lock_request *lock_req)
 {
 	struct lock_context *lock_ctx;
@@ -329,7 +330,7 @@ void ctdb_lock_free_request_context(struct lock_request *lock_req)
  */
 static void process_callbacks(struct lock_context *lock_ctx, bool locked)
 {
-	struct lock_request *request, *next;
+	struct lock_request *request;
 
 	if (lock_ctx->auto_mark && locked) {
 		switch (lock_ctx->type) {
@@ -351,19 +352,12 @@ static void process_callbacks(struct lock_context *lock_ctx, bool locked)
 		}
 	}
 
-	/* Iterate through all callbacks */
-	request = lock_ctx->req_queue;
-	while (request) {
-		if (lock_ctx->auto_mark) {
-			/* Reset the destructor, so request is not removed from the list */
-			talloc_set_destructor(request, NULL);
-		}
-
-		/* In case, callback frees the request, store next */
-		next = request->next;
-		request->callback(request->private_data, locked);
-		request = next;
+	request = lock_ctx->request;
+	if (lock_ctx->auto_mark) {
+		/* Reset the destructor, so request is not removed from the list */
+		talloc_set_destructor(request, NULL);
 	}
+	request->callback(request->private_data, locked);
 
 	if (lock_ctx->auto_mark && locked) {
 		switch (lock_ctx->type) {
@@ -458,10 +452,8 @@ static void ctdb_lock_handler(struct tevent_context *ev,
 	}
 
 	/* Update statistics */
-	CTDB_DECREMENT_STAT(lock_ctx->ctdb, locks.num_pending);
 	CTDB_INCREMENT_STAT(lock_ctx->ctdb, locks.num_calls);
 	if (lock_ctx->ctdb_db) {
-		CTDB_DECREMENT_DB_STAT(lock_ctx->ctdb_db, locks.num_pending);
 		CTDB_INCREMENT_DB_STAT(lock_ctx->ctdb_db, locks.num_calls);
 	}
 
@@ -507,7 +499,7 @@ static void ctdb_lock_timeout_handler(struct tevent_context *ev,
 	lock_ctx = talloc_get_type_abort(private_data, struct lock_context);
 	ctdb = lock_ctx->ctdb;
 
-	if (lock_ctx->type == LOCK_RECORD || lock_ctx->type == LOCK_DB) {
+	if (lock_ctx->ctdb_db) {
 		DEBUG(DEBUG_WARNING,
 		      ("Unable to get %s lock on database %s for %.0lf seconds\n",
 		       (lock_ctx->type == LOCK_RECORD ? "RECORD" : "DB"),
@@ -665,67 +657,73 @@ static char **lock_helper_args(TALLOC_CTX *mem_ctx, struct lock_context *lock_ct
 	return args;
 }
 
-
 /*
- * Find the lock context of a given type
+ * Find a lock request that can be scheduled
  */
-static struct lock_context *find_lock_context(struct lock_context *lock_list,
-					      struct ctdb_db_context *ctdb_db,
-					      TDB_DATA key,
-					      uint32_t priority,
-					      enum lock_type type,
-					      uint32_t key_hash)
+struct lock_context *ctdb_find_lock_context(struct ctdb_context *ctdb)
 {
-	struct lock_context *lock_ctx;
-
-	/* Search active locks */
-	for (lock_ctx=lock_list; lock_ctx; lock_ctx=lock_ctx->next) {
-		if (lock_ctx->type != type) {
-			continue;
-		}
+	struct lock_context *lock_ctx, *next_ctx;
+	struct ctdb_db_context *ctdb_db;
 
-		switch (lock_ctx->type) {
-		case LOCK_RECORD:
-			if (ctdb_db == lock_ctx->ctdb_db &&
-			    key_hash == lock_ctx->key_hash) {
-				goto done;
+	/* First check if there are database lock requests */
+	lock_ctx = ctdb->lock_pending;
+	while (lock_ctx != NULL) {
+		next_ctx = lock_ctx->next;
+		if (! lock_ctx->request) {
+			DEBUG(DEBUG_INFO, ("Removing lock context without lock request\n"));
+			DLIST_REMOVE(ctdb->lock_pending, lock_ctx);
+			CTDB_DECREMENT_STAT(ctdb, locks.num_pending);
+			if (lock_ctx->ctdb_db) {
+				CTDB_DECREMENT_DB_STAT(lock_ctx->ctdb_db, locks.num_pending);
 			}
+			talloc_free(lock_ctx);
+		} else {
+			/* Found a lock context with lock requests */
 			break;
+		}
+		lock_ctx = next_ctx;
+	}
 
-		case LOCK_DB:
-			if (ctdb_db == lock_ctx->ctdb_db) {
-				goto done;
-			}
-			break;
+	if (lock_ctx) {
+		return lock_ctx;
+	}
 
-		case LOCK_ALLDB_PRIO:
-			if (priority == lock_ctx->priority) {
-				goto done;
+	/* Next check database queues */
+	for (ctdb_db = ctdb->db_list; ctdb_db; ctdb_db = ctdb_db->next) {
+		if (ctdb_db->lock_num_current == ctdb->tunable.lock_processes_per_db) {
+			continue;
+		}
+		lock_ctx = ctdb_db->lock_pending;
+		while (lock_ctx != NULL) {
+			next_ctx = lock_ctx->next;
+			if (! lock_ctx->request) {
+				DEBUG(DEBUG_INFO, ("Removing lock context without lock request\n"));
+				DLIST_REMOVE(ctdb_db->lock_pending, lock_ctx);
+				CTDB_DECREMENT_STAT(ctdb, locks.num_pending);
+				CTDB_DECREMENT_DB_STAT(ctdb_db, locks.num_pending);
+				talloc_free(lock_ctx);
+			} else {
+				break;
 			}
-			break;
 
-		case LOCK_ALLDB:
-			goto done;
-			break;
+			lock_ctx = next_ctx;
 		}
-	}
 
-	/* Did not find the lock context we are searching for */
-	lock_ctx = NULL;
-
-done:
-	return lock_ctx;
+		if (lock_ctx) {
+			return lock_ctx;
+		}
+	}
 
+	return NULL;
 }
 
-
 /*
  * Schedule a new lock child process
  * Set up callback handler and timeout handler
  */
 static void ctdb_lock_schedule(struct ctdb_context *ctdb)
 {
-	struct lock_context *lock_ctx, *next_ctx, *active_ctx;
+	struct lock_context *lock_ctx;
 	int ret;
 	TALLOC_CTX *tmp_ctx;
 	const char *helper = BINDIR "/ctdb_lock_helper";
@@ -744,43 +742,8 @@ static void ctdb_lock_schedule(struct ctdb_context *ctdb)
 		CTDB_NO_MEMORY_VOID(ctdb, prog);
 	}
 
-	if (ctdb->lock_pending == NULL) {
-		return;
-	}
-
 	/* Find a lock context with requests */
-	lock_ctx = ctdb->lock_pending;
-	while (lock_ctx != NULL) {
-		next_ctx = lock_ctx->next;
-		if (! lock_ctx->req_queue) {
-			DEBUG(DEBUG_INFO, ("Removing lock context without lock requests\n"));
-			DLIST_REMOVE(ctdb->lock_pending, lock_ctx);
-			ctdb->lock_num_pending--;
-			CTDB_DECREMENT_STAT(ctdb, locks.num_pending);
-			if (lock_ctx->ctdb_db) {
-				CTDB_DECREMENT_DB_STAT(lock_ctx->ctdb_db, locks.num_pending);
-			}
-			talloc_free(lock_ctx);
-		} else {
-			active_ctx = find_lock_context(ctdb->lock_current, lock_ctx->ctdb_db,
-						       lock_ctx->key, lock_ctx->priority,
-						       lock_ctx->type, lock_ctx->key_hash);
-			if (active_ctx == NULL) {
-				if (lock_ctx->ctdb_db == NULL ||
-				    lock_ctx->ctdb_db->lock_num_current < MAX_LOCK_PROCESSES_PER_DB) {
-					/* Found a lock context with lock requests */
-					break;
-				}
-			}
-
-			/* There is already a child waiting for the
-			 * same key.  So don't schedule another child
-			 * just yet.
-			 */
-		}
-		lock_ctx = next_ctx;
-	}
-
+	lock_ctx = ctdb_find_lock_context(ctdb);
 	if (lock_ctx == NULL) {
 		return;
 	}
@@ -874,12 +837,18 @@ static void ctdb_lock_schedule(struct ctdb_context *ctdb)
 	tevent_fd_set_auto_close(lock_ctx->tfd);
 
 	/* Move the context from pending to current */
-	DLIST_REMOVE(ctdb->lock_pending, lock_ctx);
-	ctdb->lock_num_pending--;
-	DLIST_ADD_END(ctdb->lock_current, lock_ctx, NULL);
+	if (lock_ctx->type == LOCK_RECORD) {
+		DLIST_REMOVE(lock_ctx->ctdb_db->lock_pending, lock_ctx);
+		DLIST_ADD_END(lock_ctx->ctdb_db->lock_current, lock_ctx, NULL);
+	} else {
+		DLIST_REMOVE(ctdb->lock_pending, lock_ctx);
+		DLIST_ADD_END(ctdb->lock_current, lock_ctx, NULL);
+	}
+	CTDB_DECREMENT_STAT(lock_ctx->ctdb, locks.num_pending);
+	CTDB_INCREMENT_STAT(lock_ctx->ctdb, locks.num_current);
 	if (lock_ctx->ctdb_db) {
 		lock_ctx->ctdb_db->lock_num_current++;
-		CTDB_INCREMENT_STAT(lock_ctx->ctdb, locks.num_current);
+		CTDB_DECREMENT_DB_STAT(lock_ctx->ctdb_db, locks.num_pending);
 		CTDB_INCREMENT_DB_STAT(lock_ctx->ctdb_db, locks.num_current);
 	}
 }
@@ -905,66 +874,59 @@ static struct lock_request *ctdb_lock_internal(struct ctdb_context *ctdb,
 		return NULL;
 	}
 
-#if 0
-	/* Disable this optimization to ensure first-in-first-out fair
-	 * scheduling of lock requests */
+	lock_ctx = talloc_zero(ctdb, struct lock_context);
+	if (lock_ctx == NULL) {
+		DEBUG(DEBUG_ERR, ("Failed to create a new lock context\n"));
+		return NULL;
+	}
 
-	/* get a context for this key - search only the pending contexts,
-	 * current contexts might in the middle of processing callbacks */
-	lock_ctx = find_lock_context(ctdb->lock_pending, ctdb_db, key, priority, type);
-#endif
+	if ((request = talloc_zero(lock_ctx, struct lock_request)) == NULL) {
+		talloc_free(lock_ctx);
+		return NULL;
+	}
 
-	/* No existing context, create one */
-	if (lock_ctx == NULL) {
-		lock_ctx = talloc_zero(ctdb, struct lock_context);
-		if (lock_ctx == NULL) {
-			DEBUG(DEBUG_ERR, ("Failed to create a new lock context\n"));
+	lock_ctx->type = type;
+	lock_ctx->ctdb = ctdb;
+	lock_ctx->ctdb_db = ctdb_db;
+	lock_ctx->key.dsize = key.dsize;
+	if (key.dsize > 0) {
+		lock_ctx->key.dptr = talloc_memdup(lock_ctx, key.dptr, key.dsize);
+		if (lock_ctx->key.dptr == NULL) {
+			DEBUG(DEBUG_ERR, (__location__ "Memory allocation error\n"));
+			talloc_free(lock_ctx);
 			return NULL;
 		}
+		lock_ctx->key_hash = ctdb_hash(&key);
+	} else {
+		lock_ctx->key.dptr = NULL;
+	}
+	lock_ctx->priority = priority;
+	lock_ctx->auto_mark = auto_mark;
 
-		lock_ctx->type = type;
-		lock_ctx->ctdb = ctdb;
-		lock_ctx->ctdb_db = ctdb_db;
-		lock_ctx->key.dsize = key.dsize;
-		if (key.dsize > 0) {
-			lock_ctx->key.dptr = talloc_memdup(lock_ctx, key.dptr, key.dsize);
-			if (lock_ctx->key.dptr == NULL) {
-				DEBUG(DEBUG_ERR, (__location__ "Memory allocation error\n"));
-				talloc_free(lock_ctx);
-				return NULL;
-			}
-			lock_ctx->key_hash = ctdb_hash(&key);
-		} else {
-			lock_ctx->key.dptr = NULL;
-		}
-		lock_ctx->priority = priority;
-		lock_ctx->auto_mark = auto_mark;
-
-		lock_ctx->child = -1;
-		lock_ctx->block_child = -1;
+	lock_ctx->request = request;
+	lock_ctx->child = -1;
 
+	/* Non-record locks are required by recovery and should be scheduled
+	 * immediately, so keep them at the head of the pending queue.
+	 */
+	if (lock_ctx->type == LOCK_RECORD) {
+		DLIST_ADD_END(ctdb_db->lock_pending, lock_ctx, NULL);
+	} else {
 		DLIST_ADD_END(ctdb->lock_pending, lock_ctx, NULL);
-		ctdb->lock_num_pending++;
-		CTDB_INCREMENT_STAT(ctdb, locks.num_pending);
-		if (ctdb_db) {
-			CTDB_INCREMENT_DB_STAT(ctdb_db, locks.num_pending);
-		}
-
-		/* Start the timer when we activate the context */
-		lock_ctx->start_time = timeval_current();
 	}
-
-	if ((request = talloc_zero(lock_ctx, struct lock_request)) == NULL) {
-		talloc_free(lock_ctx);
-		return NULL;
+	CTDB_INCREMENT_STAT(ctdb, locks.num_pending);
+	if (ctdb_db) {
+		CTDB_INCREMENT_DB_STAT(ctdb_db, locks.num_pending);
 	}
 
+	/* Start the timer when we activate the context */
+	lock_ctx->start_time = timeval_current();
+
 	request->lctx = lock_ctx;
 	request->callback = callback;
 	request->private_data = private_data;
 
 	talloc_set_destructor(request, ctdb_lock_request_destructor);
-	DLIST_ADD_END(lock_ctx->req_queue, request, NULL);
 
 	ctdb_lock_schedule(ctdb);
 
diff --git a/ctdb/server/ctdb_tunables.c b/ctdb/server/ctdb_tunables.c
index 4a252b6..0699586 100644
--- a/ctdb/server/ctdb_tunables.c
+++ b/ctdb/server/ctdb_tunables.c
@@ -83,6 +83,7 @@ static const struct {
 	{ "NoIPHostOnAllDisabled",    0,  offsetof(struct ctdb_tunable, no_ip_host_on_all_disabled), false },
 	{ "Samba3AvoidDeadlocks", 0, offsetof(struct ctdb_tunable, samba3_hack), false },
 	{ "TDBMutexEnabled", 0, offsetof(struct ctdb_tunable, mutex_enabled), false },
+	{ "LockProcessesPerDB", 200, offsetof(struct ctdb_tunable, lock_processes_per_db), false },
 };
 
 /*


-- 
Samba Shared Repository


More information about the samba-cvs mailing list