[SCM] Samba Shared Repository - branch master updated

Amitay Isaacs amitay at samba.org
Wed May 24 19:07:02 UTC 2017


The branch, master has been updated
       via  f47d331 ctdb-daemon: Add AllowMixedVersions tunable
       via  305795a ctdb-daemon: Do not allow mixed ctdb versions in a cluster
       via  9ec302b ctdb-keepalive: Move ctdb_send_keepalive() to ctdb_keepalive.c
       via  0756134 ctdb-packaging: Remove mkversion.sh script
       via  f1ad7d0 ctdb-build: Simplify generation of version header files
       via  ae35bb8 wafsamba: Allow to specify VERSION file path
       via  f5f05a6 ctdb-readonly: Avoid a tight loop waiting for revoke to complete
       via  a50b25d Revert "ctdb-readonly: Avoid a tight loop waiting for revoke to complete"
      from  02a76d8 CVE-2017-7494: rpc_server3: Refuse to open pipe names with / inside

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


- Log -----------------------------------------------------------------
commit f47d331e671d8835de010d3e9e1cbc6379e5ec27
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri Apr 21 17:41:44 2017 +1000

    ctdb-daemon: Add AllowMixedVersions tunable
    
    This allows to mix CTDB major versions in a single cluster.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>
    
    Autobuild-User(master): Amitay Isaacs <amitay at samba.org>
    Autobuild-Date(master): Wed May 24 21:06:28 CEST 2017 on sn-devel-144

commit 305795a3231fef3af8b38d92252c44fe4a9fa9d1
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri Apr 21 17:55:11 2017 +1000

    ctdb-daemon: Do not allow mixed ctdb versions in a cluster
    
    Extend CTDB_REQ_KEEPALIVE packet to include version and uptime.  If CTDB
    versions do not match shutdown ctdb.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>

commit 9ec302bfad6abcbb1d6dfc759fa607757360ba66
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri Apr 21 17:18:49 2017 +1000

    ctdb-keepalive: Move ctdb_send_keepalive() to ctdb_keepalive.c
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>

commit 075613489cbcc024c0f9269b68c32db9213650b2
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri Apr 21 17:57:10 2017 +1000

    ctdb-packaging: Remove mkversion.sh script
    
    It's not used any more as the version headers are generated from waf.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>

commit f1ad7d075a7d6183dad0d7f990e0f4c34bd6d528
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri Apr 21 15:39:45 2017 +1000

    ctdb-build: Simplify generation of version header files
    
    Generate version headers from waf instead of separate shell script.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>

commit ae35bb8eaf5a4b2442c7d61f1332c1709e90e1f8
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Fri Apr 21 18:19:00 2017 +1000

    wafsamba: Allow to specify VERSION file path
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>

commit f5f05a644dadc0b1858c99c5f1f5af1ef80f3a28
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Thu May 18 11:50:09 2017 +1000

    ctdb-readonly: Avoid a tight loop waiting for revoke to complete
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12697
    
    During revoking readonly delegations, if one of the nodes disappears,
    then there is no point re-trying revoking readonly delegation immedately.
    The database needs to be recovered before the revoke operation can
    succeed.
    
    However, if the revoke is successful, then all the write requests need
    to be processed immediately before the read-only requests.  This avoids
    starving write requests, in case there are read-only requests coming
    from other nodes.
    
    In deferred_call_destructor, the result of revoke is not available and
    deferred calls cannot be correctly ordered.  To correctly order the
    deferred calls, process them in revokechild_destructor where the result
    of revoke is known.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>

commit a50b25d0ebbe731a766f8d2ce1924b34d6041668
Author: Amitay Isaacs <amitay at gmail.com>
Date:   Thu May 18 10:15:01 2017 +1000

    Revert "ctdb-readonly: Avoid a tight loop waiting for revoke to complete"
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=12697
    
    This reverts commit ad758cb869ac83534993caa212abc9fe9905ec68.
    
    This is an incomplete fix and introduces a regression.
    
    Signed-off-by: Amitay Isaacs <amitay at gmail.com>
    Reviewed-by: Martin Schwenke <martin at meltin.net>

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

