[SCM] CTDB repository - branch master updated - ctdb-2.3-31-g824dcec

Amitay Isaacs amitay at samba.org
Wed Jul 31 20:33:59 MDT 2013


The branch, master has been updated
       via  824dcec35ec461d78e22b2ea109473b32bfe3972 (commit)
       via  f6b066a23610fb0092298861c21a9b354b91e2f1 (commit)
       via  10a057d8e15c8c18e540598a940d3548c731b0b4 (commit)
       via  7e7e59c4047c78159387089eca65d90037bcf722 (commit)
       via  32c83e209823e9a4d6306bb7fd63d4500f3e2668 (commit)
       via  fcf77dec5af973a0e32f3999bc012053a6f47a96 (commit)
       via  049d9beb3783482490e6273a434ccbad23f85f0a (commit)
       via  ab35773518ad15588013f4d859f7bee790437450 (commit)
       via  fde4b4db5a57f75c5efa5647c309f33e0d5a68f3 (commit)
       via  e73b2e12adc9db1dedb48d32bba3a8406a80f4cd (commit)
       via  023ca2e84f5ed064a288526b9c2bc7e06674dd81 (commit)
      from  57aa2dffea60abd73a95233f8b761cc676adebb6 (commit)

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


- Log -----------------------------------------------------------------
commit 824dcec35ec461d78e22b2ea109473b32bfe3972
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Jul 30 14:17:55 2013 +1000

    ctdbd: Print set db sticky message after it's set
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit f6b066a23610fb0092298861c21a9b354b91e2f1
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Dec 4 18:27:10 2012 +1100

    tests: Add a test program to hold a lock on a database
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit 10a057d8e15c8c18e540598a940d3548c731b0b4
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Jul 30 12:45:01 2013 +1000

    recoverd: Use correct tdb flags when creating missing databases
    
    When creating missing databases either locally or remotely, make sure
    to use the correct tdb flags from other nodes.  Without this, volatile
    databases can get attached without TDB_INCOMPATIBLE_HASH flag.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit 7e7e59c4047c78159387089eca65d90037bcf722
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Thu Aug 1 11:07:59 2013 +1000

    client: Always use jenkins hash when attaching volatile databases
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit 32c83e209823e9a4d6306bb7fd63d4500f3e2668
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Jul 29 13:50:44 2013 +1000

    recoverd: Make sure to use jenkins hash for recovery databases
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit fcf77dec5af973a0e32f3999bc012053a6f47a96
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Jul 22 17:26:28 2013 +1000

    recoverd: Assemble up-to-date node flags information from remote nodes
    
    Currently nodemap used by recovery master is the one obtained from the local
    node.  This information may have been updated while processing main loop.
    Before comparing node flags on all the nodes, create up-to-date node flags
    information based on the information received from all the nodes.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit 049d9beb3783482490e6273a434ccbad23f85f0a
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Jul 15 16:35:30 2013 +1000

    tools/ctdb: Only print the hot records with non-zero hopcount
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit ab35773518ad15588013f4d859f7bee790437450
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Jul 15 16:32:40 2013 +1000

    ctdbd: Don't consider a hot record if the hopcount is zero
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit fde4b4db5a57f75c5efa5647c309f33e0d5a68f3
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri Jul 12 17:33:13 2013 +1000

    ctdbd: Fix updating of hot keys in database statistics
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit e73b2e12adc9db1dedb48d32bba3a8406a80f4cd
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Jul 15 15:24:11 2013 +1000

    ctdbd: Remove incomplete ctdb_db_statistics_wire structure
    
    Instead of maintaining another structure, add an element as place holder for
    marshall buffer of hot keys.  This avoids duplication of the structure.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

commit 023ca2e84f5ed064a288526b9c2bc7e06674dd81
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Mon Jul 15 14:52:07 2013 +1000

    Revert "ctdbd: Remove incomplete ctdb_db_statistics_wire structure"
    
    The structure cannot be removed without adding support for marshalling keys
    for hot records.
    
    This reverts commit 26a4653df594d351ca0dc1bd5f5b2f5b0eb0a9a5.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>

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

