[SCM] CTDB repository - branch 2.5 updated - ctdb-2.5.4-71-g2c5e86f

Amitay Isaacs amitay at samba.org
Sun Feb 8 21:03:08 MST 2015


The branch, 2.5 has been updated
       via  2c5e86fab6b1d178a717a5f023e3ba346342f94e (commit)
       via  3f8f67dcb275afb7bfcb5196405ec556404d6032 (commit)
       via  a78b47f4e34d8ee30805f4385966418279f6fb40 (commit)
       via  41f114c4ab59bd4c0c10f3f6f1538794f698b24c (commit)
       via  4564bf0512cb892652a6d4c4dace84c0ac0bb95b (commit)
       via  20714b4bdd5321ae7d47927fd625e97ec4f3a6a6 (commit)
       via  cf76f6398adc3a78ac44d11e869b9a1105023a51 (commit)
       via  0ddf428dc9c9e10a8140844f65a1a087ff01c79c (commit)
       via  05c6c86eea80b54e0e4bea7d2d4169ab5f1ef564 (commit)
       via  25645ee2fc7e2c69f23ded69a8d1c1d51224213c (commit)
       via  8146d7e105f12f0a81822f214f50733f3ceed6d0 (commit)
      from  1dd1b97bef36e2409f633e9c46fa5f9829ebcc1a (commit)

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


- Log -----------------------------------------------------------------
commit 2c5e86fab6b1d178a717a5f023e3ba346342f94e
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Feb 2 21:21:20 2015 +1100

    tests: Add new "ctdb setreclock" test
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>
    
    Autobuild-User(master): Amitay Isaacs <amitay at samba.org>
    Autobuild-Date(master): Wed Feb  4 05:40:55 CET 2015 on sn-devel-104
    
    (Imported from commit 0e89d586b2b7fa6a165a49862d2dce0d13f8b157)

commit 3f8f67dcb275afb7bfcb5196405ec556404d6032
Author: Martin Schwenke <martin at meltin.net>
Date:   Wed Jan 28 18:51:42 2015 +1100

    daemon: Fix SET_RECLOCK_FILE regression
    
    If the recovery lock file is unset then this dereferences a NULL
    pointer.  The regression is due to commit
    6f1ac7af0f87d85402d708231e45a69713bba026.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>
    
    (Imported from commit 5e00673f2d95b6257a05324d2ae068004e29ff85)

commit a78b47f4e34d8ee30805f4385966418279f6fb40
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Dec 30 16:04:00 2014 +1100

    scripts: Call iptables/ip6tables directly from iptables_wrapper
    
    Drops the iptables() and ip6tables() functions and, hence, the
    hardcoding of paths /sbin/iptables and /sbin/ip6tables.  The latter
    avoids problems on openSUSE where (for example) /usr/sbin/iptables is
    used instead.
    
    This means that locking around ip*tables commands is only done when
    iptables_wrapper is called directly.  This is fine because the only
    conflict is when "releaseip" or "takeip"/"updateip" events are run in
    parallel.  The other uses in 11.natgw and 70.iscsi are in events where
    there will be no collisions.
    
    Making 11.natgw support IPv6 is unnecessary.  Just put a static IPv6
    address on each interface - they're plentiful.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>
    
    Autobuild-User(master): Amitay Isaacs <amitay at samba.org>
    Autobuild-Date(master): Wed Jan 28 08:29:55 CET 2015 on sn-devel-104
    
    (Imported from commit ab51f283e7a7f4fc82a94d39e7bb3a68e8aac554)

commit 41f114c4ab59bd4c0c10f3f6f1538794f698b24c
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Dec 30 17:07:09 2014 +1100

    scripts: Error message, comment and whitespace cleanups
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>
    
    (Imported from commit 9b67c1fa3748678552400a81172d124e59d5eb79)

