[SCM] CTDB repository - branch master updated - ctdb-1.0.105-82-gb796d73

Ronnie Sahlberg sahlberg at samba.org
Sun Dec 6 23:01:21 MST 2009


The branch, master has been updated
       via  b796d736946856abfbe53de95dfcd73072ee8ccd (commit)
       via  d971b2ca84c0451dc7e5acbf4a5ade06270a2044 (commit)
       via  59faf3f923a5989b5ee94ef02a12827412775bae (commit)
       via  c23d804165e84bdf95ba960c953c736d361011d7 (commit)
       via  428914377851a98b3fc893798783fbfebffc1c0d (commit)
       via  03a5bb727b9db1ba952632f08ceb5355f0df842d (commit)
       via  8aef46d2aab3efb322dda51eaa202653cefd5222 (commit)
       via  e5496a83ef4a01604195b27c4b97f50d4979510e (commit)
       via  fe68972eb9cf3aa1f16ba1aacf57ade5d66e647c (commit)
       via  90abc4ac7c16e854cf6e8f96b60a77bc92e35e07 (commit)
       via  4113385865f53a57b18ea752a7dad8a08bed588e (commit)
       via  b9882710e12f28c96a0af298e419160f00578241 (commit)
       via  574702f8d701fe3e493b31948420b2981eb36f93 (commit)
       via  41aa9bdfa2934f564bdc14374362437dfad0045f (commit)
       via  5a7c1e7f15693522bbf1c39a53be2304ece9a134 (commit)
       via  0e130d79ab71cf3aa65c40af91866823246a0283 (commit)
      from  5fc297a6bd49d9366703eef3edb9bdf0fe8505cc (commit)

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


- Log -----------------------------------------------------------------
commit b796d736946856abfbe53de95dfcd73072ee8ccd
Author: Michael Adam <obnox at samba.org>
Date:   Fri Dec 4 23:18:12 2009 +0100

    packaging: package tests/bin/ctdb_transaction under /usr/share/doc/tests/bin
    
    For testing/diagnostic purposes.
    
    Michael

commit d971b2ca84c0451dc7e5acbf4a5ade06270a2044
Author: Michael Adam <obnox at samba.org>
Date:   Fri Dec 4 00:19:44 2009 +0100

    client: improve two error messages in ctdb_transaction_commit().
    
    Michael

commit 59faf3f923a5989b5ee94ef02a12827412775bae
Author: Michael Adam <obnox at samba.org>
Date:   Fri Dec 4 00:06:34 2009 +0100

    server:trans2_commit: move the check for active recovery down.
    
    This needs to be done after the control-dispatcher:
    In the TRANS2_COMMIT control, the client->db_id needs
    to be set before bailing out, since otherwise the
    next TRANS2_COMMIT_RETRY will fail...
    
    Michael

commit c23d804165e84bdf95ba960c953c736d361011d7
Author: Michael Adam <obnox at samba.org>
Date:   Thu Dec 3 00:28:32 2009 +0100

    client: increase the number of commit retries 10-->100
    
    To cope with timeouts when recoveries and transactions collide.
    Maybe 100 is too high.
    
    Michael

commit 428914377851a98b3fc893798783fbfebffc1c0d
Author: Michael Adam <obnox at samba.org>
Date:   Thu Dec 3 00:27:34 2009 +0100

    client: untangle checks and produce more detailed error messages
    
    in ctdb_transaction_fetch_start
    
    Michael

commit 03a5bb727b9db1ba952632f08ceb5355f0df842d
Author: Michael Adam <obnox at samba.org>
Date:   Thu Dec 3 00:26:52 2009 +0100

    client: increase the rsn of the __transaction_lock__ when storing
    
    So that it is correctly handled by recoveries.
    Also explicitly set the dmaster field to the current node's pnn.
    
    Michael