Summary of changes:
 buildtools/wafsamba/samba_patterns.py |   4 +-
 ctdb/common/tunable.c                 |   2 +
 ctdb/doc/ctdb-tunables.7.xml          |  24 +++++++
 ctdb/include/ctdb_private.h           |   5 +-
 ctdb/include/ctdb_protocol.h          |   2 +
 ctdb/packaging/mkversion.sh           |  84 -----------------------
 ctdb/protocol/protocol.h              |   7 ++
 ctdb/server/ctdb_call.c               | 121 ++++++++++++++++------------------
 ctdb/server/ctdb_keepalive.c          |  94 ++++++++++++++++++++++++++
 ctdb/server/ctdb_server.c             |   1 +
 ctdb/tests/tool/ctdb.listvars.001.sh  |   1 +
 ctdb/wscript                          |  50 ++++++--------
 12 files changed, 215 insertions(+), 180 deletions(-)
 delete mode 100755 ctdb/packaging/mkversion.sh


Changeset truncated at 500 lines:

diff --git a/buildtools/wafsamba/samba_patterns.py b/buildtools/wafsamba/samba_patterns.py
index 0481520..1baa601 100644
--- a/buildtools/wafsamba/samba_patterns.py
+++ b/buildtools/wafsamba/samba_patterns.py
@@ -14,7 +14,7 @@ def write_version_header(task):
     return 0
 
 
-def SAMBA_MKVERSION(bld, target):
+def SAMBA_MKVERSION(bld, target, source='VERSION'):
     '''generate the version.h header for Samba'''
 
     # We only force waf to re-generate this file if we are installing,
@@ -22,7 +22,7 @@ def SAMBA_MKVERSION(bld, target):
     # git revision) included in the version.
     t = bld.SAMBA_GENERATOR('VERSION',
                             rule=write_version_header,
-                            source= 'VERSION',
+                            source=source,
                             target=target,
                             always=bld.is_install)
 Build.BuildContext.SAMBA_MKVERSION = SAMBA_MKVERSION
diff --git a/ctdb/common/tunable.c b/ctdb/common/tunable.c
index 5b640d9..ed7a52d 100644
--- a/ctdb/common/tunable.c
+++ b/ctdb/common/tunable.c
@@ -155,6 +155,8 @@ static struct {
 		offsetof(struct ctdb_tunable_list, queue_buffer_size) },
 	{ "IPAllocAlgorithm", 2, false,
 		offsetof(struct ctdb_tunable_list, ip_alloc_algorithm) },
+	{ "AllowMixedVersions", 0, false,
+		offsetof(struct ctdb_tunable_list, allow_mixed_versions) },
 	{ NULL, 0, true, }
 };
 
diff --git a/ctdb/doc/ctdb-tunables.7.xml b/ctdb/doc/ctdb-tunables.7.xml
index e3d8180..d0bb450 100644
--- a/ctdb/doc/ctdb-tunables.7.xml
+++ b/ctdb/doc/ctdb-tunables.7.xml
@@ -53,6 +53,30 @@
     </refsect2>
 
     <refsect2>
+      <title>AllowMixedVersions</title>
+      <para>Default: 0</para>
+      <para>
+	CTDB will not allow incompatible versions to co-exist in
+	a cluster.  If a version mismatch is found, then losing CTDB
+	will shutdown.	To disable the incompatible version check,
+	set this tunable to 1.
+      </para>
+      <para>
+	For version checking, CTDB uses major and minor version.
+	For example, CTDB 4.6.1 and CTDB CTDB 4.6.2 are matching versions;
+	CTDB 4.5.x and CTDB 4.6.y do not match.
+      </para>
+      <para>
+	CTDB with version check support will lose to CTDB without
+	version check support.	Between two different CTDB versions with
+	version check support, one running for less time will lose.
+	If the running time for both CTDB versions with version check
+	support is equal (to seconds), then the older version will lose.
+	The losing CTDB daemon will shutdown.
+      </para>
+    </refsect2>
+
+    <refsect2>
       <title>AllowUnhealthyDBRead</title>
       <para>Default: 0</para>
       <para>
