This source file includes following definitions.
- alert_key2param
- alert_key2param_int
- 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
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 #include <crm/common/alerts_internal.h>
30 #include <crm/common/iso8601_internal.h>
31 #include <crm/lrmd_alerts_internal.h>
32
33 #include <crm/pengine/status.h>
34 #include <crm/cib.h>
35 #include <crm/lrmd.h>
36
37 static lrmd_key_value_t *
38 alert_key2param(lrmd_key_value_t *head, enum crm_alert_keys_e name,
39 const char *value)
40 {
41 const char **key;
42
43 if (value == NULL) {
44 value = "";
45 }
46 for (key = crm_alert_keys[name]; *key; key++) {
47 crm_trace("Setting alert key %s = '%s'", *key, value);
48 head = lrmd_key_value_add(head, *key, value);
49 }
50 return head;
51 }
52
53 static lrmd_key_value_t *
54 alert_key2param_int(lrmd_key_value_t *head, enum crm_alert_keys_e name,
55 int value)
56 {
57 char *value_s = crm_itoa(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, crm_alert_entry_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, GList *alert_list, enum crm_alert_flags kind,
128 const char *attr_name, lrmd_key_value_t *params)
129 {
130 bool any_success = FALSE, any_failure = FALSE;
131 const char *kind_s = crm_alert_flag2text(kind);
132 crm_time_hr_t *now = NULL;
133
134 params = alert_key2param(params, CRM_alert_kind, kind_s);
135 params = alert_key2param(params, CRM_alert_version, VERSION);
136
137 for (GList *iter = g_list_first(alert_list); iter; iter = g_list_next(iter)) {
138 crm_alert_entry_t *entry = (crm_alert_entry_t *)(iter->data);
139 lrmd_key_value_t *copy_params = NULL;
140 lrmd_key_value_t *head = NULL;
141 int rc;
142
143 if (is_not_set(entry->flags, kind)) {
144 crm_trace("Filtering unwanted %s alert to %s via %s",
145 kind_s, entry->recipient, entry->id);
146 continue;
147 }
148
149 if ((kind == crm_alert_attribute)
150 && !is_target_alert(entry->select_attribute_name, attr_name)) {
151
152 crm_trace("Filtering unwanted attribute '%s' alert to %s via %s",
153 attr_name, entry->recipient, entry->id);
154 continue;
155 }
156
157 if (now == NULL) {
158 now = crm_time_hr_new(NULL);
159 }
160 crm_info("Sending %s alert via %s to %s",
161 kind_s, entry->id, entry->recipient);
162
163
164 for (head = params; head != NULL; head = head->next) {
165 copy_params = lrmd_key_value_add(copy_params, head->key, head->value);
166 }
167
168 copy_params = alert_key2param(copy_params, CRM_alert_recipient,
169 entry->recipient);
170
171 if (now) {
172 char *timestamp = crm_time_format_hr(entry->tstamp_format, now);
173
174 if (timestamp) {
175 copy_params = alert_key2param(copy_params, CRM_alert_timestamp,
176 timestamp);
177 free(timestamp);
178 }
179 }
180
181 copy_params = alert_envvar2params(copy_params, entry);
182
183 rc = lrmd->cmds->exec_alert(lrmd, entry->id, entry->path,
184 entry->timeout, copy_params);
185 if (rc < 0) {
186 crm_err("Could not execute alert %s: %s " CRM_XS " rc=%d",
187 entry->id, pcmk_strerror(rc), rc);
188 any_failure = TRUE;
189 } else {
190 any_success = TRUE;
191 }
192 }
193
194 if (now) {
195 free(now);
196 }
197
198 if (any_failure) {
199 return (any_success? -1 : -2);
200 }
201 return pcmk_ok;
202 }
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219 int
220 lrmd_send_attribute_alert(lrmd_t *lrmd, GList *alert_list,
221 const char *node, uint32_t nodeid,
222 const char *attr_name, const char *attr_value)
223 {
224 int rc = pcmk_ok;
225 lrmd_key_value_t *params = NULL;
226
227 if (lrmd == NULL) {
228 return -2;
229 }
230
231 params = alert_key2param(params, CRM_alert_node, node);
232 params = alert_key2param_int(params, CRM_alert_nodeid, nodeid);
233 params = alert_key2param(params, CRM_alert_attribute_name, attr_name);
234 params = alert_key2param(params, CRM_alert_attribute_value, attr_value);
235
236 rc = exec_alert_list(lrmd, alert_list, crm_alert_attribute, attr_name,
237 params);
238 lrmd_key_value_freeall(params);
239 return rc;
240 }
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256 int
257 lrmd_send_node_alert(lrmd_t *lrmd, GList *alert_list,
258 const char *node, uint32_t nodeid, const char *state)
259 {
260 int rc = pcmk_ok;
261 lrmd_key_value_t *params = NULL;
262
263 if (lrmd == NULL) {
264 return -2;
265 }
266
267 params = alert_key2param(params, CRM_alert_node, node);
268 params = alert_key2param(params, CRM_alert_desc, state);
269 params = alert_key2param_int(params, CRM_alert_nodeid, nodeid);
270
271 rc = exec_alert_list(lrmd, alert_list, crm_alert_node, NULL, params);
272 lrmd_key_value_freeall(params);
273 return rc;
274 }
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291 int
292 lrmd_send_fencing_alert(lrmd_t *lrmd, GList *alert_list,
293 const char *target, const char *task, const char *desc,
294 int op_rc)
295 {
296 int rc = pcmk_ok;
297 lrmd_key_value_t *params = NULL;
298
299 if (lrmd == NULL) {
300 return -2;
301 }
302
303 params = alert_key2param(params, CRM_alert_node, target);
304 params = alert_key2param(params, CRM_alert_task, task);
305 params = alert_key2param(params, CRM_alert_desc, desc);
306 params = alert_key2param_int(params, CRM_alert_rc, op_rc);
307
308 rc = exec_alert_list(lrmd, alert_list, crm_alert_fencing, NULL, params);
309 lrmd_key_value_freeall(params);
310 return rc;
311 }
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326 int
327 lrmd_send_resource_alert(lrmd_t *lrmd, GList *alert_list,
328 const char *node, lrmd_event_data_t *op)
329 {
330 int rc = pcmk_ok;
331 int target_rc = pcmk_ok;
332 lrmd_key_value_t *params = NULL;
333
334 if (lrmd == NULL) {
335 return -2;
336 }
337
338 target_rc = rsc_op_expected_rc(op);
339 if ((op->interval == 0) && (target_rc == op->rc)
340 && safe_str_eq(op->op_type, RSC_STATUS)) {
341
342
343
344
345
346
347 return pcmk_ok;
348 }
349
350 params = alert_key2param(params, CRM_alert_node, node);
351 params = alert_key2param(params, CRM_alert_rsc, op->rsc_id);
352 params = alert_key2param(params, CRM_alert_task, op->op_type);
353 params = alert_key2param_int(params, CRM_alert_interval, op->interval);
354 params = alert_key2param_int(params, CRM_alert_target_rc, target_rc);
355 params = alert_key2param_int(params, CRM_alert_status, op->op_status);
356 params = alert_key2param_int(params, CRM_alert_rc, op->rc);
357
358 if (op->op_status == PCMK_LRM_OP_DONE) {
359 params = alert_key2param(params, CRM_alert_desc, services_ocf_exitcode_str(op->rc));
360 } else {
361 params = alert_key2param(params, CRM_alert_desc, services_lrm_status_str(op->op_status));
362 }
363
364 rc = exec_alert_list(lrmd, alert_list, crm_alert_resource, NULL, params);
365 lrmd_key_value_freeall(params);
366 return rc;
367 }