File bug-964183_pacemaker-crmd-remote-proxy-disconnect.patch of Package pacemaker.1630
commit 356c8d65cd2361929555092363dd10fc29d43d46
Author: Gao,Yan <ygao@suse.com>
Date: Tue Feb 2 11:50:02 2016 +0100
Fix: crmd: Disconnect the relevant remote proxies as well when disconnecting a remote node
Previously, the relevant remote proxies would still exist even if a
remote node was already disconnected. So whenever there was an event, it
would still trigger remote_proxy_dispatch_internal(). Especially if the
remote node was unexpectedly disconnected, lrmd_tls_send() would fail to
relay the event and call lrmd_tls_disconnect() again. It actually always
occurred when reconnecting to the remote node, which basically made
reconnecting impossible.
diff --git a/crmd/lrm_state.c b/crmd/lrm_state.c
index 6d3cd6a..0f50fef 100644
--- a/crmd/lrm_state.c
+++ b/crmd/lrm_state.c
@@ -287,6 +287,45 @@ lrm_state_get_list(void)
return g_hash_table_get_values(lrm_state_table);
}
+static remote_proxy_t *
+find_connected_proxy_by_node(const char * node_name)
+{
+ GHashTableIter gIter;
+ remote_proxy_t *proxy = NULL;
+
+ CRM_CHECK(proxy_table != NULL, return NULL);
+
+ g_hash_table_iter_init(&gIter, proxy_table);
+
+ while (g_hash_table_iter_next(&gIter, NULL, (gpointer *) &proxy)) {
+ if (proxy->source
+ && safe_str_eq(node_name, proxy->node_name)) {
+ return proxy;
+ }
+ }
+
+ return NULL;
+}
+
+static void
+remote_proxy_disconnect_by_node(const char * node_name)
+{
+ remote_proxy_t *proxy = NULL;
+
+ CRM_CHECK(proxy_table != NULL, return);
+
+ while ((proxy = find_connected_proxy_by_node(node_name)) != NULL) {
+ /* mainloop_del_ipc_client() eventually calls remote_proxy_disconnected()
+ * , which removes the entry from proxy_table.
+ * Do not do this in a g_hash_table_iter_next() loop. */
+ if (proxy->source) {
+ mainloop_del_ipc_client(proxy->source);
+ }
+ }
+
+ return;
+}
+
void
lrm_state_disconnect(lrm_state_t * lrm_state)
{
@@ -296,6 +335,9 @@ lrm_state_disconnect(lrm_state_t * lrm_state)
return;
}
crm_trace("Disconnecting %s", lrm_state->node_name);
+
+ remote_proxy_disconnect_by_node(lrm_state->node_name);
+
((lrmd_t *) lrm_state->conn)->cmds->disconnect(lrm_state->conn);
if (is_not_set(fsa_input_register, R_SHUTDOWN)) {