commit 4564bf0512cb892652a6d4c4dace84c0ac0bb95b
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Dec 30 17:03:46 2014 +1100

    scripts: iSCSI eventscript should fail when PNN can't be determined
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>
    
    (Imported from commit 1a5414b6d25ed1b1abdafd8594183b84af33a6fb)

commit 20714b4bdd5321ae7d47927fd625e97ec4f3a6a6
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Dec 30 17:01:21 2014 +1100

    scripts: Make 70.iscsi IPv6-aware
    
    Block iSCSI port for families of all address the node is configured to
    host.
    
    Could just unconditional add blocking using ip6tables instead.
    However, this would produce errors when no IPv6 public addresses are
    configured and ip6tables is not installed.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Amitay Isaacs <amitay at gmail.com>
    
    (Imported from commit d1bd26e5eb25aee2ce82ef178692a64073a99aa0)

commit cf76f6398adc3a78ac44d11e869b9a1105023a51
Author: Michael Adam <obnox at samba.org>
Date:   Fri Jan 9 00:10:37 2015 +0100

    improve helpfulness of debug message when taking reclock fails
    
    Print out the errno if the fcntl call.
    
    Signed-off-by: Michael Adam <obnox at samba.org>
    Reviewed-by: Richard Sharpe <rsharpe at samba.org>
    
    Autobuild-User(master): Michael Adam <obnox at samba.org>
    Autobuild-Date(master): Fri Jan  9 04:25:02 CET 2015 on sn-devel-104
    
    (Imported from commit a59fb322d60b7152110cc0638dd9b76dd259ac15)

commit 0ddf428dc9c9e10a8140844f65a1a087ff01c79c
Author: Martin Schwenke <martin at meltin.net>
Date:   Tue Dec 9 13:40:23 2014 +1100

    daemon: Handle out-of-memory when setting recovery lock file
    
    Log a message when the reclock file actually changes and avoid a
    memory allocation when it doesn't change.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    (Imported from commit 6f1ac7af0f87d85402d708231e45a69713bba026)

commit 05c6c86eea80b54e0e4bea7d2d4169ab5f1ef564
Author: Martin Schwenke <martin at meltin.net>
Date:   Fri Dec 19 14:19:32 2014 +1100

    scripts: Don't use the GNU awk gensub() function
    
    This is a gawk extension and can't be used reliably if just running
    "awk".  It is simple enough to switch to using the standard sub() and
    gsub() functions.
    
    The alternative is to switch to explicitly running "gawk".  However,
    although the eventscripts aren't exactly portable, it is probably
    better to move closer to portability than further away.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    (Imported from commit 4638010abb116aed0c180207aaa11475277aecb7)

commit 25645ee2fc7e2c69f23ded69a8d1c1d51224213c
Author: Martin Schwenke <martin at meltin.net>
Date:   Mon Dec 1 12:21:16 2014 +1100

    scripts: Try to deal with Ubuntu having /usr/sbin/service
    
    Falling back to running the initscript doesn't work because it detects
    that upstart is being used and fails.  This was observed when trying
    to start winbind on Ubuntu 11.04.
    
    Signed-off-by: Martin Schwenke <martin at meltin.net>
    Reviewed-by: Michael Adam <obnox at samba.org>
    
    (Imported from commit a5c5eee7d186d938c5b458cb6dbf0c78cb548b63)

commit 8146d7e105f12f0a81822f214f50733f3ceed6d0
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Thu Dec 11 13:16:47 2014 +1100

    daemon: Use correct tdb flags when enabling robust mutex support
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=11000
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>
    
    (Imported from commit e0bf5dd4566785b41ad1fa0492a9f215639f1685)

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

