[SCM] CTDB repository - branch 2.5 updated - ctdb-2.5.3-17-g8a6f2fc

Amitay Isaacs amitay at samba.org
Wed Apr 23 20:02:20 MDT 2014


The branch, 2.5 has been updated
       via  8a6f2fc686c14c713ede05c863662d4583ff3841 (commit)
       via  2d4cb9ca3106609d341f51eb2d5d53853e81f71e (commit)
       via  a5cc53fd4b02a056ac51d27d35b453de9d778477 (commit)
       via  e23cce03f5eccacd59bf0f2f94041a199115a98a (commit)
       via  378b155a58c4cf82e6584249cd2be2fc37fc2212 (commit)
       via  42c564da7b212d3883a2096923e8c962311443eb (commit)
       via  237b60eaea0ad875cda6881387d16fb579352360 (commit)
       via  f51eddecc6f2810c1e0ea9209c873f1a41102227 (commit)
      from  0646118393e493704915e9e112d2afb607fcc12b (commit)

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


- Log -----------------------------------------------------------------
commit 8a6f2fc686c14c713ede05c863662d4583ff3841
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Apr 22 15:24:49 2014 +1000

    recoverd: Detach database from recovery daemon
    
    As part of vacuuming, recoverd attaches to databases to migrate records.
    When detaching a database from main daemon, it should be removed from
    recovery daemon also.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    Autobuild-User(master): Michael Adam <obnox at samba.org>
    Autobuild-Date(master): Wed Apr 23 17:05:45 CEST 2014 on sn-devel-104
    
    (Imported from commit 463ea9e52541aaadcdcf97808d05ca6dacbbea6e)

commit 2d4cb9ca3106609d341f51eb2d5d53853e81f71e
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Apr 22 12:19:08 2014 +1000

    tests: Add test for re-attaching detached database
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    (Imported from commit b31240acafb20100cf249c6346fb41f90a06158b)

commit a5cc53fd4b02a056ac51d27d35b453de9d778477
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Wed Apr 23 11:44:20 2014 +1000

    tools/ctdb: Unlock records before closing tdb database
    
    Now freeing ctdb_db context will close the tdb database.  So make sure
    all the locks are released (by freeing record handles or memory context
    from which record handles are allocated) before freeing ctdb_db context.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    (Imported from commit 581ee2e4c32a1ddb77f4fccb6a5ade610998d47e)

commit e23cce03f5eccacd59bf0f2f94041a199115a98a
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Apr 22 15:07:33 2014 +1000

    client: Talloc tdb_wrap off ctdb_db_context
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    (Imported from commit db0a1df25c868b4536f879d1191c4317065e6f06)

commit 378b155a58c4cf82e6584249cd2be2fc37fc2212
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Sun Apr 20 20:52:03 2014 +1000

    daemon: Talloc tdb_wrap off ctdb_db_context
    
    This will ensure that when ctdb_db is freed, it will close the tdb
    database.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    (Imported from commit d9d3af7baa78c106197b222010098176a8bc6079)

commit 42c564da7b212d3883a2096923e8c962311443eb
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Apr 15 13:53:09 2014 +1000

    tests: Update "ctdb detach" test
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    (Imported from commit bf83abced4e5219c40c93098e014944e19c04cb5)

commit 237b60eaea0ad875cda6881387d16fb579352360
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Apr 15 12:27:44 2014 +1000

    tools/ctdb: Detach databases only if all nodes disallow client access
    
    This makes sure that AllowClientDBAttach is set to 0 before detaching any
    databases.
    
    If someone enables the tunable between checking of tunable and actual
    detaching of databases, then they deserve what they get. :-)
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    (Imported from commit a1e1b81b9c0a267cd956ee0a170dd5d609d12891)

commit f51eddecc6f2810c1e0ea9209c873f1a41102227
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Tue Apr 15 12:23:42 2014 +1000

    daemon: Do not allow database detach if AllowClientDBAttach=1
    
    This avoids the server detaching a database if clients are allowed to
    connect to databases.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    (Imported from commit 1d4fb1b702b8bf4ffdff6fee626c280b174c5aee)

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

Summary of changes:
 client/ctdb_client.c           |    3 +-
 doc/ctdb.1.xml                 |    4 ++
 include/ctdb_protocol.h        |    4 ++
 server/ctdb_ltdb_server.c      |   17 +++++--
 server/ctdb_recoverd.c         |   46 ++++++++++++++++++
 tests/simple/27_ctdb_detach.sh |  104 ++++++++++++++++++++++++++++++++++------
 tools/ctdb.c                   |   68 +++++++++++++++++++++++++-
 7 files changed, 224 insertions(+), 22 deletions(-)


Changeset truncated at 500 lines:

diff --git a/client/ctdb_client.c b/client/ctdb_client.c
index 51eec0e..73c593f 100644
--- a/client/ctdb_client.c
+++ b/client/ctdb_client.c
@@ -2101,7 +2101,8 @@ struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb,
 	}
 	tdb_flags |= TDB_DISALLOW_NESTING;
 
-	ctdb_db->ltdb = tdb_wrap_open(ctdb, ctdb_db->db_path, 0, tdb_flags, O_RDWR, 0);
+	ctdb_db->ltdb = tdb_wrap_open(ctdb_db, ctdb_db->db_path, 0, tdb_flags,
+				      O_RDWR, 0);
 	if (ctdb_db->ltdb == NULL) {
 		ctdb_set_error(ctdb, "Failed to open tdb '%s'\n", ctdb_db->db_path);
 		talloc_free(ctdb_db);
diff --git a/doc/ctdb.1.xml b/doc/ctdb.1.xml
index bff1188..051fe6a 100644
--- a/doc/ctdb.1.xml
+++ b/doc/ctdb.1.xml
@@ -1576,6 +1576,10 @@ HEALTH: NO-HEALTHY-NODES - ERROR - Backup of corrupted TDB in '/var/ctdb/persist
 	the cluster.  This command should only be used when none of the
 	specified database(s) are in use.
       </para>
+      <para>
+	All nodes should be active and tunable AllowClientDBAccess should
+	be disabled on all nodes before detaching databases.
+      </para>
     </refsect2>
 
     <refsect2>
diff --git a/include/ctdb_protocol.h b/include/ctdb_protocol.h
index f2d68f4..629c91c 100644
--- a/include/ctdb_protocol.h
+++ b/include/ctdb_protocol.h
@@ -114,6 +114,10 @@ struct ctdb_call_info {
 #define CTDB_SRVID_VACUUM_FETCH 0xF700000000000000LL
 
 /*
+ * a message to tell recovery daemon to detach a database
+ */
+#define CTDB_SRVID_DETACH_DATABASE 0xF701000000000000LL
+/*
   a message to tell the recovery daemon to write a talloc memdump
   to the log
  */
diff --git a/server/ctdb_ltdb_server.c b/server/ctdb_ltdb_server.c
index 3d8772f..6ff92c5 100644
--- a/server/ctdb_ltdb_server.c
+++ b/server/ctdb_ltdb_server.c
@@ -838,7 +838,7 @@ static int ctdb_local_attach(struct ctdb_context *ctdb, const char *db_name,
 	}
 
 again:
-	ctdb_db->ltdb = tdb_wrap_open(ctdb, ctdb_db->db_path, 
+	ctdb_db->ltdb = tdb_wrap_open(ctdb_db, ctdb_db->db_path,
 				      ctdb->tunable.database_hash_size, 
 				      tdb_flags, 
 				      O_CREAT|O_RDWR, mode);
@@ -1182,9 +1182,10 @@ int32_t ctdb_control_db_detach(struct ctdb_context *ctdb, TDB_DATA indata,
 		return -1;
 	}
 
-	if (ctdb->tunable.allow_client_db_attach == 0) {
-		DEBUG(DEBUG_ERR, ("DB detach from database %s denied by "
-				  "tunable AllowClientDBAccess == 0\n",
+	if (ctdb->tunable.allow_client_db_attach == 1) {
+		DEBUG(DEBUG_ERR, ("DB detach from database %s denied. "
+				  "Clients are allowed access to databases "
+				  "(AllowClientDBAccess == 1)\n",
 				  ctdb_db->db_name));
 		return -1;
 	}
@@ -1219,6 +1220,14 @@ int32_t ctdb_control_db_detach(struct ctdb_context *ctdb, TDB_DATA indata,
 		return -1;
 	}
 
+	/* Detach database from recoverd */
+	if (ctdb_daemon_send_message(ctdb, ctdb->pnn,
+				     CTDB_SRVID_DETACH_DATABASE,
+				     indata) != 0) {
+		DEBUG(DEBUG_ERR, ("Unable to detach DB from recoverd\n"));
+		return -1;
+	}
+
 	/* Disable vacuuming and drop all vacuuming data */
 	talloc_free(ctdb_db->vacuum_handle);
 	talloc_free(ctdb_db->delete_queue);
diff --git a/server/ctdb_recoverd.c b/server/ctdb_recoverd.c
index ac692ec..7758635 100644
--- a/server/ctdb_recoverd.c
+++ b/server/ctdb_recoverd.c
@@ -1095,6 +1095,47 @@ static void vacuum_fetch_handler(struct ctdb_context *ctdb, uint64_t srvid,
 
 
 /*
+ * handler for database detach
+ */
+static void detach_database_handler(struct ctdb_context *ctdb, uint64_t srvid,
+				    TDB_DATA data, void *private_data)
+{
+	struct ctdb_recoverd *rec = talloc_get_type(private_data,
+						    struct ctdb_recoverd);
+	uint32_t db_id;
+	struct vacuum_info *v, *vnext;
+	struct ctdb_db_context *ctdb_db;
+
+	if (data.dsize != sizeof(db_id)) {
+		return;
+	}
+	db_id = *(uint32_t *)data.dptr;
+
+	ctdb_db = find_ctdb_db(ctdb, db_id);
+	if (ctdb_db == NULL) {
+		/* database is not attached */
+		return;
+	}
+
+	/* Stop any active vacuum fetch */
+	v = rec->vacuum_info;
+	while (v != NULL) {
+		vnext = v->next;
+
+		if (v->ctdb_db->db_id == db_id) {
+			talloc_free(v);
+		}
+		v = vnext;
+	}
+
+	DLIST_REMOVE(ctdb->db_list, ctdb_db);
+
+	DEBUG(DEBUG_NOTICE, ("Detached from database '%s'\n",
+			     ctdb_db->db_name));
+	talloc_free(ctdb_db);
+}
+
+/*
   called when ctdb_wait_timeout should finish
  */
 static void ctdb_wait_handler(struct event_context *ev, struct timed_event *te, 
@@ -4145,6 +4186,11 @@ static void monitor_cluster(struct ctdb_context *ctdb)
 					CTDB_SRVID_DISABLE_TAKEOVER_RUNS,
 					disable_takeover_runs_handler, rec);
 
+	/* register a message port for detaching database */
+	ctdb_client_set_message_handler(ctdb,
+					CTDB_SRVID_DETACH_DATABASE,
+					detach_database_handler, rec);
+
 	for (;;) {
 		TALLOC_CTX *mem_ctx = talloc_new(ctdb);
 		struct timeval start;
diff --git a/tests/simple/27_ctdb_detach.sh b/tests/simple/27_ctdb_detach.sh
index 023320f..108a270 100755
--- a/tests/simple/27_ctdb_detach.sh
+++ b/tests/simple/27_ctdb_detach.sh
@@ -35,12 +35,33 @@ ctdb_restart_when_done
 
 ######################################################################
 
+try_command_on_node 0 "$CTDB listnodes -Y"
+listnodes_output="$out"
+numnodes=$(wc -l <<<"$listnodes_output")
+
+######################################################################
+
+# Confirm that the database is attached
+check_db ()
+{
+    db="$1"
+    try_command_on_node all $CTDB getdbmap
+    local num_db=$(grep -cF "$db" <<<"$out") || true
+    if [ $num_db -eq $numnodes ]; then
+	echo "GOOD: database $db is attached on all nodes"
+    else
+	echo "BAD: database $db is not attached on all nodes"
+	echo "$out"
+	exit 1
+    fi
+}
+
 # Confirm that no nodes have databases attached
 check_no_db ()
 {
     db="$1"
     try_command_on_node all $CTDB getdbmap
-    local num_db=$(grep -c "$db" <<<"$out") || true
+    local num_db=$(grep -cF "$db" <<<"$out") || true
     if [ $num_db -eq 0 ]; then
 	echo "GOOD: database $db is not attached any more"
     else
@@ -58,28 +79,81 @@ testdb3="detach_test3.tdb"
 testdb4="detach_test4.tdb"
 
 echo "Create test databases"
-echo "    $testdb1"
-try_command_on_node 0 $CTDB attach $testdb1
-echo "    $testdb2"
-try_command_on_node 0 $CTDB attach $testdb2
-echo "    $testdb3"
-try_command_on_node 0 $CTDB attach $testdb3
-echo "    $testdb4"
-try_command_on_node 0 $CTDB attach $testdb4
+for db in "$testdb1" "$testdb2" "$testdb3" "$testdb4" ; do
+    echo "  $db"
+    try_command_on_node 0 $CTDB attach "$db"
+done
+
+for db in "$testdb1" "$testdb2" "$testdb3" "$testdb4" ; do
+    check_db "$db"
+done
 
 ######################################################################
 
-echo "Detach single test database $testdb1"
-try_command_on_node 1 $CTDB detach $testdb1
+echo
+echo "Ensuring AllowClientDBAttach=1 on all nodes"
+try_command_on_node all $CTDB setvar AllowClientDBAttach 1
+
+echo "Check failure detaching single test database $testdb1"
+try_command_on_node 1 "! $CTDB detach $testdb1"
+check_db "$testdb1"
+
+echo
+echo "Setting AllowClientDBAttach=0 on node 0"
+try_command_on_node 0 $CTDB setvar AllowClientDBAttach 0
+
+echo "Check failure detaching single test database $testdb1"
+try_command_on_node 1 "! $CTDB detach $testdb1"
+check_db "$testdb1"
+
+echo
+echo "Setting AllowClientDBAttach=0 on all nodes"
+try_command_on_node all $CTDB setvar AllowClientDBAttach 0
 
-check_no_db $testdb1
+echo "Check detaching single test database $testdb1"
+try_command_on_node 1 "$CTDB detach $testdb1"
+check_no_db "$testdb1"
 
 ######################################################################
 
+echo
 echo "Detach multiple test databases"
 echo "    $testdb2, $testdb3, $testdb4"
 try_command_on_node 0 $CTDB detach $testdb2 $testdb3 $testdb4
 
-check_no_db $testdb2
-check_no_db $testdb3
-check_no_db $testdb4
+for db in "$testdb2" "$testdb3" "$testdb4" ; do
+    check_no_db "$db"
+done
+
+######################################################################
+
+echo
+echo "Attach a single test database"
+try_command_on_node all $CTDB setvar AllowClientDBAttach 1
+try_command_on_node 0 $CTDB attach $testdb1
+check_db "$testdb1"
+
+echo
+echo "Write a key to database"
+try_command_on_node 0 $CTDB writekey $testdb1 foo bar
+try_command_on_node 0 $CTDB catdb $testdb1
+num_keys=$(echo "$out" | sed -n -e 's/Dumped \([0-9]*\) records/\1/p') || true
+if [ -n "$num_keys" -a $num_keys -eq 1 ]; then
+    echo "GOOD: Key added to database"
+else
+    echo "BAD: Key did not get added to database"
+    echo "$out"
+    exit 1
+fi
+
+echo
+echo "Detach test database"
+try_command_on_node all $CTDB setvar AllowClientDBAttach 0
+try_command_on_node 0 $CTDB detach $testdb1
+check_no_db "$testdb1"
+
+echo
+echo "Re-attach test database"
+try_command_on_node all $CTDB setvar AllowClientDBAttach 1
+try_command_on_node 0 $CTDB attach $testdb1
+check_db "$testdb1"
diff --git a/tools/ctdb.c b/tools/ctdb.c
index 2541a60..d8265d7 100644
--- a/tools/ctdb.c
+++ b/tools/ctdb.c
@@ -3842,8 +3842,8 @@ static int control_readkey(struct ctdb_context *ctdb, int argc, const char **arg
 
 	printf("Data: size:%d ptr:[%.*s]\n", (int)data.dsize, (int)data.dsize, data.dptr);
 
-	talloc_free(ctdb_db);
 	talloc_free(tmp_ctx);
+	talloc_free(ctdb_db);
 	return 0;
 }
 
@@ -3892,8 +3892,8 @@ static int control_writekey(struct ctdb_context *ctdb, int argc, const char **ar
 	}
 
 	talloc_free(h);
-	talloc_free(ctdb_db);
 	talloc_free(tmp_ctx);
+	talloc_free(ctdb_db);
 	return 0;
 }
 
@@ -5194,6 +5194,9 @@ static int control_detach(struct ctdb_context *ctdb, int argc,
 	uint32_t db_id;
 	uint8_t flags;
 	int ret, i, status = 0;
+	struct ctdb_node_map *nodemap = NULL;
+	TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
+	uint32_t recmode;
 
 	if (argc < 1) {
 		usage();
@@ -5201,6 +5204,67 @@ static int control_detach(struct ctdb_context *ctdb, int argc,
 
 	assert_single_node_only();
 
+	ret = ctdb_ctrl_getrecmode(ctdb, tmp_ctx, TIMELIMIT(), options.pnn,
+				    &recmode);
+	if (ret != 0) {
+		DEBUG(DEBUG_ERR, ("Database cannot be detached "
+				  "when recovery is active\n"));
+		talloc_free(tmp_ctx);
+		return -1;
+	}
+
+	ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), options.pnn, tmp_ctx,
+				   &nodemap);
+	if (ret != 0) {
+		DEBUG(DEBUG_ERR, ("Unable to get nodemap from node %u\n",
+				  options.pnn));
+		talloc_free(tmp_ctx);
+		return -1;
+	}
+
+	for (i=0; i<nodemap->num; i++) {
+		uint32_t value;
+
+		if (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) {
+			continue;
+		}
+
+		if (nodemap->nodes[i].flags & NODE_FLAGS_DELETED) {
+			continue;
+		}
+
+		if (nodemap->nodes[i].flags & NODE_FLAGS_INACTIVE) {
+			DEBUG(DEBUG_ERR, ("Database cannot be detached on "
+					  "inactive (stopped or banned) node "
+					  "%u\n", nodemap->nodes[i].pnn));
+			talloc_free(tmp_ctx);
+			return -1;
+		}
+
+		ret = ctdb_ctrl_get_tunable(ctdb, TIMELIMIT(),
+					    nodemap->nodes[i].pnn,
+					    "AllowClientDBAttach",
+					    &value);
+		if (ret != 0) {
+			DEBUG(DEBUG_ERR, ("Unable to get tunable "
+					  "AllowClientDBAttach from node %u\n",
+					   nodemap->nodes[i].pnn));
+			talloc_free(tmp_ctx);
+			return -1;
+		}
+
+		if (value == 1) {
+			DEBUG(DEBUG_ERR, ("Database access is still active on "
+					  "node %u. Set AllowClientDBAttach=0 "
+					  "on all nodes.\n",
+					  nodemap->nodes[i].pnn));
+			talloc_free(tmp_ctx);
+			return -1;
+		}
+	}
+
+	talloc_free(tmp_ctx);
+
 	for (i=0; i<argc; i++) {
 		if (!db_exists(ctdb, argv[i], &db_id, NULL, &flags)) {
 			continue;


-- 
CTDB repository


More information about the samba-cvs mailing list