[SCM] CTDB repository - branch 1.2-nodeflags updated - ctdb-1.9.1-250-g9bf4766

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


The branch, 1.2-nodeflags has been updated
       via  9bf47667adbe4324b7587c61349b64affa5420c6 (commit)
       via  4a8590f76c5e7ea68acb4d5e52ec0e8a41b65fda (commit)
       via  1766f2ec5d1b2ae2d30323c03cd3e67a1bda804c (commit)
       via  7fba05d9f956ddaa3f466e72877e7d5f2e3a7a19 (commit)
       via  bb8d975376d959689e702c8e349e787fbde0db01 (commit)
      from  42f6125b66cb18bce362693358f4085c58dd0695 (commit)

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


- Log -----------------------------------------------------------------
commit 9bf47667adbe4324b7587c61349b64affa5420c6
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 4a8590f76c5e7ea68acb4d5e52ec0e8a41b65fda
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 1766f2ec5d1b2ae2d30323c03cd3e67a1bda804c
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 7fba05d9f956ddaa3f466e72877e7d5f2e3a7a19
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 bb8d975376d959689e702c8e349e787fbde0db01
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 984d826..8b6a9d3 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -647,6 +647,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 ae14d11..3f4e2d5 100644
--- a/tools/ctdb.c
+++ b/tools/ctdb.c
@@ -2918,6 +2918,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
@@ -4753,6 +4854,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