[SCM] CTDB repository - branch master updated - ctdb-1.10-43-g7376410

Ronnie Sahlberg sahlberg at samba.org
Mon Dec 6 21:39:57 MST 2010


The branch, master has been updated
       via  73764104356d3738d9d20a9d06ce51535f74f475 (commit)
       via  a8cc35191df1cd4b866897df71d317ce5f198cb5 (commit)
       via  70c2e7dd04727371590fb94579ffd20318fbeb58 (commit)
       via  fe9070ec9be69e6a6fcbf9899e7ced24541c9c3a (commit)
       via  17e231abf5ade83d7fa624b5cf54ae876e2795aa (commit)
      from  8a6da384f3fa08b1c5eba79d6febc7af7b3d9229 (commit)

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


- Log -----------------------------------------------------------------
commit 73764104356d3738d9d20a9d06ce51535f74f475
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Mon Dec 6 13:52:38 2010 +1030

    idtree: fix overflow for v. large ids on allocation and removal
    
    (Imported from SAMBA commit 09a6538969ac).
    
    Chris Cowan tracked down a SEGV in sub_alloc: idp->level can actually
    be equal to 7 (MAX_LEVEL) there, as it can be in sub_remove.
    
    (We unfairly blamed a shift of a signed var for this crash in commit
     2db1987f5a3a).
    
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>

commit a8cc35191df1cd4b866897df71d317ce5f198cb5
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Mon Dec 6 16:09:38 2010 +1100

    Add a new header flag for "migrated with data" and set this to 1
    when we migrate a non-empty record onto the node
    or a non-empty record off the node
    
    When we migrate a record back to the lmaster and yield the dmaster role,
    inspect this flag if if it is still not set, we can delete the record from
    the local database as soon as we have migrated it back to the lmaster.

commit 70c2e7dd04727371590fb94579ffd20318fbeb58
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Mon Dec 6 16:07:55 2010 +1100

    add new command line functions
    ctdb readkey <dbid> <key>
    ctdb writekey <dbid> <key> <value>
    
    these are mainly intended for debugging of databases and dmaster migration issues

commit fe9070ec9be69e6a6fcbf9899e7ced24541c9c3a
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Mon Dec 6 16:06:20 2010 +1100

    add a new ctdb_ltdb function to delete a record in a normal database

commit 17e231abf5ade83d7fa624b5cf54ae876e2795aa
Author: Michael Adam <obnox at samba.org>
Date:   Fri Dec 3 15:21:51 2010 +0100

    server: when we migrate off a record with data, set the MIGRATED_WITH_DATA flag

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

Summary of changes:
 common/ctdb_ltdb.c     |   19 +++++++++
 include/ctdb_private.h |    1 +
 lib/util/idtree.c      |    2 +-
 server/ctdb_call.c     |   28 ++++++++++++-
 tools/ctdb.c           |  103 ++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 149 insertions(+), 4 deletions(-)


Changeset truncated at 500 lines:

diff --git a/common/ctdb_ltdb.c b/common/ctdb_ltdb.c
index 7dc28dd..3572371 100644
--- a/common/ctdb_ltdb.c
+++ b/common/ctdb_ltdb.c
@@ -195,3 +195,22 @@ int ctdb_ltdb_unlock(struct ctdb_db_context *ctdb_db, TDB_DATA key)
 	}
 	return ret;
 }
+
+
+/*
+  delete a record from a normal database
+*/
+int ctdb_ltdb_delete(struct ctdb_db_context *ctdb_db, TDB_DATA key)
+{
+	struct ctdb_context *ctdb = ctdb_db->ctdb;
+
+	if (ctdb_db->persistent != 0) {
+		DEBUG(DEBUG_ERR,("Trying to delete emty record in persistent database\n"));
+		return 0;
+	}
+	if (tdb_delete(ctdb_db->ltdb->tdb, key) != 0) {
+		DEBUG(DEBUG_ERR,("Failed to delete empty record."));
+		return -1;
+	}
+	return 0;
+}
diff --git a/include/ctdb_private.h b/include/ctdb_private.h
index 5fc583c..243a4dd 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -648,6 +648,7 @@ int ctdb_ltdb_fetch(struct ctdb_db_context *ctdb_db,
 		    TALLOC_CTX *mem_ctx, TDB_DATA *data);
 int ctdb_ltdb_store(struct ctdb_db_context *ctdb_db, TDB_DATA key, 
 		    struct ctdb_ltdb_header *header, TDB_DATA data);
+int ctdb_ltdb_delete(struct ctdb_db_context *ctdb_db, TDB_DATA key);
 int32_t ctdb_control_start_persistent_update(struct ctdb_context *ctdb, 
 			struct ctdb_req_control *c,
 			TDB_DATA recdata);
diff --git a/lib/util/idtree.c b/lib/util/idtree.c
index 05c2295..09dc237 100644
--- a/lib/util/idtree.c
+++ b/lib/util/idtree.c
@@ -104,7 +104,7 @@ static int sub_alloc(struct idr_context *idp, void *ptr, int *starting_id)
 {
 	int n, m, sh;
 	struct idr_layer *p, *new;
-	struct idr_layer *pa[MAX_LEVEL];
+	struct idr_layer *pa[MAX_LEVEL+1];
 	unsigned int l, id, oid;
 	uint32_t bm;
 
diff --git a/server/ctdb_call.c b/server/ctdb_call.c
index c5f7e7d..7bc4c35 100644
--- a/server/ctdb_call.c
+++ b/server/ctdb_call.c
@@ -201,6 +201,11 @@ static void ctdb_call_send_dmaster(struct ctdb_db_context *ctdb_db,
 		return;
 	}
 
+	if (data->dsize != 0) {
+		header->flags |= CTDB_REC_FLAG_MIGRATED_WITH_DATA;
+	}
+
+
 	if (lmaster == ctdb->pnn) {
 		ctdb_send_dmaster_reply(ctdb_db, header, *key, *data, 
 					c->hdr.srcnode, c->hdr.reqid);
@@ -222,10 +227,19 @@ static void ctdb_call_send_dmaster(struct ctdb_db_context *ctdb_db,
 	memcpy(&r->data[key->dsize], data->dptr, data->dsize);
 
 	header->dmaster = c->hdr.srcnode;
-	if (ctdb_ltdb_store(ctdb_db, *key, header, *data) != 0) {
-		ctdb_fatal(ctdb, "Failed to store record in ctdb_call_send_dmaster");
+
+	if (data->dsize == 0
+	&& lmaster != ctdb->pnn
+	&& (header->flags & CTDB_REC_FLAG_MIGRATED_WITH_DATA) == 0) {
+		if (ctdb_ltdb_delete(ctdb_db, *key) != 0) {
+			ctdb_fatal(ctdb, "Failed to delete empty record when migrating it off the node");
+		}
+	} else {
+		if (ctdb_ltdb_store(ctdb_db, *key, header, *data) != 0) {
+			ctdb_fatal(ctdb, "Failed to store record in ctdb_call_send_dmaster");
+		}
 	}
-	
+
 	ctdb_queue_packet(ctdb, &r->hdr);
 
 	talloc_free(r);
@@ -253,6 +267,10 @@ static void ctdb_become_dmaster(struct ctdb_db_context *ctdb_db,
 	header.rsn = rsn + 1;
 	header.dmaster = ctdb->pnn;
 
+	if (data.dsize != 0) {
+		header.flags |= CTDB_REC_FLAG_MIGRATED_WITH_DATA;
+	}
+
 	if (ctdb_ltdb_store(ctdb_db, key, &header, data) != 0) {
 		ctdb_fatal(ctdb, "ctdb_reply_dmaster store failed\n");
 
@@ -351,6 +369,10 @@ void ctdb_request_dmaster(struct ctdb_context *ctdb, struct ctdb_req_header *hdr
 		return;
 	}
 
+	if (data.dsize != 0) {
+		header.flags |= CTDB_REC_FLAG_MIGRATED_WITH_DATA;
+	}
+
 	if (ctdb_lmaster(ctdb, &key) != ctdb->pnn) {
 		DEBUG(DEBUG_ALERT,("pnn %u dmaster request to non-lmaster lmaster=%u gen=%u curgen=%u\n",
 			 ctdb->pnn, ctdb_lmaster(ctdb, &key), 
diff --git a/tools/ctdb.c b/tools/ctdb.c
index bb18c6a..19cb071 100644
--- a/tools/ctdb.c
+++ b/tools/ctdb.c
@@ -2981,6 +2981,107 @@ static int control_catdb(struct ctdb_context *ctdb, int argc, const char **argv)
 	return 0;
 }
 
+/*
+  display the content of a database key
+ */
+static int control_readkey(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+	const char *db_name;
+	struct ctdb_db_context *ctdb_db;
+	struct ctdb_record_handle *h;
+	TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
+	TDB_DATA key, data;
+
+	if (argc < 2) {
+		usage();
+	}
+
+	db_name = argv[0];
+
+
+	if (db_exists(ctdb, db_name)) {
+		DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
+		return -1;
+	}
+
+	ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
+
+	if (ctdb_db == NULL) {
+		DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
+		return -1;
+	}
+
+	key.dptr  = discard_const(argv[1]);
+	key.dsize = strlen((char *)key.dptr);
+ 
+	h = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, &data);
+	if (h == NULL) {
+		printf("Failed to fetch record '%s' on node %d\n", 
+	       		(const char *)key.dptr, ctdb_get_pnn(ctdb));
+		talloc_free(tmp_ctx);
+		exit(10);
+	}
+
+	printf("Data: size:%d ptr:[%s]\n", (int)data.dsize, data.dptr);
+
+	talloc_free(ctdb_db);
+	talloc_free(tmp_ctx);
+	return 0;
+}
+
+/*
+  display the content of a database key
+ */
+static int control_writekey(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+	const char *db_name;
+	struct ctdb_db_context *ctdb_db;
+	struct ctdb_record_handle *h;
+	TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
+	TDB_DATA key, data;
+
+	if (argc < 3) {
+		usage();
+	}
+
+	db_name = argv[0];
+
+
+	if (db_exists(ctdb, db_name)) {
+		DEBUG(DEBUG_ERR,("Database '%s' does not exist\n", db_name));
+		return -1;
+	}
+
+	ctdb_db = ctdb_attach(ctdb, db_name, false, 0);
+
+	if (ctdb_db == NULL) {
+		DEBUG(DEBUG_ERR,("Unable to attach to database '%s'\n", db_name));
+		return -1;
+	}
+
+	key.dptr  = discard_const(argv[1]);
+	key.dsize = strlen((char *)key.dptr);
+ 
+	h = ctdb_fetch_lock(ctdb_db, tmp_ctx, key, &data);
+	if (h == NULL) {
+		printf("Failed to fetch record '%s' on node %d\n", 
+	       		(const char *)key.dptr, ctdb_get_pnn(ctdb));
+		talloc_free(tmp_ctx);
+		exit(10);
+	}
+
+	data.dptr  = discard_const(argv[2]);
+	data.dsize = strlen((char *)data.dptr);
+ 
+	if (ctdb_record_store(h, data) != 0) {
+		printf("Failed to store record\n");
+	}
+
+	talloc_free(h);
+	talloc_free(ctdb_db);
+	talloc_free(tmp_ctx);
+	return 0;
+}
 
 /*
   fetch a record from a persistent database
@@ -4833,6 +4934,8 @@ static const struct {
 	{ "pfetch", 	     control_pfetch,      	false,	false,  "fetch a record from a persistent database", "<db> <key> [<file>]" },
 	{ "pstore", 	     control_pstore,      	false,	false,  "write a record to a persistent database", "<db> <key> <file containing record>" },
 	{ "tfetch", 	     control_tfetch,      	false,	true,  "fetch a record from a [c]tdb-file", "<tdb-file> <key> [<file>]" },
+	{ "readkey", 	     control_readkey,      	true,	false,  "read the content off a database key", "<tdb-file> <key>" },
+	{ "writekey", 	     control_writekey,      	true,	false,  "write to a database key", "<tdb-file> <key> <value>" },
 };
 
 /*


-- 
CTDB repository


More information about the samba-cvs mailing list