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