|
rpm-build |
3ee90c |
/*
|
|
rpm-build |
3ee90c |
* Copyright 2004-2019 the Pacemaker project contributors
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* The version control history for this file may have further details.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* This source code is licensed under the GNU General Public License version 2
|
|
rpm-build |
3ee90c |
* or later (GPLv2+) WITHOUT ANY WARRANTY.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#include <crm_internal.h>
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#include <crm/crm.h>
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#include <crm/msg_xml.h>
|
|
rpm-build |
3ee90c |
#include <crm/common/xml.h>
|
|
rpm-build |
3ee90c |
#include <crm/cluster.h>
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
#include <pacemaker-controld.h>
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
char *max_epoch = NULL;
|
|
rpm-build |
3ee90c |
char *max_generation_from = NULL;
|
|
rpm-build |
3ee90c |
xmlNode *max_generation_xml = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
void initialize_join(gboolean before);
|
|
rpm-build |
3ee90c |
void finalize_join_for(gpointer key, gpointer value, gpointer user_data);
|
|
rpm-build |
3ee90c |
void finalize_sync_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data);
|
|
rpm-build |
3ee90c |
gboolean check_join_state(enum crmd_fsa_state cur_state, const char *source);
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
/* Numeric counter used to identify join rounds (an unsigned int would be
|
|
|
82e137 |
* appropriate, except we get and set it in XML as int)
|
|
|
82e137 |
*/
|
|
rpm-build |
3ee90c |
static int current_join_id = 0;
|
|
|
82e137 |
|
|
rpm-build |
3ee90c |
unsigned long long saved_ccm_membership_id = 0;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
crm_update_peer_join(const char *source, crm_node_t * node, enum crm_join_phase phase)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
enum crm_join_phase last = 0;
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
CRM_CHECK(node != NULL, return);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* Remote nodes do not participate in joins */
|
|
rpm-build |
3ee90c |
if (is_set(node->flags, crm_remote_node)) {
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
last = node->join;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if(phase == last) {
|
|
|
82e137 |
crm_trace("Node %s join-%d phase is still %s "
|
|
|
82e137 |
CRM_XS " nodeid=%u source=%s",
|
|
|
82e137 |
node->uname, current_join_id, crm_join_phase_str(last),
|
|
|
82e137 |
node->id, source);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if ((phase <= crm_join_none) || (phase == (last + 1))) {
|
|
rpm-build |
3ee90c |
node->join = phase;
|
|
|
82e137 |
crm_trace("Node %s join-%d phase is now %s (was %s) "
|
|
|
82e137 |
CRM_XS " nodeid=%u source=%s",
|
|
|
82e137 |
node->uname, current_join_id, crm_join_phase_str(phase),
|
|
|
82e137 |
crm_join_phase_str(last), node->id, source);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else {
|
|
|
82e137 |
crm_warn("Rejecting join-%d phase update for node %s because "
|
|
|
82e137 |
"can't go from %s to %s " CRM_XS " nodeid=%u source=%s",
|
|
|
82e137 |
current_join_id, node->uname, crm_join_phase_str(last),
|
|
|
82e137 |
crm_join_phase_str(phase), node->id, source);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
initialize_join(gboolean before)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
GHashTableIter iter;
|
|
rpm-build |
3ee90c |
crm_node_t *peer = NULL;
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
crm_debug("Starting new join round join-%d", current_join_id);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
g_hash_table_iter_init(&iter, crm_peer_cache);
|
|
rpm-build |
3ee90c |
while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &peer)) {
|
|
rpm-build |
3ee90c |
crm_update_peer_join(__FUNCTION__, peer, crm_join_none);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (before) {
|
|
rpm-build |
3ee90c |
if (max_generation_from != NULL) {
|
|
rpm-build |
3ee90c |
free(max_generation_from);
|
|
rpm-build |
3ee90c |
max_generation_from = NULL;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
if (max_generation_xml != NULL) {
|
|
rpm-build |
3ee90c |
free_xml(max_generation_xml);
|
|
rpm-build |
3ee90c |
max_generation_xml = NULL;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
clear_bit(fsa_input_register, R_HAVE_CIB);
|
|
rpm-build |
3ee90c |
clear_bit(fsa_input_register, R_CIB_ASKED);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/*!
|
|
rpm-build |
3ee90c |
* \internal
|
|
rpm-build |
3ee90c |
* \brief Create a join message from the DC
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* \param[in] join_op Join operation name
|
|
rpm-build |
3ee90c |
* \param[in] host_to Recipient of message
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
static xmlNode *
|
|
rpm-build |
3ee90c |
create_dc_message(const char *join_op, const char *host_to)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
xmlNode *msg = create_request(join_op, NULL, host_to, CRM_SYSTEM_CRMD,
|
|
rpm-build |
3ee90c |
CRM_SYSTEM_DC, NULL);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* Identify which election this is a part of */
|
|
rpm-build |
3ee90c |
crm_xml_add_int(msg, F_CRM_JOIN_ID, current_join_id);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* Add a field specifying whether the DC is shutting down. This keeps the
|
|
rpm-build |
3ee90c |
* joining node from fencing the old DC if it becomes the new DC.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
crm_xml_add_boolean(msg, F_CRM_DC_LEAVING,
|
|
rpm-build |
3ee90c |
is_set(fsa_input_register, R_SHUTDOWN));
|
|
rpm-build |
3ee90c |
return msg;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static void
|
|
rpm-build |
3ee90c |
join_make_offer(gpointer key, gpointer value, gpointer user_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
xmlNode *offer = NULL;
|
|
rpm-build |
3ee90c |
crm_node_t *member = (crm_node_t *)value;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
CRM_ASSERT(member != NULL);
|
|
rpm-build |
3ee90c |
if (crm_is_peer_active(member) == FALSE) {
|
|
|
82e137 |
crm_info("Not making join-%d offer to inactive node %s",
|
|
|
82e137 |
current_join_id,
|
|
|
82e137 |
(member->uname? member->uname : "with unknown name"));
|
|
rpm-build |
3ee90c |
if(member->expected == NULL && safe_str_eq(member->state, CRM_NODE_LOST)) {
|
|
rpm-build |
3ee90c |
/* You would think this unsafe, but in fact this plus an
|
|
rpm-build |
3ee90c |
* active resource is what causes it to be fenced.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* Yes, this does mean that any node that dies at the same
|
|
rpm-build |
3ee90c |
* time as the old DC and is not running resource (still)
|
|
rpm-build |
3ee90c |
* won't be fenced.
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* I'm not happy about this either.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
crm_update_peer_expected(__FUNCTION__, member, CRMD_JOINSTATE_DOWN);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (member->uname == NULL) {
|
|
|
82e137 |
crm_info("Not making join-%d offer to node uuid %s with unknown name",
|
|
|
82e137 |
current_join_id, member->uuid);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (saved_ccm_membership_id != crm_peer_seq) {
|
|
rpm-build |
3ee90c |
saved_ccm_membership_id = crm_peer_seq;
|
|
|
82e137 |
crm_info("Making join-%d offers based on membership event %llu",
|
|
|
82e137 |
current_join_id, crm_peer_seq);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if(user_data && member->join > crm_join_none) {
|
|
|
82e137 |
crm_info("Not making join-%d offer to already known node %s (%s)",
|
|
|
82e137 |
current_join_id, member->uname,
|
|
|
82e137 |
crm_join_phase_str(member->join));
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_update_peer_join(__FUNCTION__, (crm_node_t*)member, crm_join_none);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
offer = create_dc_message(CRM_OP_JOIN_OFFER, member->uname);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
// Advertise our feature set so the joining node can bail if not compatible
|
|
rpm-build |
3ee90c |
crm_xml_add(offer, XML_ATTR_CRM_VERSION, CRM_FEATURE_SET);
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
crm_info("Sending join-%d offer to %s", current_join_id, member->uname);
|
|
rpm-build |
3ee90c |
send_cluster_message(member, crm_msg_crmd, offer, TRUE);
|
|
rpm-build |
3ee90c |
free_xml(offer);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_update_peer_join(__FUNCTION__, member, crm_join_welcomed);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* A_DC_JOIN_OFFER_ALL */
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
do_dc_join_offer_all(long long action,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_cause cause,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_state cur_state,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_input current_input, fsa_data_t * msg_data)
|
|
rpm-build |
3ee90c |
{
|
|
|
82e137 |
int count;
|
|
|
82e137 |
|
|
rpm-build |
3ee90c |
/* Reset everyone's status back to down or in_ccm in the CIB.
|
|
rpm-build |
3ee90c |
* Any nodes that are active in the CIB but not in the cluster membership
|
|
rpm-build |
3ee90c |
* will be seen as offline by the scheduler anyway.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
current_join_id++;
|
|
rpm-build |
3ee90c |
initialize_join(TRUE);
|
|
rpm-build |
3ee90c |
/* do_update_cib_nodes(TRUE, __FUNCTION__); */
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
update_dc(NULL);
|
|
rpm-build |
3ee90c |
if (cause == C_HA_MESSAGE && current_input == I_NODE_JOIN) {
|
|
rpm-build |
3ee90c |
crm_info("A new node joined the cluster");
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
g_hash_table_foreach(crm_peer_cache, join_make_offer, NULL);
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
count = crmd_join_phase_count(crm_join_welcomed);
|
|
|
82e137 |
crm_info("Waiting on join-%d requests from %d outstanding node%s",
|
|
|
82e137 |
current_join_id, count, pcmk__plural_s(count));
|
|
|
82e137 |
|
|
rpm-build |
3ee90c |
// Don't waste time by invoking the scheduler yet
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* A_DC_JOIN_OFFER_ONE */
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
do_dc_join_offer_one(long long action,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_cause cause,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_state cur_state,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_input current_input, fsa_data_t * msg_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
crm_node_t *member;
|
|
rpm-build |
3ee90c |
ha_msg_input_t *welcome = NULL;
|
|
|
82e137 |
int count;
|
|
rpm-build |
3ee90c |
const char *join_to = NULL;
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
if (msg_data->data == NULL) {
|
|
|
82e137 |
crm_info("Making join-%d offers to any unconfirmed nodes "
|
|
|
82e137 |
"because an unknown node joined", current_join_id);
|
|
rpm-build |
3ee90c |
g_hash_table_foreach(crm_peer_cache, join_make_offer, &member);
|
|
rpm-build |
3ee90c |
check_join_state(cur_state, __FUNCTION__);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
welcome = fsa_typed_data(fsa_dt_ha_msg);
|
|
rpm-build |
3ee90c |
if (welcome == NULL) {
|
|
|
82e137 |
// fsa_typed_data() already logged an error
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
join_to = crm_element_value(welcome->msg, F_CRM_HOST_FROM);
|
|
rpm-build |
3ee90c |
if (join_to == NULL) {
|
|
|
82e137 |
crm_err("Can't make join-%d offer to unknown node", current_join_id);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
member = crm_get_peer(0, join_to);
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
/* It is possible that a node will have been sick or starting up when the
|
|
|
82e137 |
* original offer was made. However, it will either re-announce itself in
|
|
|
82e137 |
* due course, or we can re-store the original offer on the client.
|
|
|
82e137 |
*/
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_update_peer_join(__FUNCTION__, member, crm_join_none);
|
|
rpm-build |
3ee90c |
join_make_offer(NULL, member, NULL);
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
/* If the offer isn't to the local node, make an offer to the local node as
|
|
|
82e137 |
* well, to ensure the correct value for max_generation_from.
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
if (strcmp(join_to, fsa_our_uname) != 0) {
|
|
rpm-build |
3ee90c |
member = crm_get_peer(0, fsa_our_uname);
|
|
rpm-build |
3ee90c |
join_make_offer(NULL, member, NULL);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* this was a genuine join request, cancel any existing
|
|
rpm-build |
3ee90c |
* transition and invoke the PE
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
abort_transition(INFINITY, tg_restart, "Node join", NULL);
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
count = crmd_join_phase_count(crm_join_welcomed);
|
|
|
82e137 |
crm_info("Waiting on join-%d requests from %d outstanding node%s",
|
|
|
82e137 |
current_join_id, count, pcmk__plural_s(count));
|
|
|
82e137 |
|
|
rpm-build |
3ee90c |
// Don't waste time by invoking the scheduler yet
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static int
|
|
rpm-build |
3ee90c |
compare_int_fields(xmlNode * left, xmlNode * right, const char *field)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
const char *elem_l = crm_element_value(left, field);
|
|
rpm-build |
3ee90c |
const char *elem_r = crm_element_value(right, field);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
int int_elem_l = crm_int_helper(elem_l, NULL);
|
|
rpm-build |
3ee90c |
int int_elem_r = crm_int_helper(elem_r, NULL);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (int_elem_l < int_elem_r) {
|
|
rpm-build |
3ee90c |
return -1;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (int_elem_l > int_elem_r) {
|
|
rpm-build |
3ee90c |
return 1;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
return 0;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* A_DC_JOIN_PROCESS_REQ */
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
do_dc_join_filter_offer(long long action,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_cause cause,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_state cur_state,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_input current_input, fsa_data_t * msg_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
xmlNode *generation = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
int cmp = 0;
|
|
rpm-build |
3ee90c |
int join_id = -1;
|
|
|
82e137 |
int count = 0;
|
|
rpm-build |
3ee90c |
gboolean ack_nack_bool = TRUE;
|
|
rpm-build |
3ee90c |
ha_msg_input_t *join_ack = fsa_typed_data(fsa_dt_ha_msg);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
const char *join_from = crm_element_value(join_ack->msg, F_CRM_HOST_FROM);
|
|
rpm-build |
3ee90c |
const char *ref = crm_element_value(join_ack->msg, F_CRM_REFERENCE);
|
|
rpm-build |
3ee90c |
const char *join_version = crm_element_value(join_ack->msg,
|
|
rpm-build |
3ee90c |
XML_ATTR_CRM_VERSION);
|
|
|
82e137 |
crm_node_t *join_node = NULL;
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
if (join_from == NULL) {
|
|
|
82e137 |
crm_err("Ignoring invalid join request without node name");
|
|
|
82e137 |
return;
|
|
|
82e137 |
}
|
|
|
82e137 |
join_node = crm_get_peer(0, join_from);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_element_value_int(join_ack->msg, F_CRM_JOIN_ID, &join_id);
|
|
|
82e137 |
if (join_id != current_join_id) {
|
|
|
82e137 |
crm_debug("Ignoring join-%d request from %s because we are on join-%d",
|
|
|
82e137 |
join_id, join_from, current_join_id);
|
|
|
82e137 |
check_join_state(cur_state, __FUNCTION__);
|
|
|
82e137 |
return;
|
|
|
82e137 |
}
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
generation = join_ack->xml;
|
|
rpm-build |
3ee90c |
if (max_generation_xml != NULL && generation != NULL) {
|
|
rpm-build |
3ee90c |
int lpc = 0;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
const char *attributes[] = {
|
|
rpm-build |
3ee90c |
XML_ATTR_GENERATION_ADMIN,
|
|
rpm-build |
3ee90c |
XML_ATTR_GENERATION,
|
|
rpm-build |
3ee90c |
XML_ATTR_NUMUPDATES,
|
|
rpm-build |
3ee90c |
};
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
for (lpc = 0; cmp == 0 && lpc < DIMOF(attributes); lpc++) {
|
|
rpm-build |
3ee90c |
cmp = compare_int_fields(max_generation_xml, generation, attributes[lpc]);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
if (ref == NULL) {
|
|
|
82e137 |
ref = "none"; // for logging only
|
|
|
82e137 |
}
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
if (crm_is_peer_active(join_node) == FALSE) {
|
|
|
82e137 |
crm_err("Rejecting join-%d request from inactive node %s "
|
|
|
82e137 |
CRM_XS " ref=%s", join_id, join_from, ref);
|
|
rpm-build |
3ee90c |
ack_nack_bool = FALSE;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (generation == NULL) {
|
|
|
82e137 |
crm_err("Rejecting invalid join-%d request from node %s "
|
|
|
82e137 |
"missing CIB generation " CRM_XS " ref=%s",
|
|
|
82e137 |
join_id, join_from, ref);
|
|
rpm-build |
3ee90c |
ack_nack_bool = FALSE;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if ((join_version == NULL)
|
|
rpm-build |
3ee90c |
|| !feature_set_compatible(CRM_FEATURE_SET, join_version)) {
|
|
|
82e137 |
crm_err("Rejecting join-%d request from node %s because feature set %s"
|
|
|
82e137 |
" is incompatible with ours (%s) " CRM_XS " ref=%s",
|
|
|
82e137 |
join_id, join_from, (join_version? join_version : "pre-3.1.0"),
|
|
|
82e137 |
CRM_FEATURE_SET, ref);
|
|
rpm-build |
3ee90c |
ack_nack_bool = FALSE;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (max_generation_xml == NULL) {
|
|
|
82e137 |
crm_debug("Accepting join-%d request from %s "
|
|
|
82e137 |
"(with first CIB generation) " CRM_XS " ref=%s",
|
|
|
82e137 |
join_id, join_from, ref);
|
|
rpm-build |
3ee90c |
max_generation_xml = copy_xml(generation);
|
|
rpm-build |
3ee90c |
max_generation_from = strdup(join_from);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (cmp < 0 || (cmp == 0 && safe_str_eq(join_from, fsa_our_uname))) {
|
|
|
82e137 |
crm_debug("Accepting join-%d request from %s (with better "
|
|
|
82e137 |
"CIB generation than current best from %s) " CRM_XS " ref=%s",
|
|
|
82e137 |
join_id, join_from, max_generation_from, ref);
|
|
|
82e137 |
crm_log_xml_debug(max_generation_xml, "Old max generation");
|
|
|
82e137 |
crm_log_xml_debug(generation, "New max generation");
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
free(max_generation_from);
|
|
rpm-build |
3ee90c |
free_xml(max_generation_xml);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
max_generation_from = strdup(join_from);
|
|
rpm-build |
3ee90c |
max_generation_xml = copy_xml(join_ack->xml);
|
|
|
82e137 |
|
|
|
82e137 |
} else {
|
|
|
82e137 |
crm_debug("Accepting join-%d request from %s " CRM_XS " ref=%s",
|
|
|
82e137 |
join_id, join_from, ref);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (ack_nack_bool == FALSE) {
|
|
rpm-build |
3ee90c |
crm_update_peer_join(__FUNCTION__, join_node, crm_join_nack);
|
|
|
82e137 |
crm_update_peer_expected(__FUNCTION__, join_node, CRMD_JOINSTATE_NACK);
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
crm_update_peer_join(__FUNCTION__, join_node, crm_join_integrated);
|
|
|
82e137 |
crm_update_peer_expected(__FUNCTION__, join_node, CRMD_JOINSTATE_MEMBER);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
count = crmd_join_phase_count(crm_join_integrated);
|
|
|
82e137 |
crm_debug("%d node%s currently integrated in join-%d",
|
|
|
82e137 |
count, pcmk__plural_s(count), join_id);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (check_join_state(cur_state, __FUNCTION__) == FALSE) {
|
|
rpm-build |
3ee90c |
// Don't waste time by invoking the scheduler yet
|
|
|
82e137 |
count = crmd_join_phase_count(crm_join_welcomed);
|
|
|
82e137 |
crm_debug("Waiting on join-%d requests from %d outstanding node%s",
|
|
|
82e137 |
join_id, count, pcmk__plural_s(count));
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* A_DC_JOIN_FINALIZE */
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
do_dc_join_finalize(long long action,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_cause cause,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_state cur_state,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_input current_input, fsa_data_t * msg_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
char *sync_from = NULL;
|
|
rpm-build |
3ee90c |
int rc = pcmk_ok;
|
|
|
82e137 |
int count_welcomed = crmd_join_phase_count(crm_join_welcomed);
|
|
|
82e137 |
int count_integrated = crmd_join_phase_count(crm_join_integrated);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* This we can do straight away and avoid clients timing us out
|
|
rpm-build |
3ee90c |
* while we compute the latest CIB
|
|
rpm-build |
3ee90c |
*/
|
|
|
82e137 |
if (count_welcomed != 0) {
|
|
|
82e137 |
crm_debug("Waiting on join-%d requests from %d outstanding node%s "
|
|
|
82e137 |
"before finalizing join", current_join_id, count_welcomed,
|
|
|
82e137 |
pcmk__plural_s(count_welcomed));
|
|
|
82e137 |
crmd_join_phase_log(LOG_DEBUG);
|
|
rpm-build |
3ee90c |
/* crmd_fsa_stall(FALSE); Needed? */
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
} else if (count_integrated == 0) {
|
|
|
82e137 |
crm_debug("Finalization not needed for join-%d at the current time",
|
|
|
82e137 |
current_join_id);
|
|
|
82e137 |
crmd_join_phase_log(LOG_DEBUG);
|
|
rpm-build |
3ee90c |
check_join_state(fsa_state, __FUNCTION__);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
clear_bit(fsa_input_register, R_HAVE_CIB);
|
|
rpm-build |
3ee90c |
if (max_generation_from == NULL || safe_str_eq(max_generation_from, fsa_our_uname)) {
|
|
rpm-build |
3ee90c |
set_bit(fsa_input_register, R_HAVE_CIB);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (is_set(fsa_input_register, R_IN_TRANSITION)) {
|
|
|
82e137 |
crm_warn("Delaying join-%d finalization while transition in progress",
|
|
|
82e137 |
current_join_id);
|
|
|
82e137 |
crmd_join_phase_log(LOG_DEBUG);
|
|
rpm-build |
3ee90c |
crmd_fsa_stall(FALSE);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (max_generation_from && is_set(fsa_input_register, R_HAVE_CIB) == FALSE) {
|
|
rpm-build |
3ee90c |
/* ask for the agreed best CIB */
|
|
rpm-build |
3ee90c |
sync_from = strdup(max_generation_from);
|
|
rpm-build |
3ee90c |
set_bit(fsa_input_register, R_CIB_ASKED);
|
|
|
82e137 |
crm_notice("Finalizing join-%d for %d node%s (sync'ing CIB from %s)",
|
|
|
82e137 |
current_join_id, count_integrated,
|
|
|
82e137 |
pcmk__plural_s(count_integrated), sync_from);
|
|
|
82e137 |
crm_log_xml_notice(max_generation_xml, "Requested CIB version");
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
/* Send _our_ CIB out to everyone */
|
|
rpm-build |
3ee90c |
sync_from = strdup(fsa_our_uname);
|
|
|
82e137 |
crm_debug("Finalizing join-%d for %d node%s (sync'ing from local CIB)",
|
|
|
82e137 |
current_join_id, count_integrated,
|
|
|
82e137 |
pcmk__plural_s(count_integrated));
|
|
|
82e137 |
crm_log_xml_debug(max_generation_xml, "Requested CIB version");
|
|
rpm-build |
3ee90c |
}
|
|
|
82e137 |
crmd_join_phase_log(LOG_DEBUG);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
rc = fsa_cib_conn->cmds->sync_from(fsa_cib_conn, sync_from, NULL, cib_quorum_override);
|
|
rpm-build |
3ee90c |
fsa_register_cib_callback(rc, FALSE, sync_from, finalize_sync_callback);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
finalize_sync_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
CRM_LOG_ASSERT(-EPERM != rc);
|
|
rpm-build |
3ee90c |
clear_bit(fsa_input_register, R_CIB_ASKED);
|
|
rpm-build |
3ee90c |
if (rc != pcmk_ok) {
|
|
|
82e137 |
do_crm_log(((rc == -pcmk_err_old_data)? LOG_WARNING : LOG_ERR),
|
|
|
82e137 |
"Could not sync CIB from %s in join-%d: %s",
|
|
|
82e137 |
(char *) user_data, current_join_id, pcmk_strerror(rc));
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* restart the whole join process */
|
|
rpm-build |
3ee90c |
register_fsa_error_adv(C_FSA_INTERNAL, I_ELECTION_DC, NULL, NULL, __FUNCTION__);
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
} else if (!AM_I_DC) {
|
|
|
82e137 |
crm_debug("Sync'ed CIB for join-%d but no longer DC", current_join_id);
|
|
|
82e137 |
|
|
|
82e137 |
} else if (fsa_state != S_FINALIZE_JOIN) {
|
|
|
82e137 |
crm_debug("Sync'ed CIB for join-%d but no longer in S_FINALIZE_JOIN (%s)",
|
|
|
82e137 |
current_join_id, fsa_state2string(fsa_state));
|
|
|
82e137 |
|
|
|
82e137 |
} else {
|
|
rpm-build |
3ee90c |
set_bit(fsa_input_register, R_HAVE_CIB);
|
|
rpm-build |
3ee90c |
clear_bit(fsa_input_register, R_CIB_ASKED);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* make sure dc_uuid is re-set to us */
|
|
rpm-build |
3ee90c |
if (check_join_state(fsa_state, __FUNCTION__) == FALSE) {
|
|
|
82e137 |
int count_integrated = crmd_join_phase_count(crm_join_integrated);
|
|
|
82e137 |
|
|
|
82e137 |
crm_debug("Notifying %d node%s of join-%d results",
|
|
|
82e137 |
count_integrated, pcmk__plural_s(count_integrated),
|
|
|
82e137 |
current_join_id);
|
|
rpm-build |
3ee90c |
g_hash_table_foreach(crm_peer_cache, finalize_join_for, NULL);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
static void
|
|
rpm-build |
3ee90c |
join_update_complete_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
fsa_data_t *msg_data = NULL;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (rc == pcmk_ok) {
|
|
|
82e137 |
crm_debug("join-%d node history update (via CIB call %d) complete",
|
|
|
82e137 |
current_join_id, call_id);
|
|
rpm-build |
3ee90c |
check_join_state(fsa_state, __FUNCTION__);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else {
|
|
|
82e137 |
crm_err("join-%d node history update (via CIB call %d) failed: %s "
|
|
|
82e137 |
"(next transition may determine resource status incorrectly)",
|
|
|
82e137 |
current_join_id, call_id, pcmk_strerror(rc));
|
|
rpm-build |
3ee90c |
crm_log_xml_debug(msg, "failed");
|
|
rpm-build |
3ee90c |
register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
/* A_DC_JOIN_PROCESS_ACK */
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
do_dc_join_ack(long long action,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_cause cause,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_state cur_state,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_input current_input, fsa_data_t * msg_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
int join_id = -1;
|
|
rpm-build |
3ee90c |
int call_id = 0;
|
|
rpm-build |
3ee90c |
ha_msg_input_t *join_ack = fsa_typed_data(fsa_dt_ha_msg);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
const char *op = crm_element_value(join_ack->msg, F_CRM_TASK);
|
|
rpm-build |
3ee90c |
const char *join_from = crm_element_value(join_ack->msg, F_CRM_HOST_FROM);
|
|
|
82e137 |
crm_node_t *peer = NULL;
|
|
|
82e137 |
|
|
|
82e137 |
// Sanity checks
|
|
|
82e137 |
if (join_from == NULL) {
|
|
|
82e137 |
crm_warn("Ignoring message received without node identification");
|
|
|
82e137 |
return;
|
|
|
82e137 |
}
|
|
|
82e137 |
if (op == NULL) {
|
|
|
82e137 |
crm_warn("Ignoring message received from %s without task", join_from);
|
|
|
82e137 |
return;
|
|
|
82e137 |
}
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
if (strcmp(op, CRM_OP_JOIN_CONFIRM)) {
|
|
|
82e137 |
crm_debug("Ignoring '%s' message from %s while waiting for '%s'",
|
|
|
82e137 |
op, join_from, CRM_OP_JOIN_CONFIRM);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
if (crm_element_value_int(join_ack->msg, F_CRM_JOIN_ID, &join_id) != 0) {
|
|
|
82e137 |
crm_warn("Ignoring join confirmation from %s without valid join ID",
|
|
|
82e137 |
join_from);
|
|
|
82e137 |
return;
|
|
|
82e137 |
}
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
peer = crm_get_peer(0, join_from);
|
|
rpm-build |
3ee90c |
if (peer->join != crm_join_finalized) {
|
|
|
82e137 |
crm_info("Ignoring out-of-sequence join-%d confirmation from %s "
|
|
|
82e137 |
"(currently %s not %s)",
|
|
|
82e137 |
join_id, join_from, crm_join_phase_str(peer->join),
|
|
|
82e137 |
crm_join_phase_str(crm_join_finalized));
|
|
rpm-build |
3ee90c |
return;
|
|
|
82e137 |
}
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
if (join_id != current_join_id) {
|
|
|
82e137 |
crm_err("Rejecting join-%d confirmation from %s "
|
|
|
82e137 |
"because currently on join-%d",
|
|
|
82e137 |
join_id, join_from, current_join_id);
|
|
rpm-build |
3ee90c |
crm_update_peer_join(__FUNCTION__, peer, crm_join_nack);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
crm_update_peer_join(__FUNCTION__, peer, crm_join_confirmed);
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
/* Update CIB with node's current executor state. A new transition will be
|
|
|
82e137 |
* triggered later, when the CIB notifies us of the change.
|
|
rpm-build |
3ee90c |
*/
|
|
|
409f23 |
controld_delete_node_state(join_from, controld_section_lrm,
|
|
|
409f23 |
cib_scope_local);
|
|
rpm-build |
3ee90c |
if (safe_str_eq(join_from, fsa_our_uname)) {
|
|
rpm-build |
3ee90c |
xmlNode *now_dc_lrmd_state = do_lrm_query(TRUE, fsa_our_uname);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (now_dc_lrmd_state != NULL) {
|
|
rpm-build |
3ee90c |
fsa_cib_update(XML_CIB_TAG_STATUS, now_dc_lrmd_state,
|
|
rpm-build |
3ee90c |
cib_scope_local | cib_quorum_override | cib_can_create, call_id, NULL);
|
|
rpm-build |
3ee90c |
free_xml(now_dc_lrmd_state);
|
|
|
82e137 |
crm_debug("Updating local node history for join-%d "
|
|
|
82e137 |
"from query result (via CIB call %d)", join_id, call_id);
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
fsa_cib_update(XML_CIB_TAG_STATUS, join_ack->xml,
|
|
rpm-build |
3ee90c |
cib_scope_local | cib_quorum_override | cib_can_create, call_id, NULL);
|
|
|
82e137 |
crm_warn("Updating local node history from join-%d confirmation "
|
|
|
82e137 |
"because query failed (via CIB call %d)", join_id, call_id);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
} else {
|
|
rpm-build |
3ee90c |
fsa_cib_update(XML_CIB_TAG_STATUS, join_ack->xml,
|
|
rpm-build |
3ee90c |
cib_scope_local | cib_quorum_override | cib_can_create, call_id, NULL);
|
|
|
82e137 |
crm_debug("Updating node history for %s from join-%d confirmation "
|
|
|
82e137 |
"(via CIB call %d)", join_from, join_id, call_id);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
fsa_register_cib_callback(call_id, FALSE, NULL, join_update_complete_callback);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
finalize_join_for(gpointer key, gpointer value, gpointer user_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
xmlNode *acknak = NULL;
|
|
rpm-build |
3ee90c |
xmlNode *tmp1 = NULL;
|
|
rpm-build |
3ee90c |
crm_node_t *join_node = value;
|
|
rpm-build |
3ee90c |
const char *join_to = join_node->uname;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if(join_node->join != crm_join_integrated) {
|
|
|
82e137 |
crm_trace("Not updating non-integrated node %s (%s) for join-%d",
|
|
|
82e137 |
join_to, crm_join_phase_str(join_node->join),
|
|
|
82e137 |
current_join_id);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
crm_trace("Updating node state for %s", join_to);
|
|
rpm-build |
3ee90c |
tmp1 = create_xml_node(NULL, XML_CIB_TAG_NODE);
|
|
rpm-build |
3ee90c |
set_uuid(tmp1, XML_ATTR_UUID, join_node);
|
|
rpm-build |
3ee90c |
crm_xml_add(tmp1, XML_ATTR_UNAME, join_to);
|
|
rpm-build |
3ee90c |
fsa_cib_anon_update(XML_CIB_TAG_NODES, tmp1);
|
|
rpm-build |
3ee90c |
free_xml(tmp1);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
join_node = crm_get_peer(0, join_to);
|
|
rpm-build |
3ee90c |
if (crm_is_peer_active(join_node) == FALSE) {
|
|
rpm-build |
3ee90c |
/*
|
|
rpm-build |
3ee90c |
* NACK'ing nodes that the membership layer doesn't know about yet
|
|
rpm-build |
3ee90c |
* simply creates more churn
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* Better to leave them waiting and let the join restart when
|
|
rpm-build |
3ee90c |
* the new membership event comes in
|
|
rpm-build |
3ee90c |
*
|
|
rpm-build |
3ee90c |
* All other NACKs (due to versions etc) should still be processed
|
|
rpm-build |
3ee90c |
*/
|
|
rpm-build |
3ee90c |
crm_update_peer_expected(__FUNCTION__, join_node, CRMD_JOINSTATE_PENDING);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
|
82e137 |
// Acknowledge node's join request
|
|
|
82e137 |
crm_debug("Acknowledging join-%d request from %s",
|
|
rpm-build |
3ee90c |
current_join_id, join_to);
|
|
|
82e137 |
acknak = create_dc_message(CRM_OP_JOIN_ACKNAK, join_to);
|
|
rpm-build |
3ee90c |
crm_xml_add(acknak, CRM_OP_JOIN_ACKNAK, XML_BOOLEAN_TRUE);
|
|
rpm-build |
3ee90c |
crm_update_peer_join(__FUNCTION__, join_node, crm_join_finalized);
|
|
rpm-build |
3ee90c |
crm_update_peer_expected(__FUNCTION__, join_node, CRMD_JOINSTATE_MEMBER);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
send_cluster_message(crm_get_peer(0, join_to), crm_msg_crmd, acknak, TRUE);
|
|
rpm-build |
3ee90c |
free_xml(acknak);
|
|
rpm-build |
3ee90c |
return;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
gboolean
|
|
rpm-build |
3ee90c |
check_join_state(enum crmd_fsa_state cur_state, const char *source)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
static unsigned long long highest_seq = 0;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
if (saved_ccm_membership_id != crm_peer_seq) {
|
|
|
82e137 |
crm_debug("join-%d: Membership changed from %llu to %llu "
|
|
|
82e137 |
CRM_XS " highest=%llu state=%s for=%s",
|
|
|
82e137 |
current_join_id, saved_ccm_membership_id, crm_peer_seq, highest_seq,
|
|
|
82e137 |
fsa_state2string(cur_state), source);
|
|
rpm-build |
3ee90c |
if(highest_seq < crm_peer_seq) {
|
|
rpm-build |
3ee90c |
/* Don't spam the FSA with duplicates */
|
|
rpm-build |
3ee90c |
highest_seq = crm_peer_seq;
|
|
rpm-build |
3ee90c |
register_fsa_input_before(C_FSA_INTERNAL, I_NODE_JOIN, NULL);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (cur_state == S_INTEGRATION) {
|
|
rpm-build |
3ee90c |
if (crmd_join_phase_count(crm_join_welcomed) == 0) {
|
|
|
82e137 |
int count = crmd_join_phase_count(crm_join_integrated);
|
|
|
82e137 |
|
|
|
82e137 |
crm_debug("join-%d: Integration of %d peer%s complete "
|
|
|
82e137 |
CRM_XS " state=%s for=%s",
|
|
|
82e137 |
current_join_id, count, pcmk__plural_s(count),
|
|
|
82e137 |
fsa_state2string(cur_state), source);
|
|
rpm-build |
3ee90c |
register_fsa_input_before(C_FSA_INTERNAL, I_INTEGRATED, NULL);
|
|
rpm-build |
3ee90c |
return TRUE;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (cur_state == S_FINALIZE_JOIN) {
|
|
rpm-build |
3ee90c |
if (is_set(fsa_input_register, R_HAVE_CIB) == FALSE) {
|
|
|
82e137 |
crm_debug("join-%d: Delaying finalization until we have CIB "
|
|
|
82e137 |
CRM_XS " state=%s for=%s",
|
|
|
82e137 |
current_join_id, fsa_state2string(cur_state), source);
|
|
rpm-build |
3ee90c |
return TRUE;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (crmd_join_phase_count(crm_join_welcomed) != 0) {
|
|
|
82e137 |
int count = crmd_join_phase_count(crm_join_welcomed);
|
|
|
82e137 |
|
|
|
82e137 |
crm_debug("join-%d: Still waiting on %d welcomed node%s "
|
|
|
82e137 |
CRM_XS " state=%s for=%s",
|
|
|
82e137 |
current_join_id, count, pcmk__plural_s(count),
|
|
|
82e137 |
fsa_state2string(cur_state), source);
|
|
rpm-build |
3ee90c |
crmd_join_phase_log(LOG_DEBUG);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (crmd_join_phase_count(crm_join_integrated) != 0) {
|
|
|
82e137 |
int count = crmd_join_phase_count(crm_join_integrated);
|
|
|
82e137 |
|
|
|
82e137 |
crm_debug("join-%d: Still waiting on %d integrated node%s "
|
|
|
82e137 |
CRM_XS " state=%s for=%s",
|
|
|
82e137 |
current_join_id, count, pcmk__plural_s(count),
|
|
|
82e137 |
fsa_state2string(cur_state), source);
|
|
rpm-build |
3ee90c |
crmd_join_phase_log(LOG_DEBUG);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else if (crmd_join_phase_count(crm_join_finalized) != 0) {
|
|
|
82e137 |
int count = crmd_join_phase_count(crm_join_finalized);
|
|
|
82e137 |
|
|
|
82e137 |
crm_debug("join-%d: Still waiting on %d finalized node%s "
|
|
|
82e137 |
CRM_XS " state=%s for=%s",
|
|
|
82e137 |
current_join_id, count, pcmk__plural_s(count),
|
|
|
82e137 |
fsa_state2string(cur_state), source);
|
|
rpm-build |
3ee90c |
crmd_join_phase_log(LOG_DEBUG);
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
} else {
|
|
|
82e137 |
crm_debug("join-%d: Complete " CRM_XS " state=%s for=%s",
|
|
|
82e137 |
current_join_id, fsa_state2string(cur_state), source);
|
|
rpm-build |
3ee90c |
register_fsa_input_later(C_FSA_INTERNAL, I_FINALIZED, NULL);
|
|
rpm-build |
3ee90c |
return TRUE;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
return FALSE;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
void
|
|
rpm-build |
3ee90c |
do_dc_join_final(long long action,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_cause cause,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_state cur_state,
|
|
rpm-build |
3ee90c |
enum crmd_fsa_input current_input, fsa_data_t * msg_data)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
crm_debug("Ensuring DC, quorum and node attributes are up-to-date");
|
|
rpm-build |
3ee90c |
crm_update_quorum(crm_have_quorum, TRUE);
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
int crmd_join_phase_count(enum crm_join_phase phase)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
int count = 0;
|
|
rpm-build |
3ee90c |
crm_node_t *peer;
|
|
rpm-build |
3ee90c |
GHashTableIter iter;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
g_hash_table_iter_init(&iter, crm_peer_cache);
|
|
rpm-build |
3ee90c |
while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &peer)) {
|
|
rpm-build |
3ee90c |
if(peer->join == phase) {
|
|
rpm-build |
3ee90c |
count++;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
return count;
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
void crmd_join_phase_log(int level)
|
|
rpm-build |
3ee90c |
{
|
|
rpm-build |
3ee90c |
crm_node_t *peer;
|
|
rpm-build |
3ee90c |
GHashTableIter iter;
|
|
rpm-build |
3ee90c |
|
|
rpm-build |
3ee90c |
g_hash_table_iter_init(&iter, crm_peer_cache);
|
|
rpm-build |
3ee90c |
while (g_hash_table_iter_next(&iter, NULL, (gpointer *) &peer)) {
|
|
rpm-build |
3ee90c |
do_crm_log(level, "join-%d: %s=%s", current_join_id, peer->uname,
|
|
rpm-build |
3ee90c |
crm_join_phase_str(peer->join));
|
|
rpm-build |
3ee90c |
}
|
|
rpm-build |
3ee90c |
}
|