This source file includes following definitions.
- remote_proxy_notify_destroy
- remote_proxy_ack_shutdown
- remote_proxy_nack_shutdown
- remote_proxy_relay_event
- remote_proxy_relay_response
- remote_proxy_end_session
- remote_proxy_free
- remote_proxy_dispatch
- remote_proxy_disconnected
- remote_proxy_new
- remote_proxy_cb
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <glib.h>
13 #include <unistd.h>
14
15 #include <crm/crm.h>
16 #include <crm/msg_xml.h>
17 #include <crm/services.h>
18 #include <crm/common/mainloop.h>
19
20 #include <crm/pengine/status.h>
21 #include <crm/cib.h>
22 #include <crm/lrmd.h>
23 #include <crm/lrmd_internal.h>
24
25 int lrmd_internal_proxy_send(lrmd_t * lrmd, xmlNode *msg);
26 GHashTable *proxy_table = NULL;
27
28 static void
29 remote_proxy_notify_destroy(lrmd_t *lrmd, const char *session_id)
30 {
31
32 xmlNode *msg = create_xml_node(NULL, T_LRMD_IPC_PROXY);
33 crm_xml_add(msg, F_LRMD_IPC_OP, LRMD_IPC_OP_DESTROY);
34 crm_xml_add(msg, F_LRMD_IPC_SESSION, session_id);
35 lrmd_internal_proxy_send(lrmd, msg);
36 free_xml(msg);
37 }
38
39
40
41
42
43
44
45 void
46 remote_proxy_ack_shutdown(lrmd_t *lrmd)
47 {
48 xmlNode *msg = create_xml_node(NULL, T_LRMD_IPC_PROXY);
49 crm_xml_add(msg, F_LRMD_IPC_OP, LRMD_IPC_OP_SHUTDOWN_ACK);
50 lrmd_internal_proxy_send(lrmd, msg);
51 free_xml(msg);
52 }
53
54
55
56
57
58
59
60 void
61 remote_proxy_nack_shutdown(lrmd_t *lrmd)
62 {
63 xmlNode *msg = create_xml_node(NULL, T_LRMD_IPC_PROXY);
64 crm_xml_add(msg, F_LRMD_IPC_OP, LRMD_IPC_OP_SHUTDOWN_NACK);
65 lrmd_internal_proxy_send(lrmd, msg);
66 free_xml(msg);
67 }
68
69 void
70 remote_proxy_relay_event(remote_proxy_t *proxy, xmlNode *msg)
71 {
72
73 xmlNode *event = create_xml_node(NULL, T_LRMD_IPC_PROXY);
74 crm_xml_add(event, F_LRMD_IPC_OP, LRMD_IPC_OP_EVENT);
75 crm_xml_add(event, F_LRMD_IPC_SESSION, proxy->session_id);
76 add_message_xml(event, F_LRMD_IPC_MSG, msg);
77 crm_log_xml_explicit(event, "EventForProxy");
78 lrmd_internal_proxy_send(proxy->lrm, event);
79 free_xml(event);
80 }
81
82 void
83 remote_proxy_relay_response(remote_proxy_t *proxy, xmlNode *msg, int msg_id)
84 {
85
86 xmlNode *response = create_xml_node(NULL, T_LRMD_IPC_PROXY);
87 crm_xml_add(response, F_LRMD_IPC_OP, LRMD_IPC_OP_RESPONSE);
88 crm_xml_add(response, F_LRMD_IPC_SESSION, proxy->session_id);
89 crm_xml_add_int(response, F_LRMD_IPC_MSG_ID, msg_id);
90 add_message_xml(response, F_LRMD_IPC_MSG, msg);
91 lrmd_internal_proxy_send(proxy->lrm, response);
92 free_xml(response);
93 }
94
95 static void
96 remote_proxy_end_session(remote_proxy_t *proxy)
97 {
98 if (proxy == NULL) {
99 return;
100 }
101 crm_trace("ending session ID %s", proxy->session_id);
102
103 if (proxy->source) {
104 mainloop_del_ipc_client(proxy->source);
105 }
106 }
107
108 void
109 remote_proxy_free(gpointer data)
110 {
111 remote_proxy_t *proxy = data;
112
113 crm_trace("freed proxy session ID %s", proxy->session_id);
114 free(proxy->node_name);
115 free(proxy->session_id);
116 free(proxy);
117 }
118
119 int
120 remote_proxy_dispatch(const char *buffer, ssize_t length, gpointer userdata)
121 {
122
123 xmlNode *xml = NULL;
124 uint32_t flags = 0;
125 remote_proxy_t *proxy = userdata;
126
127 xml = string2xml(buffer);
128 if (xml == NULL) {
129 crm_warn("Received a NULL msg from IPC service.");
130 return 1;
131 }
132
133 flags = crm_ipc_buffer_flags(proxy->ipc);
134 if (flags & crm_ipc_proxied_relay_response) {
135 crm_trace("Passing response back to %.8s on %s: %.200s - request id: %d", proxy->session_id, proxy->node_name, buffer, proxy->last_request_id);
136 remote_proxy_relay_response(proxy, xml, proxy->last_request_id);
137 proxy->last_request_id = 0;
138
139 } else {
140 crm_trace("Passing event back to %.8s on %s: %.200s", proxy->session_id, proxy->node_name, buffer);
141 remote_proxy_relay_event(proxy, xml);
142 }
143 free_xml(xml);
144 return 1;
145 }
146
147
148 void
149 remote_proxy_disconnected(gpointer userdata)
150 {
151 remote_proxy_t *proxy = userdata;
152
153 crm_trace("destroying %p", proxy);
154
155 proxy->source = NULL;
156 proxy->ipc = NULL;
157
158 if(proxy->lrm) {
159 remote_proxy_notify_destroy(proxy->lrm, proxy->session_id);
160 proxy->lrm = NULL;
161 }
162
163 g_hash_table_remove(proxy_table, proxy->session_id);
164 }
165
166 remote_proxy_t *
167 remote_proxy_new(lrmd_t *lrmd, struct ipc_client_callbacks *proxy_callbacks,
168 const char *node_name, const char *session_id, const char *channel)
169 {
170 remote_proxy_t *proxy = NULL;
171
172 if(channel == NULL) {
173 crm_err("No channel specified to proxy");
174 remote_proxy_notify_destroy(lrmd, session_id);
175 return NULL;
176 }
177
178 proxy = calloc(1, sizeof(remote_proxy_t));
179
180 proxy->node_name = strdup(node_name);
181 proxy->session_id = strdup(session_id);
182 proxy->lrm = lrmd;
183
184 if (!strcmp(pcmk__message_name(crm_system_name), CRM_SYSTEM_CRMD)
185 && !strcmp(pcmk__message_name(channel), CRM_SYSTEM_CRMD)) {
186
187 proxy->is_local = TRUE;
188
189 } else {
190 proxy->source = mainloop_add_ipc_client(channel, G_PRIORITY_LOW, 0, proxy, proxy_callbacks);
191 proxy->ipc = mainloop_get_ipc_client(proxy->source);
192 if (proxy->source == NULL) {
193 remote_proxy_free(proxy);
194 remote_proxy_notify_destroy(lrmd, session_id);
195 return NULL;
196 }
197 }
198
199 crm_trace("new remote proxy client established to %s on %s, session id %s",
200 channel, node_name, session_id);
201 g_hash_table_insert(proxy_table, proxy->session_id, proxy);
202
203 return proxy;
204 }
205
206 void
207 remote_proxy_cb(lrmd_t *lrmd, const char *node_name, xmlNode *msg)
208 {
209 const char *op = crm_element_value(msg, F_LRMD_IPC_OP);
210 const char *session = crm_element_value(msg, F_LRMD_IPC_SESSION);
211 remote_proxy_t *proxy = g_hash_table_lookup(proxy_table, session);
212 int msg_id = 0;
213
214
215
216
217
218 CRM_CHECK(op != NULL, return);
219 CRM_CHECK(session != NULL, return);
220
221 crm_element_value_int(msg, F_LRMD_IPC_MSG_ID, &msg_id);
222
223
224 if (pcmk__str_eq(op, LRMD_IPC_OP_DESTROY, pcmk__str_casei)) {
225 remote_proxy_end_session(proxy);
226
227 } else if (pcmk__str_eq(op, LRMD_IPC_OP_REQUEST, pcmk__str_casei)) {
228 int flags = 0;
229 xmlNode *request = get_message_xml(msg, F_LRMD_IPC_MSG);
230 const char *name = crm_element_value(msg, F_LRMD_IPC_CLIENT);
231
232 CRM_CHECK(request != NULL, return);
233
234 if (proxy == NULL) {
235
236 remote_proxy_notify_destroy(lrmd, session);
237 return;
238 }
239
240
241 CRM_CHECK(proxy->is_local == FALSE,
242 remote_proxy_end_session(proxy); return);
243
244 if (!crm_ipc_connected(proxy->ipc)) {
245 remote_proxy_end_session(proxy);
246 return;
247 }
248 proxy->last_request_id = 0;
249 crm_element_value_int(msg, F_LRMD_IPC_MSG_FLAGS, &flags);
250 crm_xml_add(request, XML_ACL_TAG_ROLE, "pacemaker-remote");
251
252 CRM_ASSERT(node_name);
253 pcmk__update_acl_user(request, F_LRMD_IPC_USER, node_name);
254
255 if (pcmk_is_set(flags, crm_ipc_proxied)) {
256 const char *type = crm_element_value(request, F_TYPE);
257 int rc = 0;
258
259 if (pcmk__str_eq(type, T_ATTRD, pcmk__str_casei)
260 && crm_element_value(request,
261 PCMK__XA_ATTR_NODE_NAME) == NULL
262 && pcmk__str_any_of(crm_element_value(request, PCMK__XA_TASK),
263 PCMK__ATTRD_CMD_UPDATE,
264 PCMK__ATTRD_CMD_UPDATE_BOTH,
265 PCMK__ATTRD_CMD_UPDATE_DELAY, NULL)) {
266 pcmk__xe_add_node(request, proxy->node_name, 0);
267 }
268
269 rc = crm_ipc_send(proxy->ipc, request, flags, 5000, NULL);
270
271 if(rc < 0) {
272 xmlNode *op_reply = create_xml_node(NULL, "nack");
273
274 crm_err("Could not relay %s request %d from %s to %s for %s: %s (%d)",
275 op, msg_id, proxy->node_name, crm_ipc_name(proxy->ipc), name, pcmk_strerror(rc), rc);
276
277
278 crm_xml_add(op_reply, "function", __func__);
279 crm_xml_add_int(op_reply, "line", __LINE__);
280 crm_xml_add_int(op_reply, "rc", rc);
281 remote_proxy_relay_response(proxy, op_reply, msg_id);
282 free_xml(op_reply);
283
284 } else {
285 crm_trace("Relayed %s request %d from %s to %s for %s",
286 op, msg_id, proxy->node_name, crm_ipc_name(proxy->ipc), name);
287 proxy->last_request_id = msg_id;
288 }
289
290 } else {
291 int rc = pcmk_ok;
292 xmlNode *op_reply = NULL;
293
294
295 crm_trace("Relaying %s request %d from %s to %s for %s",
296 op, msg_id, proxy->node_name, crm_ipc_name(proxy->ipc), name);
297
298 rc = crm_ipc_send(proxy->ipc, request, flags, 10000, &op_reply);
299 if(rc < 0) {
300 crm_err("Could not relay %s request %d from %s to %s for %s: %s (%d)",
301 op, msg_id, proxy->node_name, crm_ipc_name(proxy->ipc), name, pcmk_strerror(rc), rc);
302 } else {
303 crm_trace("Relayed %s request %d from %s to %s for %s",
304 op, msg_id, proxy->node_name, crm_ipc_name(proxy->ipc), name);
305 }
306
307 if(op_reply) {
308 remote_proxy_relay_response(proxy, op_reply, msg_id);
309 free_xml(op_reply);
310 }
311 }
312 } else {
313 crm_err("Unknown proxy operation: %s", op);
314 }
315 }