[SCM] CTDB repository - branch 1.0.114 updated - ctdb-1.0.114.4-15-g44e5406

Michael Adam obnox at samba.org
Mon May 7 05:32:19 MDT 2012


The branch, 1.0.114 has been updated
       via  44e540648477217e37ba43f664124e0996b4496b (commit)
       via  e14a771817182547c6b72cab81f33c1469fad925 (commit)
       via  2a6e17e75f73e492d0da118ef00e8d37d6a7fa07 (commit)
       via  2bbf862517e10f38a4271bfd1a62e788ce7b81a5 (commit)
       via  57d4c6c50082603e8ddbe77f969dc0bffe8452f5 (commit)
       via  839e59a153f176089dc38e73ffdce8c05bf3d09b (commit)
       via  bf26780c46a2fb9ce799bec6ea5e80abd0c1644e (commit)
       via  86d02ccdac9873fff646c0aec1b7d9719332ba37 (commit)
       via  8070ab284e311d4eea9e46e0121944d4b7139b07 (commit)
       via  dce8248b16ea51a19026fb8d1256a06af13af786 (commit)
       via  41a5e9b5f51633b6c20f3ab08977f2004d95bde5 (commit)
       via  f730da217c0ec2e72c37f4cc4f69ce7373c81791 (commit)
       via  821af530cfffe8573c97b4c98490dc4b2d2db931 (commit)
       via  badde008663e15e7d43c98b1a1fd14338922dd8f (commit)
       via  ae5ef4997e474092e1a07ef52ca2f02fb9368bf6 (commit)
      from  10dce70bf8a238702a5b81ffa8ea89edea9fc61f (commit)

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


- Log -----------------------------------------------------------------
commit 44e540648477217e37ba43f664124e0996b4496b
Author: Michael Adam <obnox at samba.org>
Date:   Mon May 7 11:51:28 2012 +0200

    New version 1.0.114.5.

commit e14a771817182547c6b72cab81f33c1469fad925
Author: Michael Adam <obnox at samba.org>
Date:   Wed Feb 23 17:39:57 2011 +0100

    recover: finish pending trans3 commits when a recovery is finished.
    
    When the end_recovery control is received, pending trans3 commits are
    finished. During the recovery, all the actions like persistent_callback
    and persistent_store_timeout had been disabled to let the recovery do
    its job. After the recover is completed, send the reply to the waiting
    clients.
    (cherry picked from commit f7dfeb7143f574c2434f7dd16917380dfd1f4f64)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 2a6e17e75f73e492d0da118ef00e8d37d6a7fa07
Author: Michael Adam <obnox at samba.org>
Date:   Wed Feb 23 17:38:40 2011 +0100

    persistent: add ctdb_persistent_finish_trans3_commits().
    
    This function walks all databases and checks for running trans3 commits.
    It sends replies to all of them (with error code) and ends them.
    To be called when a recovery finishes.
    (cherry picked from commit 70ba153b532528bdccea70c5ea28972257f384c1)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 2bbf862517e10f38a4271bfd1a62e788ce7b81a5
Author: Michael Adam <obnox at samba.org>
Date:   Wed Feb 23 17:37:42 2011 +0100

    daemon: correctly end a running trans3_commit if the client disconnects.
    (cherry picked from commit 9e0898db6df52d9bc799dd87bfea8c72d5f70ba0)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 57d4c6c50082603e8ddbe77f969dc0bffe8452f5
Author: Michael Adam <obnox at samba.org>
Date:   Wed Feb 23 17:35:27 2011 +0100

    persistent: add a client context to the persistent_stat and track the db_id
    
    The db_id is tracked in the client context as an indication that a
    transaction commit is in progress. This is cleared in the persistent_state
    talloc destructor.
    
    This is in order to properly treat running trans3_commits if the client
    disconnects.
    (cherry picked from commit e886ff24f4e3e250944289db95916b948893d26c)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 839e59a153f176089dc38e73ffdce8c05bf3d09b
Author: Michael Adam <obnox at samba.org>
Date:   Wed Feb 23 00:03:07 2011 +0100

    persistent: reject trans3_control when a commit is already active.
    
    This should actually never happen.
    (cherry picked from commit f416e76838fe2adf629d4356d1cc87054b1af164)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit bf26780c46a2fb9ce799bec6ea5e80abd0c1644e