Summary of changes:
 client/ctdb_client.c                 |  30 +++++++--
 config/events.d/70.iscsi             |  57 ++++++++++++-----
 config/functions                     |  25 ++++----
 config/statd-callout                 |   4 +-
 server/ctdb_control.c                |  35 ++++++++---
 server/ctdb_lock.c                   |  30 +++++++--
 server/ctdb_lock_helper.c            |  28 ++++++---
 server/ctdb_ltdb_server.c            |   4 +-
 server/ctdb_recover.c                |   6 +-
 tests/complex/18_ctdb_reloadips.sh   |   2 +-
 tests/eventscripts/etc-ctdb/rc.local |   4 +-
 tests/scripts/integration.bash       |   5 +-
 tests/simple/35_set_recmaster.sh     | 117 +++++++++++++++++++++++++++++++++++
 13 files changed, 280 insertions(+), 67 deletions(-)
 create mode 100755 tests/simple/35_set_recmaster.sh


Changeset truncated at 500 lines:

diff --git a/client/ctdb_client.c b/client/ctdb_client.c
index df57302..4553113 100644
--- a/client/ctdb_client.c
+++ b/client/ctdb_client.c
@@ -1928,7 +1928,7 @@ int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32
 
 #ifdef TDB_MUTEX_LOCKING
 	if (!persistent && ctdb->tunable.mutex_enabled == 1) {
-		tdb_flags |= TDB_MUTEX_LOCKING;
+		tdb_flags |= (TDB_MUTEX_LOCKING | TDB_CLEAR_IF_FIRST);
 	}
 #endif
 
@@ -2055,6 +2055,9 @@ struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb,
 	TDB_DATA data;
 	int ret;
 	int32_t res;
+#ifdef TDB_MUTEX_LOCKING
+	uint32_t mutex_enabled = 0;
+#endif
 
 	ctdb_db = ctdb_db_handle(ctdb, name);
 	if (ctdb_db) {
@@ -2080,8 +2083,18 @@ struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb,
 	}
 
 #ifdef TDB_MUTEX_LOCKING
-	if (!persistent && ctdb->tunable.mutex_enabled == 1) {
-		tdb_flags |= TDB_MUTEX_LOCKING;
+	if (!persistent) {
+		ret = ctdb_ctrl_get_tunable(ctdb, timeval_current_ofs(3,0),
+					    CTDB_CURRENT_NODE,
+					    "TDBMutexEnabled",
+					    &mutex_enabled);
+		if (ret != 0) {
+			DEBUG(DEBUG_WARNING, ("Assuming no mutex support.\n"));
+		}
+
+		if (mutex_enabled == 1) {
+			tdb_flags |= (TDB_MUTEX_LOCKING | TDB_CLEAR_IF_FIRST);
+		}
 	}
 #endif
 
@@ -2105,7 +2118,16 @@ struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb,
 		return NULL;
 	}
 
-	tdb_flags = persistent?TDB_DEFAULT:TDB_NOSYNC;
+	if (persistent) {
+		tdb_flags = TDB_DEFAULT;
+	} else {
+		tdb_flags = TDB_NOSYNC;
+#ifdef TDB_MUTEX_LOCKING
+		if (mutex_enabled) {
+			tdb_flags |= (TDB_MUTEX_LOCKING | TDB_CLEAR_IF_FIRST);
+		}
+#endif
+	}
 	if (ctdb->valgrinding) {
 		tdb_flags |= TDB_NOMMAP;
 	}
diff --git a/config/events.d/70.iscsi b/config/events.d/70.iscsi
index 4627822..42d261b 100755
--- a/config/events.d/70.iscsi
+++ b/config/events.d/70.iscsi
@@ -1,5 +1,6 @@
 #!/bin/sh
-# ctdb event script for TGTD based iSCSI
+
+# CTDB event script for TGTD based iSCSI
 
 [ -n "$CTDB_BASE" ] || \
     export CTDB_BASE=$(cd -P $(dirname "$0") ; dirname "$PWD")
@@ -19,42 +20,64 @@ is_ctdb_managed_service || exit 0
 	exit 0
 }
 
-case "$1" in 
+case "$1" in
     ipreallocated)
