X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=ctdb%2Fserver%2Fctdb_keepalive.c;h=a4569ec2502265af2d0ebed32e8a210339a24ad1;hb=f47d331e671d8835de010d3e9e1cbc6379e5ec27;hp=b4899b746f471ce3f4cde40faa22455b98f6178f;hpb=2e8aac6689f8fd8b3122b0d8b3188e36e3e03982;p=samba.git diff --git a/ctdb/server/ctdb_keepalive.c b/ctdb/server/ctdb_keepalive.c index b4899b746f4..a4569ec2502 100644 --- a/ctdb/server/ctdb_keepalive.c +++ b/ctdb/server/ctdb_keepalive.c @@ -18,17 +18,72 @@ along with this program; if not, see . */ -#include "includes.h" -#include "lib/tevent/tevent.h" +#include "replace.h" #include "system/filesys.h" +#include "system/network.h" +#include "system/time.h" #include "system/wait.h" -#include "../include/ctdb_private.h" +#include +#include + +#include "lib/util/debug.h" +#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 */ -static void ctdb_check_for_dead_nodes(struct event_context *ev, struct timed_event *te, +static void ctdb_check_for_dead_nodes(struct tevent_context *ev, + struct tevent_timer *te, struct timeval t, void *private_data) { struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context); @@ -78,26 +133,31 @@ static void ctdb_check_for_dead_nodes(struct event_context *ev, struct timed_eve node->tx_cnt = 0; } - - event_add_timed(ctdb->ev, ctdb->keepalive_ctx, - timeval_current_ofs(ctdb->tunable.keepalive_interval, 0), - ctdb_check_for_dead_nodes, ctdb); + + tevent_add_timer(ctdb->ev, ctdb->keepalive_ctx, + timeval_current_ofs(ctdb->tunable.keepalive_interval, 0), + ctdb_check_for_dead_nodes, ctdb); } void ctdb_start_keepalive(struct ctdb_context *ctdb) { - struct timed_event *te; + struct tevent_timer *te; ctdb->keepalive_ctx = talloc_new(ctdb); CTDB_NO_MEMORY_FATAL(ctdb, ctdb->keepalive_ctx); - te = event_add_timed(ctdb->ev, ctdb->keepalive_ctx, - timeval_current_ofs(ctdb->tunable.keepalive_interval, 0), - ctdb_check_for_dead_nodes, ctdb); + te = tevent_add_timer(ctdb->ev, ctdb->keepalive_ctx, + timeval_current_ofs(ctdb->tunable.keepalive_interval, 0), + ctdb_check_for_dead_nodes, 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) @@ -106,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; + } + } + } + + 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); +}