diff --git a/ctdb/include/ctdb_private.h b/ctdb/include/ctdb_private.h
index 91e9885..6c7dd79 100644
--- a/ctdb/include/ctdb_private.h
+++ b/ctdb/include/ctdb_private.h
@@ -511,8 +511,6 @@ struct ctdb_call_state *ctdb_daemon_call_send_remote(
 int ctdb_daemon_call_recv(struct ctdb_call_state *state,
 			  struct ctdb_call *call);
 
-void ctdb_send_keepalive(struct ctdb_context *ctdb, uint32_t destnode);
-
 int ctdb_start_revoke_ro_record(struct ctdb_context *ctdb,
 				struct ctdb_db_context *ctdb_db,
 				TDB_DATA key, struct ctdb_ltdb_header *header,
@@ -636,6 +634,9 @@ bool ctdb_db_all_frozen(struct ctdb_context *ctdb);
 void ctdb_start_keepalive(struct ctdb_context *ctdb);
 void ctdb_stop_keepalive(struct ctdb_context *ctdb);
 
+void ctdb_request_keepalive(struct ctdb_context *ctdb,
+			    struct ctdb_req_header *hdr);
+
 /* from server/ctdb_lock.c */
 
 struct lock_request;
diff --git a/ctdb/include/ctdb_protocol.h b/ctdb/include/ctdb_protocol.h
index 2fb3b6d..52ecc45 100644
--- a/ctdb/include/ctdb_protocol.h
+++ b/ctdb/include/ctdb_protocol.h
@@ -130,6 +130,8 @@ struct ctdb_reply_control_old {
 
 struct ctdb_req_keepalive_old {
 	struct ctdb_req_header hdr;
+	uint32_t version;
+	uint32_t uptime;
 };
 
 /*
diff --git a/ctdb/packaging/mkversion.sh b/ctdb/packaging/mkversion.sh
deleted file mode 100755
index 54dc2cd..0000000
--- a/ctdb/packaging/mkversion.sh
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/bin/sh
-#
-# mkversion.sh - extract version string from git branch
-#
-# Copyright (C) Amitay Isaacs 2012
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by the Free
-# Software Foundation; either version 3 of the License, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, see <http://www.gnu.org/licenses/>.
-#
-
-#
-# Common code to generate CTDB version string
-#
-
-OUTPUT=$1
-
-if [ -z "$OUTPUT" ]; then
-    OUTPUT="include/ctdb_version.h"
-fi
-
-VERSION=$2
-RELEASE=1
-
-# We use tags and determine the version, as follows:
-# ctdb-0.9.1  (First release of 0.9).
-# ctdb-0.9.23 (23rd minor release of the 112 version)
-#
-# If we're not directly on a tag, this is a devel release; we append
-# .0.<patchnum>.<checksum>.devel to the release.
-if [ -z "$VERSION" ]; then
-
-TAG=`git describe --match "samba-*"`
-case "$TAG" in
-    samba-*)
-	TAG=${TAG##samba-}
-	case "$TAG" in
-	    *-*-g*) # 0.9-168-ge6cf0e8
-		# Not exactly on tag: devel version.
-		VERSION=`echo "$TAG" | sed 's/\([^-]\+\)-\([0-9]\+\)-\(g[0-9a-f]\+\)/\1.0.\2.\3.devel/'`
-		RELEASE=1
-		;;
-	    *)
-		# An actual release version
-		VERSION=$TAG
-		RELEASE=1
-		;;
-	esac
-	;;
-    *)
-	echo Invalid tag "$TAG" >&2
-	;;
-esac
-
-else
-
-    # If building from tarball, Samba version creation will create
-    # VERSION with UNKNOWN git hash.
-    case "$VERSION" in
-        *UNKNOWN)
-	    if [ -f ../include/ctdb_version.h ] ; then
-		VERSION=$(awk -F \" '/CTDB_VERSION_STRING/ {print $2}' ../include/ctdb_version.h)
-	    fi
-	    ;;
-    esac
-fi
-
-cat > "$OUTPUT" <<EOF
-/* This file is auto-generated by packaging/mkversion.sh */
-
-#define CTDB_VERSION_STRING "$VERSION"
-
-EOF
-
-echo "$VERSION $RELEASE"
diff --git a/ctdb/protocol/protocol.h b/ctdb/protocol/protocol.h
index 7b5a598..d405ea3 100644
--- a/ctdb/protocol/protocol.h
+++ b/ctdb/protocol/protocol.h
@@ -632,6 +632,7 @@ struct ctdb_tunable_list {
 	uint32_t rec_buffer_size_limit;
 	uint32_t queue_buffer_size;
 	uint32_t ip_alloc_algorithm;
+	uint32_t allow_mixed_versions;
 };
 
 struct ctdb_tickle_list {
@@ -979,6 +980,12 @@ struct ctdb_req_message_data {
 	TDB_DATA data;
 };
 
+struct ctdb_req_keepalive {
+	uint32_t version;
+	uint32_t uptime;
+};
+
+
 /* This is equivalent to server_id */
 struct ctdb_server_id {
 	uint64_t pid;
diff --git a/ctdb/server/ctdb_call.c b/ctdb/server/ctdb_call.c
index 3b84e75..c6bff49 100644
--- a/ctdb/server/ctdb_call.c
+++ b/ctdb/server/ctdb_call.c
@@ -1542,35 +1542,8 @@ int ctdb_daemon_call_recv(struct ctdb_call_state *state, struct ctdb_call *call)
 }
 
 
-/* 
-   send a keepalive packet to the other node
-*/
-void ctdb_send_keepalive(struct ctdb_context *ctdb, uint32_t destnode)
-{
-	struct ctdb_req_keepalive_old *r;
-	
-	if (ctdb->methods == NULL) {
-		DEBUG(DEBUG_INFO,(__location__ " Failed to send keepalive. Transport is DOWN\n"));
-		return;
-	}
-
-	r = ctdb_transport_allocate(ctdb, ctdb, CTDB_REQ_KEEPALIVE,
-				    sizeof(struct ctdb_req_keepalive_old), 
-				    struct ctdb_req_keepalive_old);
-	CTDB_NO_MEMORY_FATAL(ctdb, r);
-	r->hdr.destnode  = destnode;
-	r->hdr.reqid     = 0;
-	
-	CTDB_INCREMENT_STAT(ctdb, keepalive_packets_sent);
-
-	ctdb_queue_packet(ctdb, &r->hdr);
-
-	talloc_free(r);
-}
-
-
-
 struct revokechild_deferred_call {
+	struct revokechild_deferred_call *prev, *next;
 	struct ctdb_context *ctdb;
 	struct ctdb_req_header *hdr;
 	deferred_requeue_fn fn;
@@ -1586,50 +1559,31 @@ struct revokechild_handle {
 	int fd[2];
 	pid_t child;
 	TDB_DATA key;
-};
-
-struct revokechild_requeue_handle {
-	struct ctdb_context *ctdb;
-	struct ctdb_req_header *hdr;
-	deferred_requeue_fn fn;
-	void *ctx;
+	struct revokechild_deferred_call *deferred_call_list;
 };
 
 static void deferred_call_requeue(struct tevent_context *ev,
 				  struct tevent_timer *te,
 				  struct timeval t, void *private_data)
 {
-	struct revokechild_requeue_handle *requeue_handle = talloc_get_type(private_data, struct revokechild_requeue_handle);
-
-	requeue_handle->fn(requeue_handle->ctx, requeue_handle->hdr);
-	talloc_free(requeue_handle);
-}
+	struct revokechild_deferred_call *dlist = talloc_get_type_abort(
+		private_data, struct revokechild_deferred_call);
 
-static int deferred_call_destructor(struct revokechild_deferred_call *deferred_call)
-{
-	struct ctdb_context *ctdb = deferred_call->ctdb;
-	struct revokechild_requeue_handle *requeue_handle = talloc(ctdb, struct revokechild_requeue_handle);
-
-	requeue_handle->ctdb = ctdb;
-	requeue_handle->hdr  = deferred_call->hdr;
-	requeue_handle->fn   = deferred_call->fn;
-	requeue_handle->ctx  = deferred_call->ctx;
-	talloc_steal(requeue_handle, requeue_handle->hdr);
-
-	/* Always delay revoke requests.  Either wait for the read/write
-	 * operation to complete, or if revoking failed wait for recovery to
-	 * complete
-	 */
-	tevent_add_timer(ctdb->ev, requeue_handle,
-			 timeval_current_ofs(1, 0),
-			 deferred_call_requeue, requeue_handle);
+	while (dlist != NULL) {
+		struct revokechild_deferred_call *dcall = dlist;
 
-	return 0;
+		DLIST_REMOVE(dlist, dcall);
+		dcall->fn(dcall->ctx, dcall->hdr);
+		talloc_free(dcall);
+	}
 }
 
 
 static int revokechild_destructor(struct revokechild_handle *rc)
 {
+	struct revokechild_deferred_call *now_list = NULL;
+	struct revokechild_deferred_call *delay_list = NULL;
+
 	if (rc->fde != NULL) {
 		talloc_free(rc->fde);
 	}
@@ -1643,6 +1597,48 @@ static int revokechild_destructor(struct revokechild_handle *rc)
 	ctdb_kill(rc->ctdb, rc->child, SIGKILL);
 
 	DLIST_REMOVE(rc->ctdb_db->revokechild_active, rc);
+
+	while (rc->deferred_call_list != NULL) {
+		struct revokechild_deferred_call *dcall;
+
+		dcall = rc->deferred_call_list;
+		DLIST_REMOVE(rc->deferred_call_list, dcall);
+
+		/* If revoke is successful, then first process all the calls
+		 * that need write access, and delay readonly requests by 1
+		 * second grace.
+		 *
+		 * If revoke is unsuccessful, most likely because of node
+		 * failure, delay all the pending requests, so database can
+		 * be recovered.
+		 */
+
+		if (rc->status == 0) {
+			struct ctdb_req_call_old *c;
+
+			c = (struct ctdb_req_call_old *)dcall->hdr;
+			if (c->flags & CTDB_WANT_READONLY) {
+				DLIST_ADD(delay_list, dcall);
+			} else {
+				DLIST_ADD(now_list, dcall);
+			}
+		} else {
+			DLIST_ADD(delay_list, dcall);
+		}
+	}
+
+	if (now_list != NULL) {
+		tevent_add_timer(rc->ctdb->ev, rc->ctdb_db,
+				 tevent_timeval_current_ofs(0, 0),
+				 deferred_call_requeue, now_list);
+	}
+
+	if (delay_list != NULL) {
+		tevent_add_timer(rc->ctdb->ev, rc->ctdb_db,
+				 tevent_timeval_current_ofs(1, 0),
+				 deferred_call_requeue, delay_list);
+	}
+
 	return 0;
 }
 
@@ -1920,19 +1916,18 @@ int ctdb_add_revoke_deferred_call(struct ctdb_context *ctdb, struct ctdb_db_cont
 		return -1;
 	}
 
-	deferred_call = talloc(rc, struct revokechild_deferred_call);
+	deferred_call = talloc(ctdb_db, struct revokechild_deferred_call);
 	if (deferred_call == NULL) {
 		DEBUG(DEBUG_ERR,("Failed to allocate deferred call structure for revoking record\n"));
 		return -1;
 	}
 
 	deferred_call->ctdb = ctdb;
-	deferred_call->hdr  = hdr;
+	deferred_call->hdr  = talloc_steal(deferred_call, hdr);
 	deferred_call->fn   = fn;
 	deferred_call->ctx  = call_context;
 
-	talloc_set_destructor(deferred_call, deferred_call_destructor);
-	talloc_steal(deferred_call, hdr);
+	DLIST_ADD(rc->deferred_call_list, deferred_call);
 
 	return 0;
 }
diff --git a/ctdb/server/ctdb_keepalive.c b/ctdb/server/ctdb_keepalive.c
index a8acded..a4569ec 100644
--- a/ctdb/server/ctdb_keepalive.c
+++ b/ctdb/server/ctdb_keepalive.c
@@ -31,11 +31,54 @@
 #include "lib/util/samba_util.h"
 
 #include "ctdb_private.h"
+#include "version.h"
 
 #include "common/common.h"
 #include "common/logging.h"
 
 
+static uint32_t keepalive_version(void)
+{
+	return (SAMBA_VERSION_MAJOR << 16) | SAMBA_VERSION_MINOR;
+}
+
+static uint32_t keepalive_uptime(struct ctdb_context *ctdb)
+{
+	struct timeval current = tevent_timeval_current();
+
+	return current.tv_sec - ctdb->ctdbd_start_time.tv_sec;
+}
+
+/*
+   send a keepalive packet to the other node
+*/
+static void ctdb_send_keepalive(struct ctdb_context *ctdb, uint32_t destnode)
+{
+	struct ctdb_req_keepalive_old *r;
+
+	if (ctdb->methods == NULL) {
+		DEBUG(DEBUG_INFO,
+		      ("Failed to send keepalive. Transport is DOWN\n"));
+		return;
+	}
+
+	r = ctdb_transport_allocate(ctdb, ctdb, CTDB_REQ_KEEPALIVE,
+				    sizeof(struct ctdb_req_keepalive_old),
+				    struct ctdb_req_keepalive_old);
+	CTDB_NO_MEMORY_FATAL(ctdb, r);
+	r->hdr.destnode  = destnode;
+	r->hdr.reqid     = 0;
+
+	r->version = keepalive_version();
+	r->uptime = keepalive_uptime(ctdb);
+
+	CTDB_INCREMENT_STAT(ctdb, keepalive_packets_sent);
+
+	ctdb_queue_packet(ctdb, &r->hdr);
+
+	talloc_free(r);
+}
+
 /*
   see if any nodes are dead
  */
@@ -110,6 +153,11 @@ void ctdb_start_keepalive(struct ctdb_context *ctdb)
 	CTDB_NO_MEMORY_FATAL(ctdb, te);
 
 	DEBUG(DEBUG_NOTICE,("Keepalive monitoring has been started\n"));
+
+	if (ctdb->tunable.allow_mixed_versions == 1) {
+		DEBUG(DEBUG_WARNING,
+		      ("CTDB cluster with mixed versions configured\n"));
+	}
 }
 
 void ctdb_stop_keepalive(struct ctdb_context *ctdb)
@@ -118,3 +166,49 @@ void ctdb_stop_keepalive(struct ctdb_context *ctdb)
 	ctdb->keepalive_ctx = NULL;
 }
 
+void ctdb_request_keepalive(struct ctdb_context *ctdb,
+			    struct ctdb_req_header *hdr)
+{
+	struct ctdb_req_keepalive_old *c =
+		(struct ctdb_req_keepalive_old *)hdr;
+	uint32_t my_version = keepalive_version();
+	uint32_t my_uptime = keepalive_uptime(ctdb);
+
+	/* Don't check anything if mixed versions are allowed */
+	if (ctdb->tunable.allow_mixed_versions == 1) {
+		return;
+	}
+
+	if (hdr->length == sizeof(struct ctdb_req_header)) {
+		/* Old keepalive */
+		goto fail1;
+	}
+
+	if (c->version != my_version) {
+		if (c->uptime > my_uptime) {
+			goto fail2;
+		} else if (c->uptime == my_uptime) {
+			if (c->version > my_version) {
+				goto fail2;
+			}
+		}
+	}
+


-- 
Samba Shared Repository



More information about the samba-cvs mailing list