Author: Michael Adam <obnox at samba.org>
Date:   Wed Feb 23 00:01:13 2011 +0100

    persistent: allocate the persistent state in the ctdb_db struct in trans3_commit
    
    Make sure that ctdb_db->persistent_state is correctly NULL-ed when
    the state is freed. This way, we can use ctdb_db->persistent_state
    as an indication for whether a transaction commit is currently
    running.
    (cherry picked from commit 761cb235193564a0f337d0308f0a9e6de0ef2710)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 86d02ccdac9873fff646c0aec1b7d9719332ba37
Author: Michael Adam <obnox at samba.org>
Date:   Wed Feb 23 00:23:18 2011 +0100

    persistent: add a ctdb_db context to the ctdb_persistent_state struct.
    (cherry picked from commit a14917c983c3b9bbbf38f5ddeecdbbe5bde32364)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 8070ab284e311d4eea9e46e0121944d4b7139b07
Author: Michael Adam <obnox at samba.org>
Date:   Wed Feb 23 00:00:04 2011 +0100

    persistent: add a ctdb_persistent_state member to the ctdb_db context.
    
    To be used for tracking running transaction commits through recoveries.
    
    (Backported from commit 1237e15df4af58a3d220eea42a4b75e21e65029f)

commit dce8248b16ea51a19026fb8d1256a06af13af786
Author: Michael Adam <obnox at samba.org>
Date:   Tue Feb 22 22:49:52 2011 +0100

    persistent_callback: print "no error message given" instead of "(null)"
    (cherry picked from commit d871a38978219e004833608c11aae98fe47614b9)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 41a5e9b5f51633b6c20f3ab08977f2004d95bde5
Author: Michael Adam <obnox at samba.org>
Date:   Tue Feb 22 22:47:30 2011 +0100

    persistent: reduce indentation for the finishing moves in ctdb_persistent_callback
    (cherry picked from commit 2c2d1646eb753ea9561f085bcb101153267b052b)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit f730da217c0ec2e72c37f4cc4f69ce7373c81791
Author: Michael Adam <obnox at samba.org>
Date:   Tue Feb 22 22:44:16 2011 +0100

    persistent: if a node failed to update_record, trigger a recovery
    
    and stop processing of the update_record replies in order to let
    the recovery finish the trans3_commit control.
    (cherry picked from commit cab95570dc1eefb08abbac5ae411c29f699b51cc)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit 821af530cfffe8573c97b4c98490dc4b2d2db931
Author: Michael Adam <obnox at samba.org>
Date:   Tue Feb 22 22:24:50 2011 +0100

    persistent_store_timout: do not really time out the trans3_commit control in recovery
    
    If a recovery was started, then all further processing of the update_record
    controls sent by the trans3_commit control and timing them out is disabled.
    The recovery should trigger sending the reply for the update record control
    when finished.
    (cherry picked from commit 983c1ca2e18ecd60fca69bfe9e116125cc695857)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit badde008663e15e7d43c98b1a1fd14338922dd8f
Author: Michael Adam <obnox at samba.org>
Date:   Tue Feb 22 22:24:50 2011 +0100

    persistent_callback: ignore the update-recordreturn code of remote node in recovery
    
    If a recovery was started, then all further processing of the update_record
    controls sent by the trans3_commit control is disabled. The recovery should
    trigger sending the reply for the update record control when finished.
    (cherry picked from commit 12cf0619255b12230843cd8bb49cbfdea376ca2f)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

commit ae5ef4997e474092e1a07ef52ca2f02fb9368bf6
Author: Rusty Russell <rusty at rustcorp.com.au>
Date:   Mon Jul 12 15:11:42 2010 +0930

    config: wrap iptables in flock to avoid concurrancy.
    
    When doing a releaseip event, we do them in parallel for all the separate
    IPs.  This creates a problem for iptables, which isn't reentrant, giving
    the strange message:
    	iptables encountered unknown error "18446744073709551615" while initializing table "filter"
    
    The worst possible symptom of this is that releaseip won't remove the rule
    which prevents us listening to clients during releaseip, and the node will be
    healthy but non-responsive.
    
    The simple workaround is to flock-wrap iptables.  Better would be to rework
    the code so we didn't need to use iptables in these paths.
    
    CQ:S1018353
    Signed-off-by: Rusty Russell <rusty at rustcorp.com.au>
    (cherry picked from commit 72d6914ee913272312d7b68f1be5ad05ad06587d)
    
    Signed-off-by: Michael Adam <obnox at samba.org>

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