commit 8aef46d2aab3efb322dda51eaa202653cefd5222
Author: Michael Adam <obnox at samba.org>
Date:   Fri Dec 4 11:21:29 2009 +0100

    recovery: add special pull-logic for persistent databases
    
    The decision mechanism which records of a persistent db
    are to be pulled into the recdb during recovery is now
    as follows:
    
    * Usually a record with the higher rsn than that already
      stored is taken. (Just as for normal tdbs.)
    
    * If a transaction is running on some node, then those
      nodes copies of all records are taken and are not
      overwritten later by other nodes' copies.
    
    In order to keep track of whether a record's copy was obtained
    from a node with a transaction running, the recovery mechanism
    misuses the ctdb tdb header field 'lacount' in the recdb.
    It is cleared later when pushing out the recdb database to the
    other nodes.
    
    This way, an incomplete transaction is not spoiled when
    a recovery interrupts and the replay should usually succeed
    (possibly after a few retries).
    
    Michael

commit e5496a83ef4a01604195b27c4b97f50d4979510e
Author: Michael Adam <obnox at samba.org>
Date:   Thu Dec 3 00:25:16 2009 +0100

    make ctdb_ctrl_transaction_active public.
    
    Michael

commit fe68972eb9cf3aa1f16ba1aacf57ade5d66e647c
Author: Michael Adam <obnox at samba.org>
Date:   Sun Nov 29 11:17:18 2009 +0100

    recovery: for persistent db's don't set the dmaster to the recmaster node number
    
    It is important to keep track of the dmaster (i.e. the node that last committed
    a transaction containing changes to this node).
    
    Michael

commit 90abc4ac7c16e854cf6e8f96b60a77bc92e35e07
Author: Michael Adam <obnox at samba.org>
Date:   Sun Nov 29 11:14:31 2009 +0100

    recovery: pass the persistent flag to recover_database()
    
    and further down to pull_remote_database(), pull_one_remote_database(),
    and push_recdb_database().
    
    This is in preparation of special handling of persistent databases
    during recoveries.
    
    Michael

commit 4113385865f53a57b18ea752a7dad8a08bed588e
Author: Michael Adam <obnox at samba.org>
Date:   Sun Nov 29 11:07:36 2009 +0100

    tests:ctdb_transaction: print an extra counters when a commit fails
    
    Michael

commit b9882710e12f28c96a0af298e419160f00578241
Author: Michael Adam <obnox at samba.org>
Date:   Sun Nov 29 10:38:33 2009 +0100

    client: in catdb, print the keyname first, and separate records by a blank line
    
    Michael

commit 574702f8d701fe3e493b31948420b2981eb36f93
Author: Michael Adam <obnox at samba.org>
Date:   Tue Dec 1 23:54:12 2009 +0100

    packaging: remove the lib/popt from the tarball in debian mode
    
    Debian CTDB packaging fails when this is included.
    
    Michael

commit 41aa9bdfa2934f564bdc14374362437dfad0045f
Author: Michael Adam <obnox at samba.org>
Date:   Tue Dec 1 23:51:51 2009 +0100

    packaging: rework maketarball.sh to accept an arbitrary githas to pack
    
    The githash can be specified through the environment variable "GITHASH"
    that can contain a commit hash or a tag name, e.g.
    
    The call syntax is now
    
    [GITHASH=xyz] [USE_GITHASH=yes/no] [DEBIAN_MODE=yes/no] maketarball.sh
    
    Michael

commit 5a7c1e7f15693522bbf1c39a53be2304ece9a134
Author: Michael Adam <obnox at samba.org>
Date:   Sun Nov 29 04:05:03 2009 +0100

    ctdb: add command "ctdb wipedb" to wipe the contents of an attached tdb
    
    Michael

commit 0e130d79ab71cf3aa65c40af91866823246a0283
Author: Michael Adam <obnox at samba.org>
Date:   Thu Oct 29 22:40:50 2009 +0100

    tests: turn printfs into DEBUG statements in the ctdb_transaction test
    
    Michael

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

