This source file includes following definitions.
- alert_key2param
- alert_key2param_int
- alert_key2param_ms
- set_ev_kv
- alert_envvar2params
- is_target_alert
- exec_alert_list
- lrmd_send_attribute_alert
- lrmd_send_node_alert
- lrmd_send_fencing_alert
- lrmd_send_resource_alert
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 #include <crm/common/alerts_internal.h>
20 #include <crm/lrmd_internal.h>
21
22 #include <crm/pengine/status.h>
23 #include <crm/cib.h>
24 #include <crm/lrmd.h>
25
26 static lrmd_key_value_t *
27 alert_key2param(lrmd_key_value_t *head, enum pcmk__alert_keys_e name,
28 const char *value)
29 {
30 const char **key;
31
32 if (value == NULL) {
33 value = "";
34 }
35 for (key = pcmk__alert_keys[name]; *key; key++) {
36 crm_trace("Setting alert key %s = '%s'", *key, value);
37 head = lrmd_key_value_add(head, *key, value);
38 }
39 return head;
40 }
41
42 static lrmd_key_value_t *
43 alert_key2param_int(lrmd_key_value_t *head, enum pcmk__alert_keys_e name,
44 int value)
45 {
46 char *value_s = pcmk__itoa(value);
47
48 head = alert_key2param(head, name, value_s);
49 free(value_s);
50 return head;
51 }
52
53 static lrmd_key_value_t *
54 alert_key2param_ms(lrmd_key_value_t *head, enum pcmk__alert_keys_e name,
55 guint value)
56 {
57 char *value_s = crm_strdup_printf("%u", value);
58
59 head = alert_key2param(head, name, value_s);
60 free(value_s);
61 return head;
62 }
63
64 static void
65 set_ev_kv(gpointer key, gpointer value, gpointer user_data)
66 {
67 lrmd_key_value_t **head = (lrmd_key_value_t **) user_data;
68
69 if (value) {
70 crm_trace("Setting environment variable %s='%s'",
71 (char*)key, (char*)value);
72 *head = lrmd_key_value_add(*head, key, value);
73 }
74 }
75
76 static lrmd_key_value_t *
77 alert_envvar2params(lrmd_key_value_t *head, const pcmk__alert_t *entry)
78 {
79 if (entry->envvars) {
80 g_hash_table_foreach(entry->envvars, set_ev_kv, &head);
81 }
82 return head;
83 }
84
85
86
87
88
89 static gboolean
90 is_target_alert(char **list, const char *value)
91 {
92 int target_list_num = 0;
93 gboolean rc = FALSE;
94
95 CRM_CHECK(value != NULL, return FALSE);
96
97 if (list == NULL) {
98 return TRUE;
99 }
100
101 target_list_num = g_strv_length(list);
102
103 for (int cnt = 0; cnt < target_list_num; cnt++) {
104 if (strcmp(list[cnt], value) == 0) {
105 rc = TRUE;
106 break;
107 }
108 }
109 return rc;
110 }
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126 static int
127 exec_alert_list(lrmd_t *lrmd, const GList *alert_list,
128 enum pcmk__alert_flags kind, const char *attr_name,
129 lrmd_key_value_t *params)
130 {
131 bool any_success = FALSE, any_failure = FALSE;
132 const char *kind_s = pcmk__alert_flag2text(kind);
133 pcmk__time_hr_t *now = NULL;
134 char timestamp_epoch[20];
135 char timestamp_usec[7];
136 time_t epoch = 0;
137
138 params = alert_key2param(params, PCMK__alert_key_kind, kind_s);
139 params = alert_key2param(params, PCMK__alert_key_version,
140 PACEMAKER_VERSION);
141
142 for (const GList *iter = alert_list;
143 iter != NULL; iter = g_list_next(iter)) {
144 const pcmk__alert_t *entry = (pcmk__alert_t *) (iter->data);
145 lrmd_key_value_t *copy_params = NULL;
146 lrmd_key_value_t *head = NULL;
147 int rc;
148
149 if (!pcmk_is_set(entry->flags, kind)) {
150 crm_trace("Filtering unwanted %s alert to %s via %s",
151 kind_s, entry->recipient, entry->id);
152 continue;
153 }
154
155 if ((kind == pcmk__alert_attribute)
156 && !is_target_alert(entry->select_attribute_name, attr_name)) {
157
158 crm_trace("Filtering unwanted attribute '%s' alert to %s via %s",
159 attr_name, entry->recipient, entry->id);
160 continue;
161 }
162
163 if (now == NULL) {
164 now = pcmk__time_hr_now(&epoch);
165 }
166 crm_info("Sending %s alert via %s to %s",
167 kind_s, entry->id, entry->recipient);
168
169
170 for (head = params; head != NULL; head = head->next) {
171 copy_params = lrmd_key_value_add(copy_params, head->key, head->value);
172 }
173
174 copy_params = alert_key2param(copy_params, PCMK__alert_key_recipient,
175 entry->recipient);
176
177 if (now) {
178 char *timestamp = pcmk__time_format_hr(entry->tstamp_format, now);
179
180 if (timestamp) {
181 copy_params = alert_key2param(copy_params,
182 PCMK__alert_key_timestamp,
183 timestamp);
184 free(timestamp);
185 }
186
187 snprintf(timestamp_epoch, sizeof(timestamp_epoch), "%lld",
188 (long long) epoch);
189 copy_params = alert_key2param(copy_params,
190 PCMK__alert_key_timestamp_epoch,
191 timestamp_epoch);
192 snprintf(timestamp_usec, sizeof(timestamp_usec), "%06d", now->useconds);
193 copy_params = alert_key2param(copy_params,
194 PCMK__alert_key_timestamp_usec,
195 timestamp_usec);
196 }
197
198 copy_params = alert_envvar2params(copy_params, entry);
199
200 rc = lrmd->cmds->exec_alert(lrmd, entry->id, entry->path,
201 entry->timeout, copy_params);
202 if (rc < 0) {
203 crm_err("Could not execute alert %s: %s " CRM_XS " rc=%d",
204 entry->id, pcmk_strerror(rc), rc);
205 any_failure = TRUE;
206 } else {
207 any_success = TRUE;
208 }
209 }
210
211 if (now) {
212 free(now);
213 }
214
215 if (any_failure) {
216 return (any_success? -1 : -2);
217 }
218 return pcmk_ok;
219 }
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236 int
237 lrmd_send_attribute_alert(lrmd_t *lrmd, const GList *alert_list,
238 const char *node, uint32_t nodeid,
239 const char *attr_name, const char *attr_value)
240 {
241 int rc = pcmk_ok;
242 lrmd_key_value_t *params = NULL;
243
244 if (lrmd == NULL) {
245 return -2;
246 }
247
248 params = alert_key2param(params, PCMK__alert_key_node, node);
249 params = alert_key2param_int(params, PCMK__alert_key_nodeid, nodeid);
250 params = alert_key2param(params, PCMK__alert_key_attribute_name, attr_name);
251 params = alert_key2param(params, PCMK__alert_key_attribute_value,
252 attr_value);
253
254 rc = exec_alert_list(lrmd, alert_list, pcmk__alert_attribute, attr_name,
255 params);
256 lrmd_key_value_freeall(params);
257 return rc;
258 }
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274 int
275 lrmd_send_node_alert(lrmd_t *lrmd, const GList *alert_list,
276 const char *node, uint32_t nodeid, const char *state)
277 {
278 int rc = pcmk_ok;
279 lrmd_key_value_t *params = NULL;
280
281 if (lrmd == NULL) {
282 return -2;
283 }
284
285 params = alert_key2param(params, PCMK__alert_key_node, node);
286 params = alert_key2param(params, PCMK__alert_key_desc, state);
287 params = alert_key2param_int(params, PCMK__alert_key_nodeid, nodeid);
288
289 rc = exec_alert_list(lrmd, alert_list, pcmk__alert_node, NULL, params);
290 lrmd_key_value_freeall(params);
291 return rc;
292 }
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309 int
310 lrmd_send_fencing_alert(lrmd_t *lrmd, const GList *alert_list,
311 const char *target, const char *task, const char *desc,
312 int op_rc)
313 {
314 int rc = pcmk_ok;
315 lrmd_key_value_t *params = NULL;
316
317 if (lrmd == NULL) {
318 return -2;
319 }
320
321 params = alert_key2param(params, PCMK__alert_key_node, target);
322 params = alert_key2param(params, PCMK__alert_key_task, task);
323 params = alert_key2param(params, PCMK__alert_key_desc, desc);
324 params = alert_key2param_int(params, PCMK__alert_key_rc, op_rc);
325
326 rc = exec_alert_list(lrmd, alert_list, pcmk__alert_fencing, NULL, params);
327 lrmd_key_value_freeall(params);
328 return rc;
329 }
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344 int
345 lrmd_send_resource_alert(lrmd_t *lrmd, const GList *alert_list,
346 const char *node, const lrmd_event_data_t *op)
347 {
348 int rc = pcmk_ok;
349 int target_rc = pcmk_ok;
350 lrmd_key_value_t *params = NULL;
351
352 if (lrmd == NULL) {
353 return -2;
354 }
355
356 target_rc = rsc_op_expected_rc(op);
357 if ((op->interval_ms == 0) && (target_rc == op->rc)
358 && pcmk__str_eq(op->op_type, RSC_STATUS, pcmk__str_casei)) {
359
360
361
362
363
364
365 return pcmk_ok;
366 }
367
368 params = alert_key2param(params, PCMK__alert_key_node, node);
369 params = alert_key2param(params, PCMK__alert_key_rsc, op->rsc_id);
370 params = alert_key2param(params, PCMK__alert_key_task, op->op_type);
371 params = alert_key2param_ms(params, PCMK__alert_key_interval,
372 op->interval_ms);
373 params = alert_key2param_int(params, PCMK__alert_key_target_rc, target_rc);
374 params = alert_key2param_int(params, PCMK__alert_key_status, op->op_status);
375 params = alert_key2param_int(params, PCMK__alert_key_rc, op->rc);
376
377
378
379
380 if ((op->op_status == PCMK_EXEC_TIMEOUT) && (op->exec_time == 0)) {
381 params = alert_key2param_int(params, PCMK__alert_key_exec_time,
382 op->timeout);
383 } else {
384 params = alert_key2param_int(params, PCMK__alert_key_exec_time,
385 op->exec_time);
386 }
387
388 if (op->op_status == PCMK_EXEC_DONE) {
389 params = alert_key2param(params, PCMK__alert_key_desc,
390 services_ocf_exitcode_str(op->rc));
391 } else {
392 params = alert_key2param(params, PCMK__alert_key_desc,
393 pcmk_exec_status_str(op->op_status));
394 }
395
396 rc = exec_alert_list(lrmd, alert_list, pcmk__alert_resource, NULL, params);
397 lrmd_key_value_freeall(params);
398 return rc;
399 }