-	# block the iscsi port
-	iptables -I INPUT 1 -p tcp --dport 3260 -j DROP
-	
-	# shut down the iscsi service
+	all_ips=$(ctdb -X ip | tail -n +2)
+
+	# Block the iSCSI port.  Only block for the address families
+	# we have configured.  This copes with, for example, ip6tables
+	# being unavailable on an IPv4-only system.
+	have_ipv4=false
+	have_ipv6=false
+	while IFS='|' read x ip pnn x ; do
+	    case "$ip" in
+		*:*) have_ipv6=true ;;
+		*)   have_ipv4=true ;;
+		esac
+	done <<EOF
+$all_ips
+EOF
+	if $have_ipv4 ; then
+	    iptables -I INPUT 1 -p tcp --dport 3260 -j DROP
+	fi
+	if $have_ipv6 ; then
+	    ip6tables -I INPUT 1 -p tcp --dport 3260 -j DROP
+	fi
+
+	# Stop iSCSI daemon
 	killall -9 tgtd >/dev/null 2>/dev/null
 
+	# What node is this?
 	this_node=$(ctdb xpnn | sed -e 's at PNN:@@')
-	if [ -z "$this_node" ] ; then
-		echo "Failed to get node pnn"
-		exit 0
-	fi
+	[ -n "$this_node" ] || die "Failed to get node pnn"
 
-	# start the iscsi daemon
-	tgtd >/dev/null 2>/dev/null
+	# Start iSCSI daemon
+	tgtd >/dev/null 2>&1
 
-	ips=$(ctdb -X ip | awk -F'|' -v pnn=$this_node '$3 == pnn {print $2}')
+	# Run a script for each currently hosted public IP address
+	ips=$(echo "$all_ips" | awk -F'|' -v pnn=$this_node '$3 == pnn {print $2}')
 	for ip in $ips ; do
 	    script="${CTDB_START_ISCSI_SCRIPTS}/${ip}.sh"
 	    if [ -x "$script" ] ; then
-		echo "Starting iscsi service for public address ${ip}"
+		echo "Starting iSCSI service for public address ${ip}"
 		"$script"
 	    fi
 	done
 
-	# remove all iptables rules
+	# Unblock iSCSI port.  These can be unconditional (compared to
+	# blocking above), since errors are redirected.
 	while iptables -D INPUT -p tcp --dport 3260 -j DROP >/dev/null 2>&1 ; do
 	    :
 	done
+	while ip6tables -D INPUT -p tcp --dport 3260 -j DROP >/dev/null 2>&1 ; do
+	    :
+	done
 
 	;;
 
     shutdown)
-	# shutdown iscsi when ctdb goes down
-	killall -9 tgtd >/dev/null 2>/dev/null
+	# Shutdown iSCSI daemon when ctdb goes down
+	killall -9 tgtd >/dev/null 2>&1
 	;;
 
     monitor)
diff --git a/config/functions b/config/functions
index ef05e35..a41c195 100755
--- a/config/functions
+++ b/config/functions
@@ -161,6 +161,8 @@ _service ()
 
   if [ -x /sbin/service ]; then
       $_nice /sbin/service "$_service_name" "$_op"
+  elif [ -x /usr/sbin/service ]; then
+      $_nice /usr/sbin/service "$_service_name" "$_op"
   elif [ -x $CTDB_ETCDIR/init.d/$_service_name ]; then
       $_nice $CTDB_ETCDIR/init.d/$_service_name "$_op"
   elif [ -x $CTDB_ETCDIR/rc.d/init.d/$_service_name ]; then
@@ -903,7 +905,7 @@ delete_ip_from_iface()
     }
 }
 
