File pacemaker-crmd-dont-fence-old-DC-if-shutting-down-as-soon-to-be-DC-joins.patch of Package pacemaker.14737
commit 249c7c9a83371a67e573276a285697994fe66fed
Author: Ken Gaillot <kgaillot@redhat.com>
Date: Mon Apr 17 15:41:18 2017 -0500
Fix: crmd: don't fence old DC if it's shutting down as soon-to-be DC joins
Existing peers of a DC that is shutting down can avoid fencing it (by updating
its expected state) because it broadcasts its shutdown request. However, a
newly joining node won't get that broadcast.
Previously, if the joining node became the new DC, it would fence the old one.
Now, the DC notifies joining nodes (via a join message field) whether it is
shutting down, and joining nodes update its expected state accordingly.
Index: pacemaker/crmd/join_client.c
===================================================================
--- pacemaker.orig/crmd/join_client.c
+++ pacemaker/crmd/join_client.c
@@ -30,6 +30,26 @@ void join_query_callback(xmlNode * msg,
extern ha_msg_input_t *copy_ha_msg_input(ha_msg_input_t * orig);
+/*!
+ * \internal
+ * \brief Remember if DC is shutting down as we join
+ *
+ * If we're joining while the current DC is shutting down, update its expected
+ * state, so we don't fence it if we become the new DC. (We weren't a peer
+ * when it broadcast its shutdown request.)
+ *
+ * \param[in] msg A join message from the DC
+ */
+static void
+update_dc_expected(xmlNode *msg)
+{
+ if (fsa_our_dc && crm_is_true(crm_element_value(msg, F_CRM_DC_LEAVING))) {
+ crm_node_t *dc_node = crm_get_peer(0, fsa_our_dc);
+
+ crm_update_peer_expected(__FUNCTION__, dc_node, CRMD_JOINSTATE_DOWN);
+ }
+}
+
/* A_CL_JOIN_QUERY */
/* is there a DC out there? */
void
@@ -128,6 +148,8 @@ do_cl_join_offer_respond(long long actio
return;
}
+ update_dc_expected(input->msg);
+
CRM_LOG_ASSERT(input != NULL);
query_call_id =
fsa_cib_conn->cmds->query(fsa_cib_conn, NULL, NULL, cib_scope_local | cib_no_children);
@@ -225,6 +247,8 @@ do_cl_join_finalize_respond(long long ac
return;
}
+ update_dc_expected(input->msg);
+
/* send our status section to the DC */
crm_debug("Confirming join join-%d: %s", join_id, crm_element_value(input->msg, F_CRM_TASK));
tmp1 = do_lrm_query(TRUE, fsa_our_uname);
Index: pacemaker/crmd/join_dc.c
===================================================================
--- pacemaker.orig/crmd/join_dc.c
+++ pacemaker/crmd/join_dc.c
@@ -106,6 +106,30 @@ initialize_join(gboolean before)
}
}
+/*!
+ * \internal
+ * \brief Create a join message from the DC
+ *
+ * \param[in] join_op Join operation name
+ * \param[in] host_to Recipient of message
+ */
+static xmlNode *
+create_dc_message(const char *join_op, const char *host_to)
+{
+ xmlNode *msg = create_request(join_op, NULL, host_to, CRM_SYSTEM_CRMD,
+ CRM_SYSTEM_DC, NULL);
+
+ /* Identify which election this is a part of */
+ crm_xml_add_int(msg, F_CRM_JOIN_ID, current_join_id);
+
+ /* Add a field specifying whether the DC is shutting down. This keeps the
+ * joining node from fencing the old DC if it becomes the new DC.
+ */
+ crm_xml_add_boolean(msg, F_CRM_DC_LEAVING,
+ is_set(fsa_input_register, R_SHUTDOWN));
+ return msg;
+}
+
static void
join_make_offer(gpointer key, gpointer value, gpointer user_data)
{
@@ -147,10 +171,8 @@ join_make_offer(gpointer key, gpointer v
crm_update_peer_join(__FUNCTION__, (crm_node_t*)member, crm_join_none);
- offer = create_request(CRM_OP_JOIN_OFFER, NULL, member->uname,
- CRM_SYSTEM_CRMD, CRM_SYSTEM_DC, NULL);
+ offer = create_dc_message(CRM_OP_JOIN_OFFER, member->uname);
- crm_xml_add_int(offer, F_CRM_JOIN_ID, current_join_id);
/* send the welcome */
crm_info("join-%d: Sending offer to %s", current_join_id, member->uname);
@@ -588,9 +610,7 @@ finalize_join_for(gpointer key, gpointer
}
/* send the ack/nack to the node */
- acknak = create_request(CRM_OP_JOIN_ACKNAK, NULL, join_to,
- CRM_SYSTEM_CRMD, CRM_SYSTEM_DC, NULL);
- crm_xml_add_int(acknak, F_CRM_JOIN_ID, current_join_id);
+ acknak = create_dc_message(CRM_OP_JOIN_ACKNAK, join_to);
crm_debug("join-%d: ACK'ing join request from %s",
current_join_id, join_to);
Index: pacemaker/include/crm/msg_xml.h
===================================================================
--- pacemaker.orig/include/crm/msg_xml.h
+++ pacemaker/include/crm/msg_xml.h
@@ -64,6 +64,7 @@
# define F_CRM_ORIGIN "origin"
# define F_CRM_USER "crm_user"
# define F_CRM_JOIN_ID "join_id"
+# define F_CRM_DC_LEAVING "dc-leaving"
# define F_CRM_ELECTION_ID "election-id"
# define F_CRM_ELECTION_AGE_S "election-age-sec"
# define F_CRM_ELECTION_AGE_US "election-age-nano-sec"