Summary of changes:
 Makefile.in               |    6 ++++-
 client/ctdb_client.c      |   20 +++++++++++++----
 include/ctdb_client.h     |    2 +-
 include/ctdb_private.h    |    4 +++
 include/ctdb_protocol.h   |   10 ++++----
 libctdb/control.c         |   22 ++++++++++++++++---
 server/ctdb_call.c        |   23 ++++++++++++++------
 server/ctdb_control.c     |   15 ++-----------
 server/ctdb_ltdb_server.c |   49 ++++++++++++++++++++++++++++++++++++++++++--
 server/ctdb_recoverd.c    |   23 ++++++++++++++++++--
 tests/src/ctdb_lock_tdb.c |   42 ++++++++++++++++++++++++++++++++++++++
 tools/ctdb.c              |    9 ++++++++
 12 files changed, 184 insertions(+), 41 deletions(-)
 create mode 100644 tests/src/ctdb_lock_tdb.c


Changeset truncated at 500 lines:

diff --git a/Makefile.in b/Makefile.in
index 620ed84..7bda4d5 100755
--- a/Makefile.in
+++ b/Makefile.in
@@ -120,7 +120,7 @@ TEST_BINS=tests/bin/ctdb_bench tests/bin/ctdb_fetch tests/bin/ctdb_fetch_one \
 	tests/bin/ctdb_takeover_tests tests/bin/ctdb_update_record \
 	tests/bin/ctdb_update_record_persistent \
 	tests/bin/ctdb_tool_libctdb tests/bin/ctdb_tool_stubby \
-	tests/bin/ctdb_porting_tests \
+	tests/bin/ctdb_porting_tests tests/bin/ctdb_lock_tdb \
 	@INFINIBAND_BINS@
 
 BINS = bin/ctdb @CTDB_SCSI_IO@ bin/smnotify bin/ping_pong bin/ltdbtool \
@@ -313,6 +313,10 @@ tests/bin/ctdb_tool_stubby: $(CTDB_TEST_OBJ) tests/src/ctdb_tool_stubby.o
 	@echo Linking $@
 	$(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_tool_stubby.o $(CTDB_TEST_OBJ) $(POPT_OBJ) $(LIB_FLAGS)
 
+tests/bin/ctdb_lock_tdb: tests/src/ctdb_lock_tdb.o @TDB_OBJ@
+	@echo Linking $@
+	$(WRAPPER) $(CC) $(CFLAGS) -o $@ $^ $(LIB_FLAGS)
+
 tests/bin/ibwrapper_test: $(CTDB_CLIENT_OBJ) ib/ibwrapper_test.o
 	@echo Linking $@
 	$(WRAPPER) $(CC) $(CFLAGS) -o $@ ib/ibwrapper_test.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
diff --git a/client/ctdb_client.c b/client/ctdb_client.c
index 08e4903..ebd448c 100644
--- a/client/ctdb_client.c
+++ b/client/ctdb_client.c
@@ -1781,19 +1781,21 @@ int ctdb_ctrl_getdbhealth(struct ctdb_context *ctdb,
 /*
   create a database
  */
-int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, 
-		       TALLOC_CTX *mem_ctx, const char *name, bool persistent)
+int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode,
+		       TALLOC_CTX *mem_ctx, const char *name, uint32_t tdb_flags)
 {
 	int ret;
 	int32_t res;
 	TDB_DATA data;
+	bool persistent;
 
 	data.dptr = discard_const(name);
 	data.dsize = strlen(name)+1;
 
-	ret = ctdb_control(ctdb, destnode, 0, 
-			   persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH, 
-			   0, data, 
+	persistent = (tdb_flags & CTDB_DB_FLAGS_PERSISTENT);
+	ret = ctdb_control(ctdb, destnode, 0,
+			   persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
+			   tdb_flags, data,
 			   mem_ctx, &data, &res, &timeout, NULL);
 
 	if (ret != 0 || res != 0) {
@@ -1930,6 +1932,14 @@ struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb,
 	data.dptr = discard_const(name);
 	data.dsize = strlen(name)+1;
 
+	/* CTDB has switched to using jenkins hash for volatile databases.
+	 * Even if tdb_flags do not explicitly mention TDB_INCOMPATIBLE_HASH,
+	 * always set it.
+	 */
+	if (!persistent) {
+		tdb_flags |= TDB_INCOMPATIBLE_HASH;
+	}
+
 	/* tell ctdb daemon to attach */
 	ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, tdb_flags, 
 			   persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
diff --git a/include/ctdb_client.h b/include/ctdb_client.h
index 8739923..b2ae3bf 100644
--- a/include/ctdb_client.h
+++ b/include/ctdb_client.h
@@ -289,7 +289,7 @@ int ctdb_ctrl_getdbhealth(struct ctdb_context *ctdb,
 			  uint32_t destnode,
 			  uint32_t dbid, TALLOC_CTX *mem_ctx,
 			  const char **reason);
-int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, const char *name, bool persistent);
+int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, const char *name, uint32_t tdb_flags);
 
 int ctdb_ctrl_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid);
 