-# If the given IP is hosted then print 2 items: maskbits and iface 
+# If the given IP is hosted then print 2 items: maskbits and iface
 ip_maskbits_iface ()
 {
     _addr="$1"
@@ -915,8 +917,9 @@ ip_maskbits_iface ()
 
     ip addr show to "${_addr}/${_bits}" 2>/dev/null | \
 	awk -v family="${_family}" \
-	    'NR == 1 { iface = gensub(":$", "", 1, $2) } \
-             $1 ~ /inet/ { print gensub(".*/", "", 1, $2), iface, family }'
+	    'NR == 1 { iface = $2; sub(":$", "", iface) } \
+             $1 ~ /inet/ { mask = $2; sub(".*/", "", mask); \
+                           print mask, iface, family }'
 }
 
 drop_ip ()
@@ -1387,23 +1390,17 @@ ctdb_standard_event_handler ()
     esac
 }
 
-# iptables doesn't like being re-entered, so flock-wrap it.
-iptables ()
-{
-	flock -w 30 $CTDB_VARDIR/iptables-ctdb.flock /sbin/iptables "$@"
-}
-ip6tables ()
-{
-	flock -w 30 $CTDB_VARDIR/iptables-ctdb.flock /sbin/ip6tables "$@"
-}
 iptables_wrapper ()
 {
     _family="$1" ; shift
     if [ "$_family" = "inet6" ] ; then
-	ip6tables "$@"
+	_iptables_cmd="ip6tables"
     else
-	iptables "$@"
+	_iptables_cmd="iptables"
     fi
+
+    # iptables doesn't like being re-entered, so flock-wrap it.
+    flock -w 30 "${CTDB_VARDIR}/iptables-ctdb.flock" "$_iptables_cmd" "$@"
 }
 
 # AIX (and perhaps others?) doesn't have mktemp
diff --git a/config/statd-callout b/config/statd-callout
index 5e8eb0e..e2a955e 100755
--- a/config/statd-callout
+++ b/config/statd-callout
@@ -145,7 +145,9 @@ case "$1" in
 	#   server-IP client-IP
 	# but only for the server-IPs that are hosted on this node.
 	sed_expr=$(ctdb ip | tail -n +2 |
-	    awk -v pnn=$pnn 'pnn == $2 { printf "s/^key.*=.*statd-state@\\(%s\\)@\\([^\"]*\\).*/\\1 \\2/p\n", gensub(/\./, "\\\\.", "g", $1) }')
+	    awk -v pnn=$pnn 'pnn == $2 { \
+                ip = $1; gsub(/\./, "\\\\.", ip); \
+                printf "s/^key.*=.*statd-state@\\(%s\\)@\\([^\"]*\\).*/\\1 \\2/p\n", ip }')
 
 	statd_state=$(ctdb catdb ctdb.tdb | sed -n "$sed_expr" | sort)
 	[ -n "$statd_state" ] || exit 0
diff --git a/server/ctdb_control.c b/server/ctdb_control.c
index 1f9e4bc..7cd5795 100644
--- a/server/ctdb_control.c
+++ b/server/ctdb_control.c
@@ -519,17 +519,36 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
 			outdata->dsize = strlen(ctdb->recovery_lock_file) + 1;
 		}
 		return 0;
