1 /*
2 * Copyright 2024 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU Lesser General Public License
7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8 */
9
10 #include <crm_internal.h>
11
12 #include <stdio.h> // NULL
13
14 #include <crm/crm.h>
15
16 /* Each Pacemaker subdaemon offers an IPC interface, and most exchange cluster
17 * messages as well. Particular names need to be used for logging, connecting
18 * IPC, and IPC/cluster message types.
19 *
20 * This array is indexed by enum pcmk_ipc_server and gathers all those names for
21 * easier mapping. Most members are lists with the first value listed being the
22 * "main" one returned if another value is mapped to it.
23 *
24 * @COMPAT Ideally, we'd use a single string (such as the server's
25 * crm_system_name) as the sole IPC name and sole message type for each server,
26 * making most of this unnecessary. However, backward compatiblity with older
27 * nodes involved in a rolling upgrade or Pacemaker Remote connection would
28 * be a nightmare: we'd have to add duplicate message attributes, struct
29 * members, and libqb IPC server endpoints for both the old and new names, and
30 * could drop the old names only after we no longer supported connections with
31 * older nodes.
32 */
33 static struct {
34 const char *log_name; // Readable server name for use in logs
35 const char *system_names[2]; // crm_system_name values (subdaemon names)
36 const char *ipc_names[3]; // libqb IPC names used to contact server
37 const char *message_types[3]; // IPC/cluster message types sent to server
38 } server_info[] = {
39 [pcmk_ipc_unknown] = {
40 NULL,
41 { NULL, NULL, },
42 { NULL, NULL, NULL, },
43 { NULL, NULL, NULL, },
44 },
45
46 [pcmk_ipc_attrd] = {
47 "attribute manager",
48 { PCMK__SERVER_ATTRD, NULL, },
49 { PCMK__VALUE_ATTRD, NULL, NULL, },
50 { PCMK__VALUE_ATTRD, NULL, NULL, },
51 },
52
53 [pcmk_ipc_based] = {
54 "CIB manager",
55 { PCMK__SERVER_BASED, NULL, },
56 { PCMK__SERVER_BASED_RW, PCMK__SERVER_BASED_RO,
57 PCMK__SERVER_BASED_SHM, },
58 { CRM_SYSTEM_CIB, NULL, NULL, },
59 },
60
61 [pcmk_ipc_controld] = {
62 "controller",
63 { PCMK__SERVER_CONTROLD, NULL, },
64 { PCMK__VALUE_CRMD, NULL, NULL, },
65 { PCMK__VALUE_CRMD, CRM_SYSTEM_DC, CRM_SYSTEM_TENGINE, },
66 },
67
68 [pcmk_ipc_execd] = {
69 "executor",
70 { PCMK__SERVER_EXECD, PCMK__SERVER_REMOTED, },
71 { PCMK__VALUE_LRMD, NULL, NULL, },
72 { PCMK__VALUE_LRMD, NULL, NULL, },
73 },
74
75 [pcmk_ipc_fenced] = {
76 "fencer",
77 { PCMK__SERVER_FENCED, NULL, },
78 { PCMK__VALUE_STONITH_NG, NULL, NULL, },
79 { PCMK__VALUE_STONITH_NG, NULL, NULL, },
80 },
81
82 [pcmk_ipc_pacemakerd] = {
83 "launcher",
84 { PCMK__SERVER_PACEMAKERD, NULL, },
85 { CRM_SYSTEM_MCP, NULL, NULL, },
86 { CRM_SYSTEM_MCP, NULL, NULL, },
87 },
88
89 [pcmk_ipc_schedulerd] = {
90 "scheduler",
91 { PCMK__SERVER_SCHEDULERD, NULL, },
92 { CRM_SYSTEM_PENGINE, NULL, NULL, },
93 { CRM_SYSTEM_PENGINE, NULL, NULL, },
94 },
95 };
96
97 /*!
98 * \internal
99 * \brief Return server's (primary) system name
100 *
101 * \param[in] server Server to get system name for
102 *
103 * \return System name for server (or NULL if invalid)
104 * \note If \p server is an \c enum pcmk_ipc_server value other than
105 * \c pcmk_ipc_unknown, the return value is guaranteed to be non-NULL.
106 */
107 const char *
108 pcmk__server_name(enum pcmk_ipc_server server)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
109 {
110 CRM_CHECK((server > 0) && (server < PCMK__NELEM(server_info)),
111 return NULL);
112 return server_info[server].system_names[0];
113 }
114
115 /*!
116 * \internal
117 * \brief Return a readable description of server for logging
118 *
119 * \param[in] server Server to get log name for
120 *
121 * \return Log name for server (or NULL if invalid)
122 * \note If \p server is an \c enum pcmk_ipc_server value other than
123 * \c pcmk_ipc_unknown, the return value is guaranteed to be non-NULL.
124 */
125 const char *
126 pcmk__server_log_name(enum pcmk_ipc_server server)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
127 {
128 CRM_CHECK((server > 0) && (server < PCMK__NELEM(server_info)),
129 return NULL);
130 return server_info[server].log_name;
131 }
132
133 /*!
134 * \internal
135 * \brief Return the (primary) IPC endpoint name for a server
136 *
137 * \param[in] server Server to get IPC endpoint for
138 *
139 * \return IPC endpoint for server (or NULL if invalid)
140 * \note If \p server is an \c enum pcmk_ipc_server value other than
141 * \c pcmk_ipc_unknown, the return value is guaranteed to be non-NULL.
142 */
143 const char *
144 pcmk__server_ipc_name(enum pcmk_ipc_server server)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
145 {
146 CRM_CHECK((server > 0) && (server < PCMK__NELEM(server_info)),
147 return NULL);
148 return server_info[server].ipc_names[0];
149 }
150
151 /*!
152 * \internal
153 * \brief Return the (primary) message type for a server
154 *
155 * \param[in] server Server to get message type for
156 *
157 * \return Message type for server (or NULL if invalid)
158 * \note If \p server is an \c enum pcmk_ipc_server value other than
159 * \c pcmk_ipc_unknown, the return value is guaranteed to be non-NULL.
160 */
161 const char *
162 pcmk__server_message_type(enum pcmk_ipc_server server)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
163 {
164 CRM_CHECK((server > 0) && (server < PCMK__NELEM(server_info)),
165 return NULL);
166 return server_info[server].message_types[0];
167 }
168
169 /*!
170 * \internal
171 * \brief Get the server corresponding to a name
172 *
173 * \param[in] text A system name, IPC endpoint name, or message type
174 *
175 * \return Server corresponding to \p text
176 */
177 enum pcmk_ipc_server
178 pcmk__parse_server(const char *text)
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
179 {
180 if (text == NULL) {
181 return pcmk_ipc_unknown;
182 }
183 for (enum pcmk_ipc_server server = pcmk_ipc_attrd;
184 server <= pcmk_ipc_schedulerd; ++server) {
185
186 int name;
187
188 for (name = 0;
189 (name < 2) && (server_info[server].system_names[name] != NULL);
190 ++name) {
191 if (strcmp(text, server_info[server].system_names[name]) == 0) {
192 return server;
193 }
194 }
195 for (name = 0;
196 (name < 3) && (server_info[server].ipc_names[name] != NULL);
197 ++name) {
198 if (strcmp(text, server_info[server].ipc_names[name]) == 0) {
199 return server;
200 }
201 }
202 for (name = 0;
203 (name < 3) && (server_info[server].message_types[name] != NULL);
204 ++name) {
205 if (strcmp(text, server_info[server].message_types[name]) == 0) {
206 return server;
207 }
208 }
209 }
210 return pcmk_ipc_unknown;
211 }