Summary of changes:
 client/ctdb_client.c         |   44 +++++++++---
 include/ctdb.h               |    5 ++
 packaging/RPM/ctdb.spec.in   |    5 ++
 packaging/maketarball.sh     |   65 ++++++++++-------
 server/ctdb_persistent.c     |   10 ++--
 server/ctdb_recoverd.c       |   84 +++++++++++++++++++---
 tests/src/ctdb_transaction.c |   37 +++++-----
 tools/ctdb.c                 |  163 ++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 341 insertions(+), 72 deletions(-)


Changeset truncated at 500 lines:

diff --git a/client/ctdb_client.c b/client/ctdb_client.c
index 3e6b833..82f156d 100644
--- a/client/ctdb_client.c
+++ b/client/ctdb_client.c
@@ -1854,9 +1854,6 @@ static int dumpdb_fn(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data, voi
 	FILE *f = (FILE *)p;
 	struct ctdb_ltdb_header *h = (struct ctdb_ltdb_header *)data.dptr;
 
-	fprintf(f, "dmaster: %u\n", h->dmaster);
-	fprintf(f, "rsn: %llu\n", (unsigned long long)h->rsn);
-
 	fprintf(f, "key(%u) = \"", (unsigned)key.dsize);
 	for (i=0;i<key.dsize;i++) {
 		if (ISASCII(key.dptr[i])) {
@@ -1867,6 +1864,9 @@ static int dumpdb_fn(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data, voi
 	}
 	fprintf(f, "\"\n");
 
+	fprintf(f, "dmaster: %u\n", h->dmaster);
+	fprintf(f, "rsn: %llu\n", (unsigned long long)h->rsn);
+
 	fprintf(f, "data(%u) = \"", (unsigned)data.dsize);
 	for (i=sizeof(*h);i<data.dsize;i++) {
 		if (ISASCII(data.dptr[i])) {
@@ -1877,6 +1877,8 @@ static int dumpdb_fn(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data, voi
 	}
 	fprintf(f, "\"\n");
 
+	fprintf(f, "\n");
+
 	return 0;
 }
 
@@ -3146,9 +3148,9 @@ int ctdb_ctrl_getcapabilities(struct ctdb_context *ctdb, struct timeval timeout,
 /**
  * check whether a transaction is active on a given db on a given node
  */
-static int32_t ctdb_ctrl_transaction_active(struct ctdb_context *ctdb,
-					    uint32_t destnode,
-					    uint32_t db_id)
+int32_t ctdb_ctrl_transaction_active(struct ctdb_context *ctdb,
+				     uint32_t destnode,
+				     uint32_t db_id)
 {
 	int32_t status;
 	int ret;
@@ -3243,6 +3245,8 @@ again:
 	pid = getpid();
 	data.dptr = (unsigned char *)&pid;
 	data.dsize = sizeof(pid_t);
+	rh->header.rsn++;
+	rh->header.dmaster = ctdb_db->ctdb->pnn;
 	ret = ctdb_ltdb_store(ctdb_db, key, &(rh->header), data);
 	if (ret != 0) {
 		DEBUG(DEBUG_ERR, (__location__ " Failed to store pid in "
@@ -3261,13 +3265,25 @@ again:
 	}
 
 	ret = ctdb_ltdb_fetch(ctdb_db, key, &header, tmp_ctx, &data);
-	if (ret != 0 || header.dmaster != ctdb_db->ctdb->pnn) {
+	if (ret != 0) {
+		DEBUG(DEBUG_ERR,(__location__ " Failed to re-fetch transaction "
+				 "lock record inside transaction\n"));
+		tdb_transaction_cancel(ctdb_db->ltdb->tdb);
+		talloc_free(tmp_ctx);
+		goto again;
+	}
+
+	if (header.dmaster != ctdb_db->ctdb->pnn) {
+		DEBUG(DEBUG_DEBUG,(__location__ " not dmaster any more on "
+				   "transaction lock record\n"));
 		tdb_transaction_cancel(ctdb_db->ltdb->tdb);
 		talloc_free(tmp_ctx);
 		goto again;
 	}
 
 	if ((data.dsize != sizeof(pid_t)) || (*(pid_t *)(data.dptr) != pid)) {
+		DEBUG(DEBUG_DEBUG, (__location__ " my pid is not stored in "
+				    "the transaction lock record\n"));
 		tdb_transaction_cancel(ctdb_db->ltdb->tdb);
 		talloc_free(tmp_ctx);
 		goto again;
@@ -3523,7 +3539,7 @@ again:
 			}
 		}
 
-		if (++retries == 10) {
+		if (++retries == 100) {
 			DEBUG(DEBUG_ERR,(__location__ " Giving up transaction on db 0x%08x after %d retries failure_control=%u\n", 
 					 h->ctdb_db->db_id, retries, (unsigned)failure_control));
 			ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id, 
@@ -3534,7 +3550,11 @@ again:
 		}		
 
 		if (ctdb_replay_transaction(h) != 0) {
-			DEBUG(DEBUG_ERR,(__location__ " Failed to replay transaction\n"));
+			DEBUG(DEBUG_ERR, (__location__ " Failed to replay "
+					  "transaction on db 0x%08x, "
+					  "failure control =%u\n",
+					  h->ctdb_db->db_id,
+					  (unsigned)failure_control));
 			ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id, 
 				     failure_control, CTDB_CTRL_FLAG_NOREPLY, 
 				     tdb_null, NULL, NULL, NULL, NULL, NULL);		
@@ -3549,7 +3569,11 @@ again:
 	/* do the real commit locally */
 	ret = tdb_transaction_commit(h->ctdb_db->ltdb->tdb);
 	if (ret != 0) {
-		DEBUG(DEBUG_ERR,(__location__ " Failed to commit transaction\n"));
+		DEBUG(DEBUG_ERR, (__location__ " Failed to commit transaction "
+				  "on db id 0x%08x locally, "
+				  "failure_control=%u\n",
+				  h->ctdb_db->db_id,
+				  (unsigned)failure_control));
 		ctdb_control(ctdb, CTDB_CURRENT_NODE, h->ctdb_db->db_id, 
 			     failure_control, CTDB_CTRL_FLAG_NOREPLY, 
 			     tdb_null, NULL, NULL, NULL, NULL, NULL);		
diff --git a/include/ctdb.h b/include/ctdb.h
index db4c5cc..1d5d0d8 100644
--- a/include/ctdb.h
+++ b/include/ctdb.h
@@ -622,6 +622,11 @@ struct ctdb_client_control_state *ctdb_ctrl_getcapabilities_send(struct ctdb_con
 
 int ctdb_ctrl_getcapabilities_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *capabilities);
 
+
+int32_t ctdb_ctrl_transaction_active(struct ctdb_context *ctdb,
+				     uint32_t destnode,
+				     uint32_t db_id);
+
 struct ctdb_marshall_buffer *ctdb_marshall_add(TALLOC_CTX *mem_ctx, 
 					       struct ctdb_marshall_buffer *m,
 					       uint64_t db_id,
diff --git a/packaging/RPM/ctdb.spec.in b/packaging/RPM/ctdb.spec.in
index 90509d0..1cebcad 100644
--- a/packaging/RPM/ctdb.spec.in
+++ b/packaging/RPM/ctdb.spec.in
@@ -68,6 +68,9 @@ make DESTDIR=$RPM_BUILD_ROOT docdir=%{_docdir} install
 install -m644 config/ctdb.sysconfig $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/ctdb
 install -m755 config/ctdb.init $RPM_BUILD_ROOT%{initdir}/ctdb
 
+mkdir -p $RPM_BUILD_ROOT%{_docdir}/ctdb/tests/bin
+install -m755 tests/bin/ctdb_transaction $RPM_BUILD_ROOT%{_docdir}/ctdb/tests/bin
+
 # Remove "*.old" files
 find $RPM_BUILD_ROOT -name "*.old" -exec rm -f {} \;
 
@@ -117,6 +120,8 @@ rm -rf $RPM_BUILD_ROOT
 %{_includedir}/ctdb_private.h
 %{_libdir}/pkgconfig/ctdb.pc
 
+%{_docdir}/ctdb/tests/bin/ctdb_transaction
+
 %changelog
 * Wed Dec 2 2009 : Version 1.0.107
  - fix for rusty to solve a double-free that can happen when there are
diff --git a/packaging/maketarball.sh b/packaging/maketarball.sh
index 1ba353d..137f4d2 100755
--- a/packaging/maketarball.sh
+++ b/packaging/maketarball.sh
@@ -26,26 +26,22 @@
 
 DIRNAME=$(dirname $0)
 TOPDIR=${DIRNAME}/..
-RPMDIR=${DIRNAME}/RPM
-SPECFILE=${RPMDIR}/ctdb.spec
+
+TAR_PREFIX_TMP="ctdb-tmp"
+SPECFILE=/tmp/${TAR_PREFIX_TMP}/packaging/RPM/ctdb.spec
 SPECFILE_IN=${SPECFILE}.in
 
 EXTRA_SUFFIX="$1"
 
-GITHASH=".$(git log --pretty=format:%h -1)"
-
-if test "x$USE_GITHASH" = "xno" ; then
-	GITHASH=""
+# if no githash was specified on the commandline,
+# then use the current head
+if test x"$GITHASH" = "x" ; then
+	GITHASH="$(git log --pretty=format:%h -1)"
 fi
 
-sed -e s/GITHASH/${GITHASH}/g \
-	< ${SPECFILE_IN} \
-	> ${SPECFILE}
-
-VERSION=$(grep ^Version ${SPECFILE} | sed -e 's/^Version:\ \+//')${GITHASH}
-
-if [ "x${EXTRA_SUFFIX}" != "x" ]; then
-	VERSION="${VERSION}-${EXTRA_SUFFIX}"
+GITHASH_SUFFIX=".${GITHASH}"
+if test "x$USE_GITHASH" = "xno" ; then
+	GITHASH_SUFFIX=""
 fi
 
 if echo | gzip -c --rsyncable - > /dev/null 2>&1 ; then
@@ -54,20 +50,9 @@ else
 	GZIP="gzip -9"
 fi
 
-TAR_PREFIX="ctdb-${VERSION}"
-TAR_BASE="ctdb-${VERSION}"
-
-if test "x${DEBIAN_MODE}" = "xyes" ; then
-	TAR_PREFIX="ctdb-${VERSION}.orig"
-	TAR_BASE="ctdb_${VERSION}.orig"
-fi
-
-TAR_BALL=${TAR_BASE}.tar
-TAR_GZ_BALL=${TAR_BALL}.gz
-
 pushd ${TOPDIR}
-echo "Creating ${TAR_BASE}.tar.gz ... "
-git archive --prefix=${TAR_PREFIX}/ HEAD | ( cd /tmp ; tar xf - )
+echo "Creating tarball ... "
+git archive --prefix=${TAR_PREFIX_TMP}/ ${GITHASH} | ( cd /tmp ; tar xf - )
 RC=$?
 popd
 if [ $RC -ne 0 ]; then
@@ -75,7 +60,20 @@ if [ $RC -ne 0 ]; then
 	exit 1
 fi
 
-pushd /tmp/${TAR_PREFIX}
+sed -e s/GITHASH/${GITHASH_SUFFIX}/g \
+	< ${SPECFILE_IN} \
+	> ${SPECFILE}
+
+VERSION=$(grep ^Version ${SPECFILE} | sed -e 's/^Version:\ \+//')${GITHASH_SUFFIX}
+
+if [ "x${EXTRA_SUFFIX}" != "x" ]; then
+	VERSION="${VERSION}-${EXTRA_SUFFIX}"
+fi
+
+TAR_PREFIX="ctdb-${VERSION}"
+TAR_BASE="ctdb-${VERSION}"
+
+pushd /tmp/${TAR_PREFIX_TMP}
 ./autogen.sh
 RC=$?
 popd
@@ -84,6 +82,17 @@ if [ $RC -ne 0 ]; then
 	exit 1
 fi
 
+if test "x${DEBIAN_MODE}" = "xyes" ; then
+	TAR_PREFIX="ctdb-${VERSION}.orig"
+	TAR_BASE="ctdb_${VERSION}.orig"
+	rm -rf /tmp/${TAR_PREFIX_TMP}/lib/popt
+fi
+
+TAR_BALL=${TAR_BASE}.tar
+TAR_GZ_BALL=${TAR_BALL}.gz
+
+mv /tmp/${TAR_PREFIX_TMP} /tmp/${TAR_PREFIX}
+
 pushd /tmp
 tar cf ${TAR_BALL} ${TAR_PREFIX}
 RC=$?
diff --git a/server/ctdb_persistent.c b/server/ctdb_persistent.c
index 02ca7c8..7fc4587 100644
--- a/server/ctdb_persistent.c
+++ b/server/ctdb_persistent.c
@@ -105,11 +105,6 @@ int32_t ctdb_control_trans2_commit(struct ctdb_context *ctdb,
 	struct ctdb_marshall_buffer *m = (struct ctdb_marshall_buffer *)recdata.dptr;
 	struct ctdb_db_context *ctdb_db;
 
-	if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
-		DEBUG(DEBUG_INFO,("rejecting ctdb_control_trans2_commit when recovery active\n"));
-		return -1;
-	}
-
 	ctdb_db = find_ctdb_db(ctdb, m->db_id);
 	if (ctdb_db == NULL) {
 		DEBUG(DEBUG_ERR,(__location__ " ctdb_control_trans2_commit: "
@@ -189,6 +184,11 @@ int32_t ctdb_control_trans2_commit(struct ctdb_context *ctdb,
 		break;
 	}
 
+	if (ctdb->recovery_mode != CTDB_RECOVERY_NORMAL) {
+		DEBUG(DEBUG_INFO,("rejecting ctdb_control_trans2_commit when recovery active\n"));
+		return -1;
+	}
+
 	state = talloc_zero(ctdb, struct ctdb_persistent_state);
 	CTDB_NO_MEMORY(ctdb, state);
 
diff --git a/server/ctdb_recoverd.c b/server/ctdb_recoverd.c
index a227dba..071c0a3 100644
--- a/server/ctdb_recoverd.c
+++ b/server/ctdb_recoverd.c
@@ -521,13 +521,15 @@ static int create_missing_local_databases(struct ctdb_context *ctdb, struct ctdb
   pull the remote database contents from one node into the recdb
  */
 static int pull_one_remote_database(struct ctdb_context *ctdb, uint32_t srcnode, 
-				    struct tdb_wrap *recdb, uint32_t dbid)
+				    struct tdb_wrap *recdb, uint32_t dbid,
+				    bool persistent)
 {
 	int ret;
 	TDB_DATA outdata;
 	struct ctdb_marshall_buffer *reply;
 	struct ctdb_rec_data *rec;
 	int i;
+	int32_t transaction_active = 0;
 	TALLOC_CTX *tmp_ctx = talloc_new(recdb);
 
 	ret = ctdb_ctrl_pulldb(ctdb, srcnode, dbid, CTDB_LMASTER_ANY, tmp_ctx,
@@ -547,6 +549,18 @@ static int pull_one_remote_database(struct ctdb_context *ctdb, uint32_t srcnode,
 	}
 	
 	rec = (struct ctdb_rec_data *)&reply->data[0];
+
+	if (persistent) {
+		transaction_active = ctdb_ctrl_transaction_active(ctdb, srcnode,
+								  dbid);
+		if (transaction_active == -1) {
+			DEBUG(DEBUG_ERR, (__location__ " error calling "
+					  "ctdb_ctrl_transaction_active to node"
+					  " %u\n", srcnode));
+			talloc_free(tmp_ctx);
+			return -1;
+		}
+	}
 	
 	for (i=0;
 	     i<reply->count;
@@ -582,12 +596,42 @@ static int pull_one_remote_database(struct ctdb_context *ctdb, uint32_t srcnode,
 			}
 			header = *(struct ctdb_ltdb_header *)existing.dptr;
 			free(existing.dptr);
-			if (!(header.rsn < hdr->rsn ||
-			      (header.dmaster != ctdb->recovery_master && header.rsn == hdr->rsn))) {
-				continue;
+			if (!persistent) {
+				if (!(header.rsn < hdr->rsn ||
+				    (header.dmaster != ctdb->recovery_master && header.rsn == hdr->rsn)))
+				{
+					continue;
+				}
+			} else {
+				if (header.lacount == (uint32_t)-1) {
+					/*
+					 * skip record if the stored copy came
+					 * from a node with active transaction
+					 */
+					continue;
+				}
+
+				if ((header.rsn >= hdr->rsn) &&
+				    !transaction_active)
+				{
+					continue;
+				}
 			}
 		}
-		
+
+		if (persistent) {
+			/*
+			 * Misuse the lacount field to signal
+			 * that we got the record from a node
+			 * that has a transaction running.
+			 */
+			if (transaction_active) {
+				hdr->lacount = (uint32_t)-1;
+			} else {
+				hdr->lacount = 0;
+			}
+		}
+
 		if (tdb_store(recdb->tdb, key, data, TDB_REPLACE) != 0) {
 			DEBUG(DEBUG_CRIT,(__location__ " Failed to store record\n"));
 			talloc_free(tmp_ctx);
@@ -606,7 +650,8 @@ static int pull_one_remote_database(struct ctdb_context *ctdb, uint32_t srcnode,
 static int pull_remote_database(struct ctdb_context *ctdb,
 				struct ctdb_recoverd *rec, 
 				struct ctdb_node_map *nodemap, 
-				struct tdb_wrap *recdb, uint32_t dbid)
+				struct tdb_wrap *recdb, uint32_t dbid,
+				bool persistent)
 {
 	int j;
 
@@ -618,7 +663,7 @@ static int pull_remote_database(struct ctdb_context *ctdb,
 		if (nodemap->nodes[j].flags & NODE_FLAGS_INACTIVE) {
 			continue;
 		}
-		if (pull_one_remote_database(ctdb, nodemap->nodes[j].pnn, recdb, dbid) != 0) {
+		if (pull_one_remote_database(ctdb, nodemap->nodes[j].pnn, recdb, dbid, persistent) != 0) {
 			DEBUG(DEBUG_ERR,(__location__ " Failed to pull remote database from node %u\n", 
 				 nodemap->nodes[j].pnn));
 			ctdb_set_culprit_count(rec, nodemap->nodes[j].pnn, nodemap->num);
@@ -1039,6 +1084,7 @@ struct recdb_data {
 	struct ctdb_marshall_buffer *recdata;
 	uint32_t len;
 	bool failed;
+	bool persistent;
 };
 
 static int traverse_recdb(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *p)
@@ -1054,7 +1100,16 @@ static int traverse_recdb(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data,
 
 	/* update the dmaster field to point to us */
 	hdr = (struct ctdb_ltdb_header *)data.dptr;
-	hdr->dmaster = params->ctdb->pnn;
+	if (!params->persistent) {
+		hdr->dmaster = params->ctdb->pnn;
+	} else {
+		/*
+		 * Clear the lacount field that had been misused
+		 * when pulling the db in order to keep track of
+		 * whether the node had a transaction running.
+		 */
+		hdr->lacount = 0;
+	}
 
 	/* add the record to the blob ready to send to the nodes */
 	rec = ctdb_marshall_record(params->recdata, 0, key, NULL, data);
@@ -1081,6 +1136,7 @@ static int traverse_recdb(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data,
   push the recdb database out to all nodes
  */
 static int push_recdb_database(struct ctdb_context *ctdb, uint32_t dbid,
+			       bool persistent,
 			       struct tdb_wrap *recdb, struct ctdb_node_map *nodemap)
 {
 	struct recdb_data params;
@@ -1101,6 +1157,7 @@ static int push_recdb_database(struct ctdb_context *ctdb, uint32_t dbid,
 	params.recdata = recdata;
 	params.len = offsetof(struct ctdb_marshall_buffer, data);
 	params.failed = false;
+	params.persistent = persistent;
 
 	if (tdb_traverse_read(recdb->tdb, traverse_recdb, &params) == -1) {
 		DEBUG(DEBUG_ERR,(__location__ " Failed to traverse recdb database\n"));
@@ -1149,6 +1206,7 @@ static int push_recdb_database(struct ctdb_context *ctdb, uint32_t dbid,
 static int recover_database(struct ctdb_recoverd *rec, 
 			    TALLOC_CTX *mem_ctx,
 			    uint32_t dbid,
+			    bool persistent,
 			    uint32_t pnn, 
 			    struct ctdb_node_map *nodemap,
 			    uint32_t transaction_id)
@@ -1166,7 +1224,7 @@ static int recover_database(struct ctdb_recoverd *rec,
 	}
 
 	/* pull all remote databases onto the recdb */
-	ret = pull_remote_database(ctdb, rec, nodemap, recdb, dbid);
+	ret = pull_remote_database(ctdb, rec, nodemap, recdb, dbid, persistent);
 	if (ret != 0) {
 		DEBUG(DEBUG_ERR, (__location__ " Unable to pull remote database 0x%x\n", dbid));
 		return -1;
@@ -1194,7 +1252,7 @@ static int recover_database(struct ctdb_recoverd *rec,
 	
 	/* push out the correct database. This sets the dmaster and skips 
 	   the empty records */
-	ret = push_recdb_database(ctdb, dbid, recdb, nodemap);
+	ret = push_recdb_database(ctdb, dbid, persistent, recdb, nodemap);
 	if (ret != 0) {
 		talloc_free(recdb);
 		return -1;
@@ -1360,7 +1418,11 @@ static int do_recovery(struct ctdb_recoverd *rec,
 	DEBUG(DEBUG_NOTICE,(__location__ " started transactions on all nodes\n"));
 
 	for (i=0;i<dbmap->num;i++) {
-		if (recover_database(rec, mem_ctx, dbmap->dbs[i].dbid, pnn, nodemap, generation) != 0) {
+		ret = recover_database(rec, mem_ctx,
+				       dbmap->dbs[i].dbid,
+				       dbmap->dbs[i].persistent,
+				       pnn, nodemap, generation);
+		if (ret != 0) {
 			DEBUG(DEBUG_ERR, (__location__ " Failed to recover database 0x%x\n", dbmap->dbs[i].dbid));
 			return -1;
 		}
diff --git a/tests/src/ctdb_transaction.c b/tests/src/ctdb_transaction.c
index c747e1a..2144719 100644
--- a/tests/src/ctdb_transaction.c
+++ b/tests/src/ctdb_transaction.c
@@ -133,32 +133,32 @@ static void test_store_records(struct ctdb_context *ctdb, struct event_context *
 
 
 		if (!no_trans) {
-			if (verbose) printf("starting transaction\n");
+			if (verbose) DEBUG(DEBUG_ERR, ("starting transaction\n"));
 			h = ctdb_transaction_start(ctdb_db, tmp_ctx);
 			if (h == NULL) {
-				printf("Failed to start transaction on node %d\n",
-				       ctdb_get_pnn(ctdb));
+				DEBUG(DEBUG_ERR, ("Failed to start transaction on node %d\n",
+				       ctdb_get_pnn(ctdb)));
 				talloc_free(tmp_ctx);
 				return;
 			}
-			if (verbose) printf("transaction started\n");
+			if (verbose) DEBUG(DEBUG_ERR, ("transaction started\n"));
 			do_sleep(delay);
 
-			if (verbose) printf("calling transaction_fetch\n");
+			if (verbose) DEBUG(DEBUG_ERR, ("calling transaction_fetch\n"));


-- 
CTDB repository


More information about the samba-cvs mailing list