26ad17
From f7389ac6f67804f20393951462a59a0b505dfe03 Mon Sep 17 00:00:00 2001
26ad17
From: Ken Gaillot <kgaillot@redhat.com>
26ad17
Date: Tue, 21 Jul 2020 16:41:18 -0500
26ad17
Subject: [PATCH] Fix: executor: only send executor notifications to executor
26ad17
 clients
26ad17
26ad17
This bug has existed since Pacemaker Remote was first implemented, but was
26ad17
hidden until crm_node -l/-p was recently modified to go through controller IPC,
26ad17
because other command-line IPC API clients either fire-and-forget IPC requests
26ad17
or merely count replies, rather than parse the content of replies.
26ad17
26ad17
Previously, when the executor sent notifications of results, it broadcast the
26ad17
notification to all IPC clients. Normally this behavior makes sense, but for
26ad17
the executor in particular, it may be running as pacemaker-remoted, in which
26ad17
case its IPC clients include not only clients that connected to the executor
26ad17
IPC, but clients that connected via proxy to other IPC APIs on the cluster node
26ad17
hosting the remote connection.
26ad17
26ad17
With crm_node -l/-p, this meant that it was possible for an executor API
26ad17
notification to arrive while crm_node was waiting for a controller IPC reply.
26ad17
It would not find the information it needed and would report a protocol
26ad17
violation error.
26ad17
26ad17
The fix is to send executor notifications only to executor clients.
26ad17
---
26ad17
 daemons/execd/execd_commands.c    | 9 +++++++++
26ad17
 daemons/execd/remoted_proxy.c     | 5 +++++
26ad17
 include/crm/common/ipc_internal.h | 5 +++--
26ad17
 3 files changed, 17 insertions(+), 2 deletions(-)
26ad17
26ad17
diff --git a/daemons/execd/execd_commands.c b/daemons/execd/execd_commands.c
26ad17
index aaf2976..685fcc7 100644
26ad17
--- a/daemons/execd/execd_commands.c
26ad17
+++ b/daemons/execd/execd_commands.c
26ad17
@@ -507,6 +507,15 @@ send_client_notify(gpointer key, gpointer value, gpointer user_data)
26ad17
         crm_trace("Skipping notification to client without name");
26ad17
         return;
26ad17
     }
26ad17
+    if (is_set(client->flags, pcmk__client_to_proxy)) {
26ad17
+        /* We only want to notify clients of the executor IPC API. If we are
26ad17
+         * running as Pacemaker Remote, we may have clients proxied to other
26ad17
+         * IPC services in the cluster, so skip those.
26ad17
+         */
26ad17
+        crm_trace("Skipping executor API notification to %s IPC client",
26ad17
+                  client->name);
26ad17
+        return;
26ad17
+    }
26ad17
 
26ad17
     rc = lrmd_server_send_notify(client, update_msg);
26ad17
     if (rc == pcmk_rc_ok) {
26ad17
diff --git a/daemons/execd/remoted_proxy.c b/daemons/execd/remoted_proxy.c
26ad17
index dda7eed..5c58de4 100644
26ad17
--- a/daemons/execd/remoted_proxy.c
26ad17
+++ b/daemons/execd/remoted_proxy.c
26ad17
@@ -88,6 +88,11 @@ ipc_proxy_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid, const char *ipc
26ad17
     client->userdata = strdup(ipc_proxy->id);
26ad17
     client->name = crm_strdup_printf("proxy-%s-%d-%.8s", ipc_channel, client->pid, client->id);
26ad17
 
26ad17
+    /* Allow remote executor to distinguish between proxied local clients and
26ad17
+     * actual executor API clients
26ad17
+     */
26ad17
+    set_bit(client->flags, pcmk__client_to_proxy);
26ad17
+
26ad17
     g_hash_table_insert(ipc_clients, client->id, client);
26ad17
 
26ad17
     msg = create_xml_node(NULL, T_LRMD_IPC_PROXY);
26ad17
diff --git a/include/crm/common/ipc_internal.h b/include/crm/common/ipc_internal.h
26ad17
index 6a1fcf3..91b3435 100644
26ad17
--- a/include/crm/common/ipc_internal.h
26ad17
+++ b/include/crm/common/ipc_internal.h
26ad17
@@ -121,8 +121,9 @@ struct pcmk__remote_s {
26ad17
 };
26ad17
 
26ad17
 enum pcmk__client_flags {
26ad17
-    pcmk__client_proxied    = 0x00001, /* ipc_proxy code only */
26ad17
-    pcmk__client_privileged = 0x00002, /* root or cluster user */
26ad17
+    pcmk__client_proxied    = (1 << 0), // Remote client behind proxy
26ad17
+    pcmk__client_privileged = (1 << 1), // root or cluster user
26ad17
+    pcmk__client_to_proxy   = (1 << 2), // Local client to be proxied
26ad17
 };
26ad17
 
26ad17
 struct pcmk__client_s {
26ad17
-- 
26ad17
1.8.3.1
26ad17