[SCM] CTDB repository - branch 2.5 updated - ctdb-2.5.3-118-g6459305

Amitay Isaacs amitay at samba.org
Wed Aug 6 01:59:07 MDT 2014


The branch, 2.5 has been updated
       via  645930530be50e180b757576ac1aeefdd80ea563 (commit)
       via  1bc5683258b21c0ef9cb1be15348788f986dc5b6 (commit)
       via  26cb2fc7ce61f8ac3a7177438f782479770c264e (commit)
       via  008df1bc8fcc9170f00f0baf6e336654b1192538 (commit)
       via  4fb620bbf493d91e296d99ff347efe8f30ddb8c5 (commit)
       via  32e02f86103ce09fc0462a7dee4f7a8e29d22b4f (commit)
       via  e05daef50fdec8844edc8dd1ccc525a133f7c358 (commit)
       via  cba4078ccc31cd5ace0b27f5e81c088117bc6d36 (commit)
       via  5bd20f2fdbcb5585c55399272f2860e8299ef21e (commit)
       via  84fbe6085dbfc1c911f0d10fbd27e9894f2b93dd (commit)
       via  939099011d26dff6170b6402dd15953e4ad1aa43 (commit)
       via  b430b02b6a1ff815e2379d53727fb02f86c85230 (commit)
       via  adafb6deee38ee3abe868bc5673748a01990fceb (commit)
       via  4d56b042d0edd74a75f45811593390e43d5cde1a (commit)
       via  b3510efddbac4c2e106cd4f81de6bccc7ae2c690 (commit)
       via  e27d02261445911b551371f77956696dccbf81a4 (commit)
      from  15f56f68d56b12c775ec8e9d111d003cea455d9b (commit)

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


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

    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
    
    (Imported from commit 88f6a6c188b8e43f710c50a9c1f88af660772e3d)

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

    locking: Update a comment
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Volker Lendecke <vl at samba.org>
    
    (Imported from commit f73adff737c8fd3ab797de35bf1463359ce801cd)

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

    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>
    
    (Imported from commit a890e760bbcb2d0f384aff285d1282de2a42d313)

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

    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>
    
    (Imported from commit aa1ff305f9bdd97675ceb4ce2b18f4cd623b8a38)

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

    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>
    
    (Imported from commit dce68a21416dd3dc016ed6a7c884b1314ffca121)

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

    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>
    
    (Imported from commit 7189437be447d33038eb26bca055b1025cebacd3)

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

    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>
    
    (Imported from commit 3aa96c3a3eb87fc6a1ad94c983e363b402b48ff5)

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

    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>
    
    (Imported from commit 3ff8ec02830b5fd2f88e33748a2bfd9f066a1285)

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

    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>
    
    (Imported from commit 59d45ea307fd460953a3b4924dfa60f5ab6dea4a)

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

    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>
    
    (Imported from commit e0d54594519de67b6f0d0ec003bc0327f70f026b)

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

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

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

    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>
    
    (Imported from commit c9664b4b17660c03ed96072a9f5392dbb0800f2c)

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

    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>
    
    (Imported from commit 19b3810b61e4856dc5ab6b8a5a785b836172f01e)

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

    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>
    
    (Imported from commit a89f3508796d6be8efe45ccc1f9ffee7e4d3f4f3)

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

    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>
    
    (Imported from commit b93d9c062229252a78a4497fba402ec968be9713)

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

    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>
    
    (Imported from commit 8aa6c039ae8f2bfd99515999e1ce647f0e4028d7)

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

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


Changeset truncated at 500 lines:

diff --git a/include/ctdb_private.h b/include/ctdb_private.h
index e94d2c8..416cf56 100644
--- a/include/ctdb_private.h
+++ b/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/server/ctdb_lock.c b/server/ctdb_lock.c
index 339a9d2..7d0be86 100644
--- a/server/ctdb_lock.c
+++ b/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/server/ctdb_tunables.c b/server/ctdb_tunables.c
index 4a252b6..0699586 100644
--- a/server/ctdb_tunables.c
+++ b/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 },
 };
 
 /*


-- 
CTDB repository


More information about the samba-cvs mailing list