diff --git a/include/ctdb_private.h b/include/ctdb_private.h
index cbaff97..9c78440 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -1561,6 +1561,10 @@ int ctdb_fetch_func(struct ctdb_call_info *call);
 
 int ctdb_fetch_with_header_func(struct ctdb_call_info *call);
 
+int32_t ctdb_control_get_db_statistics(struct ctdb_context *ctdb,
+				uint32_t db_id,
+				TDB_DATA *outdata);
+
 int ctdb_set_db_sticky(struct ctdb_context *ctdb, struct ctdb_db_context *ctdb_db);
 
 /*
diff --git a/include/ctdb_protocol.h b/include/ctdb_protocol.h
index 9e95f4d..f72381f 100644
--- a/include/ctdb_protocol.h
+++ b/include/ctdb_protocol.h
@@ -714,10 +714,6 @@ struct ctdb_statistics_wire {
 /*
  * db statistics
  */
-struct ctdb_db_hot_key {
-	uint32_t count;
-	TDB_DATA key;
-};
 struct ctdb_db_statistics {
 	struct {
 		uint32_t num_calls;
@@ -731,7 +727,11 @@ struct ctdb_db_statistics {
 	uint32_t db_ro_revokes;
 	uint32_t hop_count_bucket[MAX_COUNT_BUCKETS];
 	uint32_t num_hot_keys;
-	struct ctdb_db_hot_key hot_keys[MAX_HOT_KEYS];
+	struct {
+		uint32_t count;
+		TDB_DATA key;
+	} hot_keys[MAX_HOT_KEYS];
+	char hot_keys_wire[1];
 };
 
 /*
diff --git a/libctdb/control.c b/libctdb/control.c
index 2a7db95..447a1d1 100644
--- a/libctdb/control.c
+++ b/libctdb/control.c
@@ -124,6 +124,9 @@ bool ctdb_getdbstat_recv(struct ctdb_connection *ctdb,
 			 struct ctdb_db_statistics **stat)
 {
 	struct ctdb_reply_control *reply;
+	struct ctdb_db_statistics *s, *wire;
+	int i;
+	char *ptr;
 
 	reply = unpack_reply_control(req, CTDB_CONTROL_GET_DB_STATISTICS);
 	if (!reply) {
@@ -133,16 +136,27 @@ bool ctdb_getdbstat_recv(struct ctdb_connection *ctdb,
 		DEBUG(ctdb, LOG_ERR, "ctdb_getpnn_recv: status -1");
 		return false;
 	}
-	if (reply->datalen < offsetof(struct ctdb_db_statistics, hot_keys)) {
+	if (reply->datalen < offsetof(struct ctdb_db_statistics, hot_keys_wire)) {
 		DEBUG(ctdb, LOG_ERR, "ctdb_getdbstat_recv: returned data is %d bytes but should be >= %d", reply->datalen, (int)sizeof(struct ctdb_db_statistics));
 		return false;
 	}
 
-	*stat = malloc(reply->datalen);
-	if (*stat == NULL) {
+	wire = (struct ctdb_db_statistics *)reply->data;
+
+	s = malloc(sizeof(struct ctdb_db_statistics));
+	if (!s) {
 		return false;
 	}
-	memcpy(*stat, reply->data, reply->datalen);
+
+	*s = *wire;
+	ptr = &wire->hot_keys_wire[0];
+	for (i = 0; i < wire->num_hot_keys; i++) {
+		s->hot_keys[i].key.dptr = malloc(s->hot_keys[i].key.dsize);
+		memcpy(s->hot_keys[i].key.dptr, ptr, s->hot_keys[i].key.dsize);
+		ptr += s->hot_keys[i].key.dsize;
+	}
+
+	*stat = s;
 
 	return true;
 }
diff --git a/server/ctdb_call.c b/server/ctdb_call.c
index aa69f93..87209fd 100644
--- a/server/ctdb_call.c
+++ b/server/ctdb_call.c
@@ -658,7 +658,7 @@ ctdb_defer_pinned_down_request(struct ctdb_context *ctdb, struct ctdb_db_context
 static void
 ctdb_update_db_stat_hot_keys(struct ctdb_db_context *ctdb_db, TDB_DATA key, int hopcount)
 {
-	int i;
+	int i, id;
 
 	/* smallest value is always at index 0 */
 	if (hopcount <= ctdb_db->statistics.hot_keys[0].count) {
@@ -681,16 +681,25 @@ ctdb_update_db_stat_hot_keys(struct ctdb_db_context *ctdb_db, TDB_DATA key, int
 		goto sort_keys;
 	}
 
-	if (ctdb_db->statistics.hot_keys[0].key.dptr != NULL) {
-		talloc_free(ctdb_db->statistics.hot_keys[0].key.dptr);
+	if (ctdb_db->statistics.num_hot_keys < MAX_HOT_KEYS) {
+		id = ctdb_db->statistics.num_hot_keys;
+		ctdb_db->statistics.num_hot_keys++;
+	} else {
+		id = 0;
 	}
-	ctdb_db->statistics.hot_keys[0].key.dsize = key.dsize;
-	ctdb_db->statistics.hot_keys[0].key.dptr  = talloc_memdup(ctdb_db, key.dptr, key.dsize);
-	ctdb_db->statistics.hot_keys[0].count = hopcount;
 
+	if (ctdb_db->statistics.hot_keys[id].key.dptr != NULL) {
+		talloc_free(ctdb_db->statistics.hot_keys[id].key.dptr);
+	}
+	ctdb_db->statistics.hot_keys[id].key.dsize = key.dsize;
+	ctdb_db->statistics.hot_keys[id].key.dptr  = talloc_memdup(ctdb_db, key.dptr, key.dsize);
+	ctdb_db->statistics.hot_keys[id].count = hopcount;
 
 sort_keys:
-	for (i = 2; i < MAX_HOT_KEYS; i++) {
+	for (i = 1; i < MAX_HOT_KEYS; i++) {
+		if (ctdb_db->statistics.hot_keys[i].count == 0) {
+			continue;
+		}
 		if (ctdb_db->statistics.hot_keys[i].count < ctdb_db->statistics.hot_keys[0].count) {
 			hopcount = ctdb_db->statistics.hot_keys[i].count;
 			ctdb_db->statistics.hot_keys[i].count = ctdb_db->statistics.hot_keys[0].count;
diff --git a/server/ctdb_control.c b/server/ctdb_control.c
index 690608e..a8771f3 100644
--- a/server/ctdb_control.c
+++ b/server/ctdb_control.c
@@ -651,18 +651,9 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
 		CHECK_CONTROL_DATA_SIZE(size);
 		return ctdb_control_schedule_for_deletion(ctdb, indata);
 	}
-	case CTDB_CONTROL_GET_DB_STATISTICS: {
-		uint32_t db_id;
-		struct ctdb_db_context *ctdb_db;
-
-		CHECK_CONTROL_DATA_SIZE(sizeof(db_id));
-		db_id = *(uint32_t *)indata.dptr;
-		ctdb_db = find_ctdb_db(ctdb, db_id);
-		if (ctdb_db == NULL) return -1;
-		outdata->dptr = (uint8_t *)&ctdb_db->statistics;
-		outdata->dsize = sizeof(ctdb_db->statistics);
-		return 0;
-	}
+	case CTDB_CONTROL_GET_DB_STATISTICS:
+		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
+		return ctdb_control_get_db_statistics(ctdb, *(uint32_t *)indata.dptr, outdata);
 
 	case CTDB_CONTROL_RELOAD_PUBLIC_IPS:
 		CHECK_CONTROL_DATA_SIZE(0);
diff --git a/server/ctdb_ltdb_server.c b/server/ctdb_ltdb_server.c
index 57e0d68..db9bc01 100644
--- a/server/ctdb_ltdb_server.c
+++ b/server/ctdb_ltdb_server.c
@@ -1484,9 +1484,6 @@ int32_t ctdb_control_set_db_priority(struct ctdb_context *ctdb, TDB_DATA indata)
 
 int ctdb_set_db_sticky(struct ctdb_context *ctdb, struct ctdb_db_context *ctdb_db)
 {
-
-	DEBUG(DEBUG_NOTICE,("set db sticky %s\n", ctdb_db->db_name));
-
 	if (ctdb_db->sticky) {
 		return 0;
 	}
@@ -1500,5 +1497,51 @@ int ctdb_set_db_sticky(struct ctdb_context *ctdb, struct ctdb_db_context *ctdb_d
 
 	ctdb_db->sticky = true;
 
+	DEBUG(DEBUG_NOTICE,("set db sticky %s\n", ctdb_db->db_name));
+
+	return 0;
+}
+
+int32_t ctdb_control_get_db_statistics(struct ctdb_context *ctdb,
+				uint32_t db_id,
+				TDB_DATA *outdata)
+{
+	struct ctdb_db_context *ctdb_db;
+	struct ctdb_db_statistics *stats;
+	int i;
+	int len;
+	char *ptr;
+
+	ctdb_db = find_ctdb_db(ctdb, db_id);
+	if (!ctdb_db) {
+		DEBUG(DEBUG_ERR,("Unknown db_id 0x%x in get_db_statistics\n", db_id));
+		return -1;
+	}
+
+	len = offsetof(struct ctdb_db_statistics, hot_keys_wire);
+	for (i = 0; i < MAX_HOT_KEYS; i++) {
+		len += ctdb_db->statistics.hot_keys[i].key.dsize;
+	}
+
+	stats = talloc_size(outdata, len);
+	if (stats == NULL) {
+		DEBUG(DEBUG_ERR,("Failed to allocate db statistics structure\n"));
+		return -1;
+	}
+
+	*stats = ctdb_db->statistics;
+
+	stats->num_hot_keys = MAX_HOT_KEYS;
+
+	ptr = &stats->hot_keys_wire[0];
+	for (i = 0; i < MAX_HOT_KEYS; i++) {
+		memcpy(ptr, ctdb_db->statistics.hot_keys[i].key.dptr,
+		       ctdb_db->statistics.hot_keys[i].key.dsize);
+		ptr += ctdb_db->statistics.hot_keys[i].key.dsize;
+	}
+
+	outdata->dptr  = (uint8_t *)stats;
+	outdata->dsize = len;
+
 	return 0;
 }
diff --git a/server/ctdb_recoverd.c b/server/ctdb_recoverd.c
index bf8d8cc..cb07339 100644
--- a/server/ctdb_recoverd.c
+++ b/server/ctdb_recoverd.c
@@ -468,7 +468,7 @@ static int create_missing_remote_databases(struct ctdb_context *ctdb, struct ctd
 			}
 			ctdb_ctrl_createdb(ctdb, CONTROL_TIMEOUT(), nodemap->nodes[j].pnn, 
 					   mem_ctx, name,
-					   dbmap->dbs[db].flags & CTDB_DB_FLAGS_PERSISTENT);
+					   dbmap->dbs[db].flags);
 			if (ret != 0) {
 				DEBUG(DEBUG_ERR, (__location__ " Unable to create remote db:%s\n", name));
 				return -1;
@@ -531,7 +531,7 @@ static int create_missing_local_databases(struct ctdb_context *ctdb, struct ctdb
 				return -1;
 			}
 			ctdb_ctrl_createdb(ctdb, CONTROL_TIMEOUT(), pnn, mem_ctx, name, 
-					   remote_dbmap->dbs[db].flags & CTDB_DB_FLAGS_PERSISTENT);
+					   remote_dbmap->dbs[db].flags);
 			if (ret != 0) {
 				DEBUG(DEBUG_ERR, (__location__ " Unable to create local db:%s\n", name));
 				return -1;
@@ -1176,7 +1176,7 @@ static struct tdb_wrap *create_recdb(struct ctdb_context *ctdb, TALLOC_CTX *mem_
 	if (ctdb->valgrinding) {
 		tdb_flags |= TDB_NOMMAP;
 	}
-	tdb_flags |= TDB_DISALLOW_NESTING;
+	tdb_flags |= (TDB_INCOMPATIBLE_HASH | TDB_DISALLOW_NESTING);
 
 	recdb = tdb_wrap_open(mem_ctx, name, ctdb->tunable.database_hash_size, 
 			      tdb_flags, O_RDWR|O_CREAT|O_EXCL, 0600);
@@ -3716,6 +3716,23 @@ static void main_loop(struct ctdb_context *ctdb, struct ctdb_recoverd *rec,
 				return;
 			}
 		}
+	}
+
+	/*
+	 * Update node flags obtained from each active node. This ensure we have
+	 * up-to-date information for all the nodes.
+	 */
+	for (j=0; j<nodemap->num; j++) {
+		if (nodemap->nodes[j].flags & NODE_FLAGS_INACTIVE) {
+			continue;
+		}
+		nodemap->nodes[j].flags = remote_nodemaps[j]->nodes[j].flags;
+	}
+
+	for (j=0; j<nodemap->num; j++) {
+		if (nodemap->nodes[j].flags & NODE_FLAGS_INACTIVE) {
+			continue;
+		}
 
 		/* verify the flags are consistent
 		*/
diff --git a/tests/src/ctdb_lock_tdb.c b/tests/src/ctdb_lock_tdb.c
new file mode 100644
index 0000000..ad2a329
--- /dev/null
+++ b/tests/src/ctdb_lock_tdb.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include <fcntl.h>
+
+#include "includes.h"
+
+const char *tdb_file;
+TDB_CONTEXT *tdb;
+
+void signal_handler(int signum)
+{
+	tdb_close(tdb);
+}
+
+
+int
+main(int argc, char *argv[])
+{
+	if (argc != 2) {
+		printf("Usage: %s <tdb file>\n", argv[0]);
+		exit(1);
+	}
+
+	tdb_file = argv[1];
+
+	tdb = tdb_open(tdb_file, 0, 0, O_RDWR, 0);
+	if (tdb == NULL) {
+		fprintf(stderr, "Failed to open TDB file %s\n", tdb_file);
+		exit(1);
+	}
+
+	signal(SIGINT, signal_handler);
+
+	if (tdb_lockall(tdb) != 0) {
+		fprintf(stderr, "Failed to lock database %s\n", tdb_file);
+		tdb_close(tdb);
+		exit(1);
+	}
+
+	sleep(999999);
+
+	return 0;
+}
diff --git a/tools/ctdb.c b/tools/ctdb.c
index 4c04725..ee60374 100644
--- a/tools/ctdb.c
+++ b/tools/ctdb.c
@@ -604,6 +604,7 @@ static int control_dbstatistics(struct ctdb_context *ctdb, int argc, const char
 	struct ctdb_db_statistics *dbstat;
 	int i;
 	uint32_t db_id;
+	int num_hot_keys;
 
 	if (argc < 1) {
 		usage();
@@ -651,6 +652,14 @@ static int control_dbstatistics(struct ctdb_context *ctdb, int argc, const char
 		 0.0),
 		dbstat->locks.latency.max,
 		dbstat->locks.latency.num);
+	num_hot_keys = 0;
+	for (i=0; i<dbstat->num_hot_keys; i++) {
+		if (dbstat->hot_keys[i].count > 0) {
+			num_hot_keys++;
+		}
+	}
+	dbstat->num_hot_keys = num_hot_keys;
+
 	printf(" Num Hot Keys:     %d\n", dbstat->num_hot_keys);
 	for (i = 0; i < dbstat->num_hot_keys; i++) {
 		int j;


-- 
CTDB repository


More information about the samba-cvs mailing list