-	case CTDB_CONTROL_SET_RECLOCK_FILE:
-		ctdb->tunable.verify_recovery_lock = 0;
-		if (ctdb->recovery_lock_file != NULL) {
-			talloc_free(ctdb->recovery_lock_file);
-			ctdb->recovery_lock_file = NULL;
+	case CTDB_CONTROL_SET_RECLOCK_FILE: {
+		char *t;
+
+		if (indata.dsize == 0) {
+			TALLOC_FREE(ctdb->recovery_lock_file);
+			return 0;
+		}
+
+		/* Return silent success if unchanged.  Recovery
+		 * master updates all nodes on each recovery - we
+		 * don't need the extra memory allocation or log
+		 * message each time. */
+		if (ctdb->recovery_lock_file != NULL &&
+		    strcmp(discard_const(indata.dptr),
+			   ctdb->recovery_lock_file) == 0) {
+			return 0;
 		}
-		if (indata.dsize > 0) {
-			ctdb->recovery_lock_file = talloc_strdup(ctdb, discard_const(indata.dptr));
-			ctdb->tunable.verify_recovery_lock = 1;
+
+		t = talloc_strdup(ctdb, discard_const(indata.dptr));
+		if (t == NULL) {
+			DEBUG(DEBUG_ERR, ("Out of memory in SET_RECLOCK_FILE\n"));
+			return -1;
 		}
+
+		talloc_free(ctdb->recovery_lock_file);
+		ctdb->recovery_lock_file = t;
+		DEBUG(DEBUG_NOTICE, ("Updated recovery lock file to %s\n", t));
+
 		return 0;
+	}
 
 	case CTDB_CONTROL_STOP_NODE:
 		CHECK_CONTROL_DATA_SIZE(0);
diff --git a/server/ctdb_lock.c b/server/ctdb_lock.c
index 8292599..8638cd7 100644
--- a/server/ctdb_lock.c
+++ b/server/ctdb_lock.c
@@ -544,11 +544,23 @@ static int db_count_handler(struct ctdb_db_context *ctdb_db, uint32_t priority,
 {
 	int *count = (int *)private_data;
 
-	(*count)++;
+	(*count) += 2;
 
 	return 0;
 }
 
+static int db_flags(struct ctdb_db_context *ctdb_db)
+{
+	int tdb_flags = TDB_DEFAULT;
+
+#ifdef TDB_MUTEX_LOCKING
+	if (!ctdb_db->persistent && ctdb_db->ctdb->tunable.mutex_enabled) {
+		tdb_flags = (TDB_MUTEX_LOCKING | TDB_CLEAR_IF_FIRST);
+	}
+#endif
+	return tdb_flags;
+}
+
 struct db_namelist {
 	const char **names;
 	int n;
@@ -560,7 +572,9 @@ static int db_name_handler(struct ctdb_db_context *ctdb_db, uint32_t priority,
 	struct db_namelist *list = (struct db_namelist *)private_data;
 
 	list->names[list->n] = talloc_strdup(list->names, ctdb_db->db_path);
-	list->n++;
+	list->names[list->n+1] = talloc_asprintf(list->names, "0x%x",
+						 db_flags(ctdb_db));
+	list->n += 2;
 
 	return 0;
 }
@@ -577,11 +591,11 @@ static bool lock_helper_args(TALLOC_CTX *mem_ctx,
 
 	switch (lock_ctx->type) {
 	case LOCK_RECORD:
-		nargs = 5;
+		nargs = 6;
 		break;
 
 	case LOCK_DB:
-		nargs = 4;
+		nargs = 5;
 		break;
 
 	case LOCK_ALLDB_PRIO:
@@ -612,16 +626,20 @@ static bool lock_helper_args(TALLOC_CTX *mem_ctx,
 	case LOCK_RECORD:
 		args[2] = talloc_strdup(args, "RECORD");
 		args[3] = talloc_strdup(args, lock_ctx->ctdb_db->db_path);
+		args[4] = talloc_asprintf(args, "0x%x",
+					  db_flags(lock_ctx->ctdb_db));
 		if (lock_ctx->key.dsize == 0) {
-			args[4] = talloc_strdup(args, "NULL");
+			args[5] = talloc_strdup(args, "NULL");
 		} else {
-			args[4] = hex_encode_talloc(args, lock_ctx->key.dptr, lock_ctx->key.dsize);
+			args[5] = hex_encode_talloc(args, lock_ctx->key.dptr, lock_ctx->key.dsize);
 		}
 		break;
 
 	case LOCK_DB:
 		args[2] = talloc_strdup(args, "DB");
 		args[3] = talloc_strdup(args, lock_ctx->ctdb_db->db_path);
+		args[4] = talloc_asprintf(args, "0x%x",
+					  db_flags(lock_ctx->ctdb_db));
 		break;
 
 	case LOCK_ALLDB_PRIO:
diff --git a/server/ctdb_lock_helper.c b/server/ctdb_lock_helper.c
index f164769..c68e5e7 100644
--- a/server/ctdb_lock_helper.c
+++ b/server/ctdb_lock_helper.c
@@ -36,17 +36,21 @@ static void send_result(int fd, char result)
 static void usage(void)
 {
 	fprintf(stderr, "\n");
-	fprintf(stderr, "Usage: %s <log-fd> <ctdbd-pid> <output-fd> RECORD <db-path> <db-key>\n",
+	fprintf(stderr, "Usage: %s <log-fd> <ctdbd-pid> <output-fd> RECORD <db-path> <db-flags> <db-key>\n",
 		progname);
-	fprintf(stderr, "       %s <log-fd> <ctdbd-pid> <output-fd> DB <db1-path> [<db2-path> ...]\n",
+	fprintf(stderr, "       %s <log-fd> <ctdbd-pid> <output-fd> DB <db1-path> <db1-flags> [<db2-path> <db2-flags>...]\n",
 		progname);
 }
 
 
-static int lock_record(const char *dbpath, const char *dbkey)
+static int lock_record(const char *dbpath, const char *dbflags, const char *dbkey)
 {
 	TDB_DATA key;
 	struct tdb_context *tdb;
+	int tdb_flags;
+
+	/* No error checking since CTDB always passes sane values */
+	tdb_flags = strtol(dbflags, NULL, 0);
 
 	/* Convert hex key to key */
 	if (strcmp(dbkey, "NULL") == 0) {
@@ -56,7 +60,7 @@ static int lock_record(const char *dbpath, const char *dbkey)
 		key.dptr = hex_decode_talloc(NULL, dbkey, &key.dsize);
 	}
 
-	tdb = tdb_open(dbpath, 0, TDB_DEFAULT, O_RDWR, 0600);
+	tdb = tdb_open(dbpath, 0, tdb_flags, O_RDWR, 0600);
 	if (tdb == NULL) {
 		fprintf(stderr, "%s: Error opening database %s\n", progname, dbpath);
 		return 1;
@@ -73,11 +77,15 @@ static int lock_record(const char *dbpath, const char *dbkey)
 }
 
 
-static int lock_db(const char *dbpath)
+static int lock_db(const char *dbpath, const char *dbflags)
 {
 	struct tdb_context *tdb;
+	int tdb_flags;
+
+	/* No error checking since CTDB always passes sane values */
+	tdb_flags = strtol(dbflags, NULL, 0);
 
-	tdb = tdb_open(dbpath, 0, TDB_DEFAULT, O_RDWR, 0600);
+	tdb = tdb_open(dbpath, 0, tdb_flags, O_RDWR, 0600);
 	if (tdb == NULL) {
 		fprintf(stderr, "%s: Error opening database %s\n", progname, dbpath);
 		return 1;
@@ -124,21 +132,21 @@ int main(int argc, char *argv[])
 	lock_type = argv[4];
 
 	if (strcmp(lock_type, "RECORD") == 0) {
-		if (argc != 7) {
+		if (argc != 8) {
 			fprintf(stderr, "%s: Invalid number of arguments (%d)\n",
 				progname, argc);
 			usage();
 			exit(1);
 		}
-		result = lock_record(argv[5], argv[6]);
+		result = lock_record(argv[5], argv[6], argv[7]);
 
 	} else if (strcmp(lock_type, "DB") == 0) {
 		int n;
 
 		/* If there are no databases specified, no need for lock */
 		if (argc > 5) {
-			for (n=5; n<argc; n++) {
-				result = lock_db(argv[n]);
+			for (n=5; n+1<argc; n+=2) {
+				result = lock_db(argv[n], argv[n+1]);
 				if (result != 0) {
 					break;
 				}
diff --git a/server/ctdb_ltdb_server.c b/server/ctdb_ltdb_server.c
index 24ad255..6a11851 100644
--- a/server/ctdb_ltdb_server.c
+++ b/server/ctdb_ltdb_server.c
@@ -844,7 +844,7 @@ static int ctdb_local_attach(struct ctdb_context *ctdb, const char *db_name,
 #ifdef TDB_MUTEX_LOCKING
 	if (ctdb->tunable.mutex_enabled && mutexes &&
 	    tdb_runtime_check_for_robust_mutexes()) {
-		tdb_flags |= TDB_MUTEX_LOCKING;
+		tdb_flags |= (TDB_MUTEX_LOCKING | TDB_CLEAR_IF_FIRST);
 	}
 #endif
 
@@ -1138,7 +1138,7 @@ int32_t ctdb_control_db_attach(struct ctdb_context *ctdb, TDB_DATA indata,
 	   that tdb_flags is passed in via the (otherwise unused)
 	   srvid to the attach control */
 #ifdef TDB_MUTEX_LOCKING
-	tdb_flags &= (TDB_NOSYNC|TDB_INCOMPATIBLE_HASH|TDB_MUTEX_LOCKING);
+	tdb_flags &= (TDB_NOSYNC|TDB_INCOMPATIBLE_HASH|TDB_MUTEX_LOCKING|TDB_CLEAR_IF_FIRST);
 #else
 	tdb_flags &= (TDB_NOSYNC|TDB_INCOMPATIBLE_HASH);
 #endif
diff --git a/server/ctdb_recover.c b/server/ctdb_recover.c
index d45b7f6..393b72f 100644
--- a/server/ctdb_recover.c
+++ b/server/ctdb_recover.c
@@ -752,10 +752,14 @@ bool ctdb_recovery_lock(struct ctdb_context *ctdb, bool keep)
 	lock.l_pid = 0;
 
 	if (fcntl(ctdb->recovery_lock_fd, F_SETLK, &lock) != 0) {
+		int saved_errno = errno;
 		close(ctdb->recovery_lock_fd);
 		ctdb->recovery_lock_fd = -1;
 		if (keep) {
-			DEBUG(DEBUG_CRIT,("ctdb_recovery_lock: Failed to get recovery lock on '%s'\n", ctdb->recovery_lock_file));
+			DEBUG(DEBUG_CRIT,("ctdb_recovery_lock: Failed to get "
+					  "recovery lock on '%s' - (%s)\n",
+					  ctdb->recovery_lock_file,
+					  strerror(saved_errno)));
 		}
 		return false;
 	}
diff --git a/tests/complex/18_ctdb_reloadips.sh b/tests/complex/18_ctdb_reloadips.sh
index 13f7c21..71f997c 100755
--- a/tests/complex/18_ctdb_reloadips.sh
+++ b/tests/complex/18_ctdb_reloadips.sh
@@ -56,7 +56,7 @@ ctdb_ip_info=$(echo "$out" | awk -F'|' 'NR > 1 { print $2, $3, $5 }')
 echo "Getting IP information from interfaces..."
 try_command_on_node all "ip addr show"
 ip_addr_info=$(echo "$out" | \
-    awk '$1 == "inet" { print gensub(/\/.*/, "", "", $2)}')
+    awk '$1 == "inet" { ip = $2; sub(/\/.*/, "", ip); print ip }')
 
 prefix=""
 for b in $(seq 0 255) ; do
diff --git a/tests/eventscripts/etc-ctdb/rc.local b/tests/eventscripts/etc-ctdb/rc.local
index 0dc531f..0291e57 100755
--- a/tests/eventscripts/etc-ctdb/rc.local
+++ b/tests/eventscripts/etc-ctdb/rc.local


-- 
CTDB repository


More information about the samba-cvs mailing list