|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
/*
|
|
|
- * Copyright (c) 2009-2012 Red Hat, Inc.
|
|
|
|
|
|
|
+ * Copyright (c) 2009-2014 Red Hat, Inc.
|
|
|
*
|
|
*
|
|
|
* All rights reserved.
|
|
* All rights reserved.
|
|
|
*
|
|
*
|
|
@@ -36,7 +36,10 @@
|
|
|
#include <config.h>
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/types.h>
|
|
|
|
|
+#include <sys/stat.h>
|
|
|
|
|
+#include <fcntl.h>
|
|
|
#include <stdint.h>
|
|
#include <stdint.h>
|
|
|
|
|
+#include <unistd.h>
|
|
|
|
|
|
|
|
#include <qb/qbipc_common.h>
|
|
#include <qb/qbipc_common.h>
|
|
|
|
|
|
|
@@ -85,6 +88,10 @@ static uint32_t last_man_standing_window = DEFAULT_LMS_WIN;
|
|
|
static uint8_t allow_downscale = 0;
|
|
static uint8_t allow_downscale = 0;
|
|
|
static uint32_t ev_barrier = 0;
|
|
static uint32_t ev_barrier = 0;
|
|
|
|
|
|
|
|
|
|
+static uint8_t ev_tracking = 0;
|
|
|
|
|
+static uint32_t ev_tracking_barrier = 0;
|
|
|
|
|
+static int ev_tracking_fd = -1;
|
|
|
|
|
+
|
|
|
/*
|
|
/*
|
|
|
* votequorum_exec defines/structs/forward definitions
|
|
* votequorum_exec defines/structs/forward definitions
|
|
|
*/
|
|
*/
|
|
@@ -589,6 +596,47 @@ static void decode_flags(uint32_t flags)
|
|
|
LEAVE();
|
|
LEAVE();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/*
|
|
|
|
|
+ * load/save are copied almost pristine from totemsrp,c
|
|
|
|
|
+ */
|
|
|
|
|
+static int load_ev_tracking_barrier(void)
|
|
|
|
|
+{
|
|
|
|
|
+ int res = 0;
|
|
|
|
|
+ char filename[PATH_MAX];
|
|
|
|
|
+
|
|
|
|
|
+ ENTER();
|
|
|
|
|
+
|
|
|
|
|
+ snprintf(filename, sizeof(filename) - 1, LOCALSTATEDIR "/lib/corosync/ev_tracking");
|
|
|
|
|
+
|
|
|
|
|
+ ev_tracking_fd = open(filename, O_RDWR, 0700);
|
|
|
|
|
+ if (ev_tracking_fd != -1) {
|
|
|
|
|
+ res = read (ev_tracking_fd, &ev_tracking_barrier, sizeof(uint32_t));
|
|
|
|
|
+ if (res == sizeof (uint32_t)) {
|
|
|
|
|
+ LEAVE();
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ev_tracking_barrier = 0;
|
|
|
|
|
+ umask(0);
|
|
|
|
|
+ ev_tracking_fd = open (filename, O_CREAT|O_RDWR, 0700);
|
|
|
|
|
+ if (ev_tracking_fd != -1) {
|
|
|
|
|
+ res = write (ev_tracking_fd, &ev_tracking_barrier, sizeof (uint32_t));
|
|
|
|
|
+ if ((res == -1) || (res != sizeof (uint32_t))) {
|
|
|
|
|
+ log_printf(LOGSYS_LEVEL_WARNING,
|
|
|
|
|
+ "Unable to write to %s", filename);
|
|
|
|
|
+ }
|
|
|
|
|
+ LEAVE();
|
|
|
|
|
+ return 0;
|
|
|
|
|
+ }
|
|
|
|
|
+ log_printf(LOGSYS_LEVEL_WARNING,
|
|
|
|
|
+ "Unable to create %s file", filename);
|
|
|
|
|
+
|
|
|
|
|
+ LEAVE();
|
|
|
|
|
+
|
|
|
|
|
+ return -1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
static void update_wait_for_all_status(uint8_t wfa_status)
|
|
static void update_wait_for_all_status(uint8_t wfa_status)
|
|
|
{
|
|
{
|
|
|
ENTER();
|
|
ENTER();
|
|
@@ -644,6 +692,32 @@ static void update_qdevice_master_wins(uint8_t allow)
|
|
|
LEAVE();
|
|
LEAVE();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+static void update_ev_tracking_barrier(uint32_t ev_t_barrier)
|
|
|
|
|
+{
|
|
|
|
|
+ int res;
|
|
|
|
|
+
|
|
|
|
|
+ ENTER();
|
|
|
|
|
+
|
|
|
|
|
+ ev_tracking_barrier = ev_t_barrier;
|
|
|
|
|
+ icmap_set_uint32("runtime.votequorum.ev_tracking_barrier", ev_tracking_barrier);
|
|
|
|
|
+
|
|
|
|
|
+ if (lseek (ev_tracking_fd, 0, SEEK_SET) != 0) {
|
|
|
|
|
+ log_printf(LOGSYS_LEVEL_WARNING,
|
|
|
|
|
+ "Unable to update ev_tracking_barrier on disk data!!!");
|
|
|
|
|
+ LEAVE();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ res = write (ev_tracking_fd, &ev_tracking_barrier, sizeof (uint32_t));
|
|
|
|
|
+ if (res != sizeof (uint32_t)) {
|
|
|
|
|
+ log_printf(LOGSYS_LEVEL_WARNING,
|
|
|
|
|
+ "Unable to update ev_tracking_barrier on disk data!!!");
|
|
|
|
|
+ }
|
|
|
|
|
+ fdatasync(ev_tracking_fd);
|
|
|
|
|
+
|
|
|
|
|
+ LEAVE();
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
/*
|
|
/*
|
|
|
* quorum calculation core bits
|
|
* quorum calculation core bits
|
|
|
*/
|
|
*/
|
|
@@ -854,6 +928,11 @@ static void recalculate_quorum(int allow_decrease, int by_current_nodes)
|
|
|
votequorum_exec_send_expectedvotes_notification();
|
|
votequorum_exec_send_expectedvotes_notification();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if ((ev_tracking) &&
|
|
|
|
|
+ (us->expected_votes > ev_tracking_barrier)) {
|
|
|
|
|
+ update_ev_tracking_barrier(us->expected_votes);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
quorum = calculate_quorum(allow_decrease, cluster_members, &total_votes);
|
|
quorum = calculate_quorum(allow_decrease, cluster_members, &total_votes);
|
|
|
are_we_quorate(total_votes);
|
|
are_we_quorate(total_votes);
|
|
|
|
|
|
|
@@ -1022,6 +1101,21 @@ static char *votequorum_readconfig(int runtime)
|
|
|
icmap_get_uint8("quorum.auto_tie_breaker", &auto_tie_breaker);
|
|
icmap_get_uint8("quorum.auto_tie_breaker", &auto_tie_breaker);
|
|
|
icmap_get_uint8("quorum.last_man_standing", &last_man_standing);
|
|
icmap_get_uint8("quorum.last_man_standing", &last_man_standing);
|
|
|
icmap_get_uint32("quorum.last_man_standing_window", &last_man_standing_window);
|
|
icmap_get_uint32("quorum.last_man_standing_window", &last_man_standing_window);
|
|
|
|
|
+ icmap_get_uint8("quorum.expected_votes_tracking", &ev_tracking);
|
|
|
|
|
+
|
|
|
|
|
+ /* allow_downscale requires ev_tracking */
|
|
|
|
|
+ if (allow_downscale) {
|
|
|
|
|
+ ev_tracking = 1;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (ev_tracking) {
|
|
|
|
|
+ if (load_ev_tracking_barrier() < 0) {
|
|
|
|
|
+ LEAVE();
|
|
|
|
|
+ return ((char *)"Unable to load ev_tracking file!");
|
|
|
|
|
+ }
|
|
|
|
|
+ update_ev_tracking_barrier(ev_tracking_barrier);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -1144,6 +1238,11 @@ static char *votequorum_readconfig(int runtime)
|
|
|
/*
|
|
/*
|
|
|
* set this node votes and expected_votes
|
|
* set this node votes and expected_votes
|
|
|
*/
|
|
*/
|
|
|
|
|
+ log_printf(LOGSYS_LEVEL_DEBUG, "ev_tracking=%d, ev_tracking_barrier = %d: expected_votes = %d\n", ev_tracking, ev_tracking_barrier, expected_votes);
|
|
|
|
|
+
|
|
|
|
|
+ if (ev_tracking) {
|
|
|
|
|
+ expected_votes = ev_tracking_barrier;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
if (have_nodelist) {
|
|
if (have_nodelist) {
|
|
|
us->votes = node_votes;
|
|
us->votes = node_votes;
|
|
@@ -1666,7 +1765,7 @@ static void message_handler_req_exec_votequorum_nodeinfo (
|
|
|
us->expected_votes = req_exec_quorum_nodeinfo->expected_votes;
|
|
us->expected_votes = req_exec_quorum_nodeinfo->expected_votes;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (node->flags & NODE_FLAGS_QUORATE) {
|
|
|
|
|
|
|
+ if (node->flags & NODE_FLAGS_QUORATE || (ev_tracking)) {
|
|
|
node->expected_votes = req_exec_quorum_nodeinfo->expected_votes;
|
|
node->expected_votes = req_exec_quorum_nodeinfo->expected_votes;
|
|
|
} else {
|
|
} else {
|
|
|
node->expected_votes = us->expected_votes;
|
|
node->expected_votes = us->expected_votes;
|
|
@@ -1683,7 +1782,6 @@ static void message_handler_req_exec_votequorum_nodeinfo (
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
recalculate:
|
|
recalculate:
|
|
|
-
|
|
|
|
|
if ((new_node) ||
|
|
if ((new_node) ||
|
|
|
(nodeid == us->node_id) ||
|
|
(nodeid == us->node_id) ||
|
|
|
(node->flags & NODE_FLAGS_FIRST) ||
|
|
(node->flags & NODE_FLAGS_FIRST) ||
|
|
@@ -1739,6 +1837,9 @@ static void message_handler_req_exec_votequorum_reconfigure (
|
|
|
}
|
|
}
|
|
|
votequorum_exec_send_expectedvotes_notification();
|
|
votequorum_exec_send_expectedvotes_notification();
|
|
|
update_ev_barrier(req_exec_quorum_reconfigure->value);
|
|
update_ev_barrier(req_exec_quorum_reconfigure->value);
|
|
|
|
|
+ if (ev_tracking) {
|
|
|
|
|
+ us->expected_votes = max(us->expected_votes, ev_tracking_barrier);
|
|
|
|
|
+ }
|
|
|
recalculate_quorum(1, 0); /* Allow decrease */
|
|
recalculate_quorum(1, 0); /* Allow decrease */
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
@@ -1772,6 +1873,11 @@ static int votequorum_exec_exit_fn (void)
|
|
|
ret = votequorum_exec_send_nodeinfo(us->node_id);
|
|
ret = votequorum_exec_send_nodeinfo(us->node_id);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ if ((ev_tracking) && (ev_tracking_fd != -1)) {
|
|
|
|
|
+ close(ev_tracking_fd);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
LEAVE();
|
|
LEAVE();
|
|
|
return ret;
|
|
return ret;
|
|
|
}
|
|
}
|