[SCM] Samba Shared Repository - branch master updated

Michael Adam obnox at samba.org
Wed Apr 23 09:06:04 MDT 2014


The branch, master has been updated
       via  463ea9e ctdb-recoverd: Detach database from recovery daemon
       via  b31240a ctdb-tests: Add test for re-attaching detached database
       via  581ee2e ctdb-tools/ctdb: Unlock records before closing tdb database
       via  db0a1df ctdb-client: Talloc tdb_wrap off ctdb_db_context
       via  d9d3af7 ctdb-daemon: Talloc tdb_wrap off ctdb_db_context
       via  bf83abc ctdb-tests: Update "ctdb detach" test
       via  a1e1b81 ctdb-tools/ctdb: Detach databases only if all nodes disallow client access
       via  1d4fb1b ctdb-daemon: Do not allow database detach if AllowClientDBAttach=1
      from  720f763 ad-dc: use exit_daemon() to communicate status of startup to systemd

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


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

    ctdb-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

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

    ctdb-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>

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

    ctdb-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>

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

    ctdb-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>

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

    ctdb-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>

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

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

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

    ctdb-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>

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

    ctdb-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>

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

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


Changeset truncated at 500 lines:

diff --git a/ctdb/client/ctdb_client.c b/ctdb/client/ctdb_client.c
index 51eec0e..73c593f 100644
--- a/ctdb/client/ctdb_client.c
+++ b/ctdb/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/ctdb/doc/ctdb.1.xml b/ctdb/doc/ctdb.1.xml
index 95a67db..433e650 100644
--- a/ctdb/doc/ctdb.1.xml
+++ b/ctdb/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/ctdb/include/ctdb_protocol.h b/ctdb/include/ctdb_protocol.h
index f2d68f4..629c91c 100644
--- a/ctdb/include/ctdb_protocol.h
+++ b/ctdb/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/ctdb/server/ctdb_ltdb_server.c b/ctdb/server/ctdb_ltdb_server.c
index 3d8772f..6ff92c5 100644
--- a/ctdb/server/ctdb_ltdb_server.c
+++ b/ctdb/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/ctdb/server/ctdb_recoverd.c b/ctdb/server/ctdb_recoverd.c
index ac692ec..7758635 100644
--- a/ctdb/server/ctdb_recoverd.c
+++ b/ctdb/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/ctdb/tests/simple/27_ctdb_detach.sh b/ctdb/tests/simple/27_ctdb_detach.sh
index 023320f..108a270 100755
--- a/ctdb/tests/simple/27_ctdb_detach.sh
+++ b/ctdb/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/ctdb/tools/ctdb.c b/ctdb/tools/ctdb.c
index 74cf321..624c61c 100644
--- a/ctdb/tools/ctdb.c
+++ b/ctdb/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;


-- 
Samba Shared Repository


More information about the samba-cvs mailing list