ctdb-daemon: Do not allow mixed ctdb versions in a cluster
authorAmitay Isaacs <amitay@gmail.com>
Fri, 21 Apr 2017 07:55:11 +0000 (17:55 +1000)
committerAmitay Isaacs <amitay@samba.org>
Wed, 24 May 2017 15:03:28 +0000 (17:03 +0200)
Extend CTDB_REQ_KEEPALIVE packet to include version and uptime.  If CTDB
versions do not match shutdown ctdb.

Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/include/ctdb_private.h
ctdb/include/ctdb_protocol.h
ctdb/protocol/protocol.h
ctdb/server/ctdb_keepalive.c
ctdb/server/ctdb_server.c

index 7d16c42588107e366fe2cc66ed79c7dd6b8d2078..6c7dd7941b7c8e7f465a0fbc670477382eb81e7f 100644 (file)
@@ -634,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;
index 2fb3b6d0dca7c8a45d5f8862c67d6ed4026b1835..52ecc4569474ce0480d0e92717fa37dea0f7e14d 100644 (file)
@@ -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;
 };
 
 /*
index 7b5a5983be11229ba1f84ec7dc6fa132dafa3a16..13231536917e6e7a200119c8d077375108ec9fc5 100644 (file)
@@ -979,6 +979,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;
index 5562bffd8baf1fbe3738ffc6b5fb3f0d6f6dfff8..1a8f0f4f76e588ee72daf2cfc6d93e34df3ac71e 100644 (file)
 #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
 */
@@ -56,6 +69,9 @@ static void ctdb_send_keepalive(struct ctdb_context *ctdb, uint32_t destnode)
        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);
@@ -145,3 +161,44 @@ 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);
+
+       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;
+                       }
+               }
+       }
+
+       return;
+
+fail1:
+       DEBUG(DEBUG_ERR,
+             ("Keepalive version missing from node %u\n", hdr->srcnode));
+       goto shutdown;
+
+fail2:
+       DEBUG(DEBUG_ERR,
+             ("Keepalive version mismatch 0x%08x != 0x%08x from node %u\n",
+              my_version, c->version, hdr->srcnode));
+       goto shutdown;
+
+shutdown:
+       DEBUG(DEBUG_ERR,
+             ("CTDB Cluster with mixed versions, cannot continue\n"));
+       ctdb_shutdown_sequence(ctdb, 0);
+}
index 1712e39013ca81ae03f3f6abf2cd16659a5df759..c3d38c4b9dafbce9669a4581234916d60d037be4 100644 (file)
@@ -265,6 +265,7 @@ void ctdb_input_pkt(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
 
        case CTDB_REQ_KEEPALIVE:
                CTDB_INCREMENT_STAT(ctdb, keepalive_packets_recv);
+               ctdb_request_keepalive(ctdb, hdr);
                break;
 
        default: