|
|
@@ -225,13 +225,19 @@ static int last_man_standing_timer_set = 0;
|
|
|
* Service Interfaces required by service_message_handler struct
|
|
|
*/
|
|
|
|
|
|
-static void votequorum_confchg_fn (
|
|
|
- enum totem_configuration_type configuration_type,
|
|
|
- const unsigned int *member_list, size_t member_list_entries,
|
|
|
- const unsigned int *left_list, size_t left_list_entries,
|
|
|
- const unsigned int *joined_list, size_t joined_list_entries,
|
|
|
+static int sync_in_progress = 0;
|
|
|
+
|
|
|
+static void votequorum_sync_init (
|
|
|
+ const unsigned int *trans_list,
|
|
|
+ size_t trans_list_entries,
|
|
|
+ const unsigned int *member_list,
|
|
|
+ size_t member_list_entries,
|
|
|
const struct memb_ring_id *ring_id);
|
|
|
|
|
|
+static int votequorum_sync_process (void);
|
|
|
+static void votequorum_sync_activate (void);
|
|
|
+static void votequorum_sync_abort (void);
|
|
|
+
|
|
|
static quorum_set_quorate_fn_t quorum_callback;
|
|
|
|
|
|
/*
|
|
|
@@ -379,7 +385,10 @@ static struct corosync_service_engine votequorum_service_engine = {
|
|
|
.exec_exit_fn = votequorum_exec_exit_fn,
|
|
|
.exec_engine = votequorum_exec_engine,
|
|
|
.exec_engine_count = sizeof (votequorum_exec_engine) / sizeof (struct corosync_exec_handler),
|
|
|
- .confchg_fn = votequorum_confchg_fn
|
|
|
+ .sync_init = votequorum_sync_init,
|
|
|
+ .sync_process = votequorum_sync_process,
|
|
|
+ .sync_activate = votequorum_sync_activate,
|
|
|
+ .sync_abort = votequorum_sync_abort
|
|
|
};
|
|
|
|
|
|
struct corosync_service_engine *votequorum_get_service_engine_ver0 (void)
|
|
|
@@ -783,7 +792,8 @@ static void are_we_quorate(unsigned int total_votes)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (quorum_change) {
|
|
|
+ if ((quorum_change) &&
|
|
|
+ (sync_in_progress == 0)) {
|
|
|
quorum_callback(quorum_members, quorum_members_entries,
|
|
|
cluster_is_quorate, &quorum_ringid);
|
|
|
}
|
|
|
@@ -1838,25 +1848,41 @@ static void votequorum_last_man_standing_timer_fn(void *arg)
|
|
|
LEAVE();
|
|
|
}
|
|
|
|
|
|
-static void votequorum_confchg_fn (
|
|
|
- enum totem_configuration_type configuration_type,
|
|
|
+static void votequorum_sync_init (
|
|
|
+ const unsigned int *trans_list, size_t trans_list_entries,
|
|
|
const unsigned int *member_list, size_t member_list_entries,
|
|
|
- const unsigned int *left_list, size_t left_list_entries,
|
|
|
- const unsigned int *joined_list, size_t joined_list_entries,
|
|
|
const struct memb_ring_id *ring_id)
|
|
|
{
|
|
|
- int i;
|
|
|
+ int i, j;
|
|
|
+ int found;
|
|
|
+ int left_nodes;
|
|
|
struct cluster_node *node;
|
|
|
|
|
|
ENTER();
|
|
|
|
|
|
+ sync_in_progress = 1;
|
|
|
+
|
|
|
if (member_list_entries > 1) {
|
|
|
us->flags &= ~NODE_FLAGS_FIRST;
|
|
|
}
|
|
|
|
|
|
- if (left_list_entries) {
|
|
|
- for (i = 0; i< left_list_entries; i++) {
|
|
|
- node = find_node_by_nodeid(left_list[i]);
|
|
|
+ /*
|
|
|
+ * we don't need to track which nodes have left directly,
|
|
|
+ * since that info is in the node db, but we need to know
|
|
|
+ * if somebody has left for last_man_standing
|
|
|
+ */
|
|
|
+ left_nodes = 0;
|
|
|
+ for (i = 0; i < quorum_members_entries; i++) {
|
|
|
+ found = 0;
|
|
|
+ for (j = 0; j < member_list_entries; j++) {
|
|
|
+ if (quorum_members[i] == member_list[j]) {
|
|
|
+ found = 1;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (found == 0) {
|
|
|
+ left_nodes = 1;
|
|
|
+ node = find_node_by_nodeid(quorum_members[i]);
|
|
|
if (node) {
|
|
|
node->state = NODESTATE_DEAD;
|
|
|
}
|
|
|
@@ -1864,7 +1890,7 @@ static void votequorum_confchg_fn (
|
|
|
}
|
|
|
|
|
|
if (last_man_standing) {
|
|
|
- if (((member_list_entries >= quorum) && (left_list_entries)) ||
|
|
|
+ if (((member_list_entries >= quorum) && (left_nodes)) ||
|
|
|
((member_list_entries <= quorum) && (auto_tie_breaker) && (check_low_node_id_partition() == 1))) {
|
|
|
if (last_man_standing_timer_set) {
|
|
|
corosync_api->timer_delete(last_man_standing_timer);
|
|
|
@@ -1877,31 +1903,36 @@ static void votequorum_confchg_fn (
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (member_list_entries) {
|
|
|
- memcpy(quorum_members, member_list, sizeof(unsigned int) * member_list_entries);
|
|
|
- quorum_members_entries = member_list_entries;
|
|
|
- votequorum_exec_send_nodeinfo(us->node_id);
|
|
|
- votequorum_exec_send_nodeinfo(VOTEQUORUM_QDEVICE_NODEID);
|
|
|
- if (strlen(qdevice_name)) {
|
|
|
- votequorum_exec_send_qdevice_reg(VOTEQUORUM_QDEVICE_OPERATION_REGISTER,
|
|
|
- qdevice_name);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
+ memcpy(quorum_members, member_list, sizeof(unsigned int) * member_list_entries);
|
|
|
+ quorum_members_entries = member_list_entries;
|
|
|
memcpy(&quorum_ringid, ring_id, sizeof(*ring_id));
|
|
|
|
|
|
- if (left_list_entries) {
|
|
|
- recalculate_quorum(0, 0);
|
|
|
- }
|
|
|
+ LEAVE();
|
|
|
+}
|
|
|
|
|
|
- if (configuration_type == TOTEM_CONFIGURATION_REGULAR) {
|
|
|
- quorum_callback(quorum_members, quorum_members_entries,
|
|
|
- cluster_is_quorate, &quorum_ringid);
|
|
|
+static int votequorum_sync_process (void)
|
|
|
+{
|
|
|
+ votequorum_exec_send_nodeinfo(us->node_id);
|
|
|
+ votequorum_exec_send_nodeinfo(VOTEQUORUM_QDEVICE_NODEID);
|
|
|
+ if (strlen(qdevice_name)) {
|
|
|
+ votequorum_exec_send_qdevice_reg(VOTEQUORUM_QDEVICE_OPERATION_REGISTER,
|
|
|
+ qdevice_name);
|
|
|
}
|
|
|
+ return 0;
|
|
|
+}
|
|
|
|
|
|
- LEAVE();
|
|
|
+static void votequorum_sync_activate (void)
|
|
|
+{
|
|
|
+ recalculate_quorum(0, 0);
|
|
|
+ quorum_callback(quorum_members, quorum_members_entries,
|
|
|
+ cluster_is_quorate, &quorum_ringid);
|
|
|
+ sync_in_progress = 0;
|
|
|
}
|
|
|
|
|
|
+static void votequorum_sync_abort (void)
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
|
|
|
char *votequorum_init(struct corosync_api_v1 *api,
|
|
|
quorum_set_quorate_fn_t q_set_quorate_fn)
|