This source file includes following definitions.
- handle_unknown_request
- handle_clear_failure_request
- handle_confirm_request
- handle_flush_request
- handle_query_request
- handle_remove_request
- handle_refresh_request
- handle_sync_request
- handle_sync_response_request
- handle_update_request
- attrd_register_handlers
- attrd_unregister_handlers
- attrd_handle_request
- attrd_broadcast_protocol
- attrd_send_message
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <glib.h>
13
14 #include <crm/common/messages_internal.h>
15 #include <crm/msg_xml.h>
16
17 #include "pacemaker-attrd.h"
18
19 int minimum_protocol_version = -1;
20
21 static GHashTable *attrd_handlers = NULL;
22
23 static xmlNode *
24 handle_unknown_request(pcmk__request_t *request)
25 {
26 crm_err("Unknown IPC request %s from %s %s",
27 request->op, pcmk__request_origin_type(request),
28 pcmk__request_origin(request));
29 pcmk__format_result(&request->result, CRM_EX_PROTOCOL, PCMK_EXEC_INVALID,
30 "Unknown request type '%s' (bug?)", request->op);
31 return NULL;
32 }
33
34 static xmlNode *
35 handle_clear_failure_request(pcmk__request_t *request)
36 {
37 if (request->peer != NULL) {
38
39
40
41 attrd_peer_clear_failure(request);
42 pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
43 return NULL;
44 } else {
45 if (attrd_request_has_sync_point(request->xml)) {
46
47
48
49
50
51
52
53 attrd_add_client_to_waitlist(request);
54
55 } else {
56
57
58
59
60 attrd_send_ack(request->ipc_client, request->ipc_id,
61 request->ipc_flags);
62 }
63
64 return attrd_client_clear_failure(request);
65 }
66 }
67
68 static xmlNode *
69 handle_confirm_request(pcmk__request_t *request)
70 {
71 if (request->peer != NULL) {
72 int callid;
73
74 crm_debug("Received confirmation from %s", request->peer);
75
76 if (crm_element_value_int(request->xml, XML_LRM_ATTR_CALLID, &callid) == -1) {
77 pcmk__set_result(&request->result, CRM_EX_PROTOCOL, PCMK_EXEC_INVALID,
78 "Could not get callid from XML");
79 } else {
80 attrd_handle_confirmation(callid, request->peer);
81 }
82
83 pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
84 return NULL;
85 } else {
86 return handle_unknown_request(request);
87 }
88 }
89
90 static xmlNode *
91 handle_flush_request(pcmk__request_t *request)
92 {
93 if (request->peer != NULL) {
94
95
96
97 pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
98 return NULL;
99 } else {
100 return handle_unknown_request(request);
101 }
102 }
103
104 static xmlNode *
105 handle_query_request(pcmk__request_t *request)
106 {
107 if (request->peer != NULL) {
108 return handle_unknown_request(request);
109 } else {
110 return attrd_client_query(request);
111 }
112 }
113
114 static xmlNode *
115 handle_remove_request(pcmk__request_t *request)
116 {
117 if (request->peer != NULL) {
118 const char *host = crm_element_value(request->xml, PCMK__XA_ATTR_NODE_NAME);
119 attrd_peer_remove(host, true, request->peer);
120 pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
121 return NULL;
122 } else {
123 return attrd_client_peer_remove(request);
124 }
125 }
126
127 static xmlNode *
128 handle_refresh_request(pcmk__request_t *request)
129 {
130 if (request->peer != NULL) {
131 return handle_unknown_request(request);
132 } else {
133 return attrd_client_refresh(request);
134 }
135 }
136
137 static xmlNode *
138 handle_sync_request(pcmk__request_t *request)
139 {
140 if (request->peer != NULL) {
141 crm_node_t *peer = crm_get_peer(0, request->peer);
142
143 attrd_peer_sync(peer, request->xml);
144 pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
145 return NULL;
146 } else {
147 return handle_unknown_request(request);
148 }
149 }
150
151 static xmlNode *
152 handle_sync_response_request(pcmk__request_t *request)
153 {
154 if (request->ipc_client != NULL) {
155 return handle_unknown_request(request);
156 } else {
157 if (request->peer != NULL) {
158 crm_node_t *peer = crm_get_peer(0, request->peer);
159 bool peer_won = attrd_check_for_new_writer(peer, request->xml);
160
161 if (!pcmk__str_eq(peer->uname, attrd_cluster->uname, pcmk__str_casei)) {
162 attrd_peer_sync_response(peer, peer_won, request->xml);
163 }
164 }
165
166 pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
167 return NULL;
168 }
169 }
170
171 static xmlNode *
172 handle_update_request(pcmk__request_t *request)
173 {
174 if (request->peer != NULL) {
175 const char *host = crm_element_value(request->xml, PCMK__XA_ATTR_NODE_NAME);
176 crm_node_t *peer = crm_get_peer(0, request->peer);
177
178 attrd_peer_update(peer, request->xml, host, false);
179 pcmk__set_result(&request->result, CRM_EX_OK, PCMK_EXEC_DONE, NULL);
180 return NULL;
181
182 } else {
183 if (attrd_request_has_sync_point(request->xml)) {
184
185
186
187
188
189
190
191 attrd_add_client_to_waitlist(request);
192
193 } else {
194
195
196
197
198
199
200
201
202 attrd_send_ack(request->ipc_client, request->ipc_id,
203 request->flags|crm_ipc_client_response);
204 }
205
206 return attrd_client_update(request);
207 }
208 }
209
210 static void
211 attrd_register_handlers(void)
212 {
213 pcmk__server_command_t handlers[] = {
214 { PCMK__ATTRD_CMD_CLEAR_FAILURE, handle_clear_failure_request },
215 { PCMK__ATTRD_CMD_CONFIRM, handle_confirm_request },
216 { PCMK__ATTRD_CMD_FLUSH, handle_flush_request },
217 { PCMK__ATTRD_CMD_PEER_REMOVE, handle_remove_request },
218 { PCMK__ATTRD_CMD_QUERY, handle_query_request },
219 { PCMK__ATTRD_CMD_REFRESH, handle_refresh_request },
220 { PCMK__ATTRD_CMD_SYNC, handle_sync_request },
221 { PCMK__ATTRD_CMD_SYNC_RESPONSE, handle_sync_response_request },
222 { PCMK__ATTRD_CMD_UPDATE, handle_update_request },
223 { PCMK__ATTRD_CMD_UPDATE_DELAY, handle_update_request },
224 { PCMK__ATTRD_CMD_UPDATE_BOTH, handle_update_request },
225 { NULL, handle_unknown_request },
226 };
227
228 attrd_handlers = pcmk__register_handlers(handlers);
229 }
230
231 void
232 attrd_unregister_handlers(void)
233 {
234 if (attrd_handlers != NULL) {
235 g_hash_table_destroy(attrd_handlers);
236 attrd_handlers = NULL;
237 }
238 }
239
240 void
241 attrd_handle_request(pcmk__request_t *request)
242 {
243 xmlNode *reply = NULL;
244 char *log_msg = NULL;
245 const char *reason = NULL;
246
247 if (attrd_handlers == NULL) {
248 attrd_register_handlers();
249 }
250
251 reply = pcmk__process_request(request, attrd_handlers);
252
253 if (reply != NULL) {
254 crm_log_xml_trace(reply, "Reply");
255
256 if (request->ipc_client != NULL) {
257 pcmk__ipc_send_xml(request->ipc_client, request->ipc_id, reply,
258 request->ipc_flags);
259 } else {
260 crm_err("Not sending CPG reply to client");
261 }
262
263 free_xml(reply);
264 }
265
266 reason = request->result.exit_reason;
267 log_msg = crm_strdup_printf("Processed %s request from %s %s: %s%s%s%s",
268 request->op, pcmk__request_origin_type(request),
269 pcmk__request_origin(request),
270 pcmk_exec_status_str(request->result.execution_status),
271 (reason == NULL)? "" : " (",
272 pcmk__s(reason, ""),
273 (reason == NULL)? "" : ")");
274
275 if (!pcmk__result_ok(&request->result)) {
276 crm_warn("%s", log_msg);
277 } else {
278 crm_debug("%s", log_msg);
279 }
280
281 free(log_msg);
282 pcmk__reset_request(request);
283 }
284
285
286
287
288
289 void
290 attrd_broadcast_protocol(void)
291 {
292 xmlNode *attrd_op = create_xml_node(NULL, __func__);
293
294 crm_xml_add(attrd_op, F_TYPE, T_ATTRD);
295 crm_xml_add(attrd_op, F_ORIG, crm_system_name);
296 crm_xml_add(attrd_op, PCMK__XA_TASK, PCMK__ATTRD_CMD_UPDATE);
297 crm_xml_add(attrd_op, PCMK__XA_ATTR_NAME, CRM_ATTR_PROTOCOL);
298 crm_xml_add(attrd_op, PCMK__XA_ATTR_VALUE, ATTRD_PROTOCOL_VERSION);
299 crm_xml_add_int(attrd_op, PCMK__XA_ATTR_IS_PRIVATE, 1);
300 pcmk__xe_add_node(attrd_op, attrd_cluster->uname, attrd_cluster->nodeid);
301
302 crm_debug("Broadcasting attrd protocol version %s for node %s",
303 ATTRD_PROTOCOL_VERSION, attrd_cluster->uname);
304
305 attrd_send_message(NULL, attrd_op, false);
306
307 free_xml(attrd_op);
308 }
309
310 gboolean
311 attrd_send_message(crm_node_t *node, xmlNode *data, bool confirm)
312 {
313 const char *op = crm_element_value(data, PCMK__XA_TASK);
314
315 crm_xml_add(data, F_TYPE, T_ATTRD);
316 crm_xml_add(data, PCMK__XA_ATTR_VERSION, ATTRD_PROTOCOL_VERSION);
317
318
319
320
321
322 if (!pcmk__str_eq(op, PCMK__ATTRD_CMD_CONFIRM, pcmk__str_none)) {
323 pcmk__xe_set_bool_attr(data, PCMK__XA_CONFIRM, confirm);
324 }
325
326 attrd_xml_add_writer(data);
327 return send_cluster_message(node, crm_msg_attrd, data, TRUE);
328 }