Summary of changes:
 config/functions           |    6 ++
 include/ctdb_private.h     |    3 +
 packaging/RPM/ctdb.spec.in |    9 +++-
 server/ctdb_daemon.c       |    9 +++
 server/ctdb_persistent.c   |  137 +++++++++++++++++++++++++++++++++++++------
 server/ctdb_recover.c      |    2 +
 6 files changed, 146 insertions(+), 20 deletions(-)


Changeset truncated at 500 lines:

diff --git a/config/functions b/config/functions
index 2c78b39..ec2118a 100755
--- a/config/functions
+++ b/config/functions
@@ -761,6 +761,12 @@ ipv4_is_valid_addr()
 	return 0;
 }
 
+# iptables doesn't like being re-entered, so flock-wrap it.
+iptables()
+{
+	flock -w 30 /var/ctdb/iptables-ctdb.flock /sbin/iptables "$@"
+}
+
 ########################################################
 # load a site local config file
 ########################################################
diff --git a/include/ctdb_private.h b/include/ctdb_private.h
index bfef438..9c54e62 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -490,6 +490,7 @@ struct ctdb_db_context {
 	bool transaction_active;
 	struct ctdb_vacuum_handle *vacuum_handle;
 	char *unhealthy_reason;
+	struct ctdb_persistent_state *persistent_state;
 	struct _trbt_tree_t *delete_queue;
 	int (*ctdb_ltdb_store_fn)(struct ctdb_db_context *ctdb_db,
 				  TDB_DATA key,
@@ -1541,6 +1542,8 @@ int32_t ctdb_control_trans3_commit(struct ctdb_context *ctdb,
 				   struct ctdb_req_control *c,
 				   TDB_DATA recdata, bool *async_reply);
 
+void ctdb_persistent_finish_trans3_commits(struct ctdb_context *ctdb);
+
 int32_t ctdb_control_transaction_start(struct ctdb_context *ctdb, uint32_t id);
 int32_t ctdb_control_transaction_commit(struct ctdb_context *ctdb, uint32_t id);
 int32_t ctdb_control_transaction_cancel(struct ctdb_context *ctdb);
diff --git a/packaging/RPM/ctdb.spec.in b/packaging/RPM/ctdb.spec.in
index 9e63270..1c1f00f 100644
--- a/packaging/RPM/ctdb.spec.in
+++ b/packaging/RPM/ctdb.spec.in
@@ -4,7 +4,7 @@ Summary: Clustered TDB
 Vendor: Samba Team
 Packager: Samba Team <samba at samba.org>
 Name: ctdb
-Version: 1.0.114.4
+Version: 1.0.114.5
 Release: 1GITHASH
 Epoch: 0
 License: GNU GPL version 3
@@ -127,6 +127,13 @@ rm -rf $RPM_BUILD_ROOT
 %{_docdir}/ctdb/tests/bin/ctdb_transaction
 
 %changelog
+* Mon May 07 2012 : Version 1.0.114.5
+ - Rusty Russell: wrap iptables in flock to avoid concurrancy
+   (backported from master)
+ - Michael Adam: let recovery finish a transaction_commit
+   (backported from master)
+ - Michael Adam: let error in transaction_commit trigger a recovery
+   (backported from master)
 * Thu Jan 12 2012 : Version 1.0.114.4
  - Rusty Russell: crash fix in takeover
  - Rusty Russell: robustness fix regarding freeze vs vacuum
diff --git a/server/ctdb_daemon.c b/server/ctdb_daemon.c
index fdec5ab..1876f56 100644
--- a/server/ctdb_daemon.c
+++ b/server/ctdb_daemon.c
@@ -197,7 +197,16 @@ static int ctdb_client_destructor(struct ctdb_client *client)
 		DEBUG(DEBUG_ERR, (__location__ " client exit while transaction "
 				  "commit active. Forcing recovery.\n"));
 		client->ctdb->recovery_mode = CTDB_RECOVERY_ACTIVE;
+
+		/* legacy trans2 transaction state: */
 		ctdb_db->transaction_active = false;
+
+		/*
+		 * trans3 transaction state:
+		 *
+		 * The destructor sets the pointer to NULL.
+		 */
+		talloc_free(ctdb_db->persistent_state);
 	}
 
 	return 0;
diff --git a/server/ctdb_persistent.c b/server/ctdb_persistent.c
index d38aa8d..807b1c9 100644
--- a/server/ctdb_persistent.c
+++ b/server/ctdb_persistent.c
@@ -28,6 +28,8 @@
 
 struct ctdb_persistent_state {
 	struct ctdb_context *ctdb;
+	struct ctdb_db_context *ctdb_db; /* used by trans3_commit */
+	struct ctdb_client *client; /* used by trans3_commit */
 	struct ctdb_req_control *c;
 	const char *errormsg;
 	uint32_t num_pending;
@@ -52,27 +54,48 @@ static void ctdb_persistent_callback(struct ctdb_context *ctdb,
 {
 	struct ctdb_persistent_state *state = talloc_get_type(private_data, 
 							      struct ctdb_persistent_state);
+	enum ctdb_trans2_commit_error etype;
+
+	if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
+		DEBUG(DEBUG_INFO, ("ctdb_persistent_callback: ignoring reply "
+				   "during recovery\n"));
+		return;
+	}
 
 	if (status != 0) {
 		DEBUG(DEBUG_ERR,("ctdb_persistent_callback failed with status %d (%s)\n",
-			 status, errormsg));
+			 status, errormsg?errormsg:"no error message given"));
 		state->status = status;
 		state->errormsg = errormsg;
 		state->num_failed++;
+
+		/*
+		 * If a node failed to complete the update_record control,
+		 * then either a recovery is already running or something
+		 * bad is going on. So trigger a recovery and let the
+		 * recovery finish the transaction, sending back the reply
+		 * for the trans3_commit control to the client.
+		 */
+		ctdb->recovery_mode = CTDB_RECOVERY_ACTIVE;
+		return;
 	}
+
 	state->num_pending--;
-	if (state->num_pending == 0) {
-		enum ctdb_trans2_commit_error etype;
-		if (state->num_failed == state->num_sent) {
-			etype = CTDB_TRANS2_COMMIT_ALLFAIL;
-		} else if (state->num_failed != 0) {
-			etype = CTDB_TRANS2_COMMIT_SOMEFAIL;
-		} else {
-			etype = CTDB_TRANS2_COMMIT_SUCCESS;
-		}
-		ctdb_request_control_reply(state->ctdb, state->c, NULL, etype, state->errormsg);
-		talloc_free(state);
+
+	if (state->num_pending != 0) {
+		return;
+	}
+
+	if (state->num_failed == state->num_sent) {
+		etype = CTDB_TRANS2_COMMIT_ALLFAIL;
+	} else if (state->num_failed != 0) {
+		etype = CTDB_TRANS2_COMMIT_SOMEFAIL;
+	} else {
+		etype = CTDB_TRANS2_COMMIT_SUCCESS;
 	}
+
+	ctdb_request_control_reply(state->ctdb, state->c, NULL, etype, state->errormsg);
+	talloc_free(state);
 }
 
 /*
@@ -82,13 +105,53 @@ static void ctdb_persistent_store_timeout(struct event_context *ev, struct timed
 					 struct timeval t, void *private_data)
 {
 	struct ctdb_persistent_state *state = talloc_get_type(private_data, struct ctdb_persistent_state);
-	
+
+	if (state->ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
+		DEBUG(DEBUG_INFO, ("ctdb_persistent_store_timeout: ignoring "
+				   "timeout during recovery\n"));
+		return;
+	}
+
 	ctdb_request_control_reply(state->ctdb, state->c, NULL, CTDB_TRANS2_COMMIT_TIMEOUT, 
 				   "timeout in ctdb_persistent_state");
 
 	talloc_free(state);
 }
 
+/**
+ * Finish pending trans3 commit controls, i.e. send
+ * reply to the client. This is called by the end-recovery
+ * control to fix the situation when a recovery interrupts
+ * the usual porgress of a transaction.
+ */
+void ctdb_persistent_finish_trans3_commits(struct ctdb_context *ctdb)
+{
+	struct ctdb_db_context *ctdb_db;
+
+	if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
+		DEBUG(DEBUG_INFO, ("ctdb_persistent_store_timeout: ignoring "
+				   "timeout during recovery\n"));
+		return;
+	}
+
+	for (ctdb_db = ctdb->db_list; ctdb_db; ctdb_db = ctdb_db->next) {
+		struct ctdb_persistent_state *state;
+
+		if (ctdb_db->persistent_state == NULL) {
+			continue;
+		}
+
+		state = ctdb_db->persistent_state;
+
+		ctdb_request_control_reply(ctdb, state->c, NULL,
+					   CTDB_TRANS2_COMMIT_SOMEFAIL,
+					   "trans3 commit ended by recovery");
+
+		/* The destructor sets ctdb_db->persistent_state to NULL. */
+		talloc_free(state);
+	}
+}
+
 /*
   store a set of persistent records - called from a ctdb client when it has updated
   some records in a persistent database. The client will have the record
@@ -247,6 +310,18 @@ int32_t ctdb_control_trans2_commit(struct ctdb_context *ctdb,
 	return 0;
 }
 
+static int ctdb_persistent_state_destructor(struct ctdb_persistent_state *state)
+{
+	if (state->client != NULL) {
+		state->client->db_id = 0;
+	}
+
+	if (state->ctdb_db != NULL) {
+		state->ctdb_db->persistent_state = NULL;
+	}
+
+	return 0;
+}
 
 /*
  * Store a set of persistent records.
@@ -267,6 +342,21 @@ int32_t ctdb_control_trans3_commit(struct ctdb_context *ctdb,
 		return -1;
 	}
 
+	client = ctdb_reqid_find(ctdb, c->client_id, struct ctdb_client);
+	if (client == NULL) {
+		DEBUG(DEBUG_ERR,(__location__ " can not match persistent_store "
+				 "to a client. Returning error\n"));
+		return -1;
+	}
+
+	if (client->db_id != 0) {
+		DEBUG(DEBUG_ERR,(__location__ " ERROR: trans3_commit: "
+				 "client-db_id[0x%08x] != 0 "
+				 "(client_id[0x%08x]): trans3_commit active?\n",
+				 client->db_id, client->client_id));
+		return -1;
+	}
+
 	ctdb_db = find_ctdb_db(ctdb, m->db_id);
 	if (ctdb_db == NULL) {
 		DEBUG(DEBUG_ERR,(__location__ " ctdb_control_trans3_commit: "
@@ -274,18 +364,27 @@ int32_t ctdb_control_trans3_commit(struct ctdb_context *ctdb,
 		return -1;
 	}
 
-	client = ctdb_reqid_find(ctdb, c->client_id, struct ctdb_client);
-	if (client == NULL) {
-		DEBUG(DEBUG_ERR,(__location__ " can not match persistent_store "
-				 "to a client. Returning error\n"));
+	if (ctdb_db->persistent_state != NULL) {
+		DEBUG(DEBUG_ERR, (__location__ " Error: "
+				  "ctdb_control_trans3_commit "
+				  "called while a transaction commit is "
+				  "active. db_id[0x%08x]\n", m->db_id));
 		return -1;
 	}
 
-	state = talloc_zero(ctdb, struct ctdb_persistent_state);
-	CTDB_NO_MEMORY(ctdb, state);
+	ctdb_db->persistent_state = talloc_zero(ctdb_db,
+						struct ctdb_persistent_state);
+	CTDB_NO_MEMORY(ctdb, ctdb_db->persistent_state);
 
+	client->db_id = m->db_id;
+
+	state = ctdb_db->persistent_state;
 	state->ctdb = ctdb;
+	state->ctdb_db = ctdb_db;
 	state->c    = c;
+	state->client = client;
+
+	talloc_set_destructor(state, ctdb_persistent_state_destructor);
 
 	for (i = 0; i < ctdb->vnn_map->size; i++) {
 		struct ctdb_node *node = ctdb->nodes[ctdb->vnn_map->map[i]];
diff --git a/server/ctdb_recover.c b/server/ctdb_recover.c
index ed5c22b..e9e7659 100644
--- a/server/ctdb_recover.c
+++ b/server/ctdb_recover.c
@@ -964,6 +964,8 @@ int32_t ctdb_control_end_recovery(struct ctdb_context *ctdb,
 
 	DEBUG(DEBUG_NOTICE,("Recovery has finished\n"));
 
+	ctdb_persistent_finish_trans3_commits(ctdb);
+
 	state = talloc(ctdb, struct recovery_callback_state);
 	CTDB_NO_MEMORY(ctdb, state);
 


-- 
CTDB repository


More information about the samba-cvs mailing list