This source file includes following definitions.
- get_meta_attrs_from_cib
- get_envvars_from_cib
- unpack_alert_filter
- unpack_alert
- pe_unpack_alerts
- pe_free_alert_list
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11 #include <crm/crm.h>
12 #include <crm/msg_xml.h>
13 #include <crm/pengine/rules.h>
14 #include <crm/common/alerts_internal.h>
15 #include <crm/common/xml_internal.h>
16 #include <crm/pengine/rules_internal.h>
17
18 static void
19 get_meta_attrs_from_cib(xmlNode *basenode, pcmk__alert_t *entry,
20 guint *max_timeout)
21 {
22 GHashTable *config_hash = pcmk__strkey_table(free, free);
23 crm_time_t *now = crm_time_new(NULL);
24 const char *value = NULL;
25
26 pe_unpack_nvpairs(basenode, basenode, XML_TAG_META_SETS, NULL, config_hash,
27 NULL, FALSE, now, NULL);
28 crm_time_free(now);
29
30 value = g_hash_table_lookup(config_hash, XML_ALERT_ATTR_TIMEOUT);
31 if (value) {
32 entry->timeout = crm_get_msec(value);
33 if (entry->timeout <= 0) {
34 if (entry->timeout == 0) {
35 crm_trace("Alert %s uses default timeout of %dmsec",
36 entry->id, PCMK__ALERT_DEFAULT_TIMEOUT_MS);
37 } else {
38 crm_warn("Alert %s has invalid timeout value '%s', using default %dmsec",
39 entry->id, (char*)value, PCMK__ALERT_DEFAULT_TIMEOUT_MS);
40 }
41 entry->timeout = PCMK__ALERT_DEFAULT_TIMEOUT_MS;
42 } else {
43 crm_trace("Alert %s uses timeout of %dmsec",
44 entry->id, entry->timeout);
45 }
46 if (entry->timeout > *max_timeout) {
47 *max_timeout = entry->timeout;
48 }
49 }
50 value = g_hash_table_lookup(config_hash, XML_ALERT_ATTR_TSTAMP_FORMAT);
51 if (value) {
52
53
54
55 entry->tstamp_format = strdup(value);
56 crm_trace("Alert %s uses timestamp format '%s'",
57 entry->id, entry->tstamp_format);
58 }
59
60 g_hash_table_destroy(config_hash);
61 }
62
63 static void
64 get_envvars_from_cib(xmlNode *basenode, pcmk__alert_t *entry)
65 {
66 xmlNode *child;
67
68 if ((basenode == NULL) || (entry == NULL)) {
69 return;
70 }
71
72 child = first_named_child(basenode, XML_TAG_ATTR_SETS);
73 if (child == NULL) {
74 return;
75 }
76
77 if (entry->envvars == NULL) {
78 entry->envvars = pcmk__strkey_table(free, free);
79 }
80
81 for (child = first_named_child(child, XML_CIB_TAG_NVPAIR); child != NULL;
82 child = crm_next_same_xml(child)) {
83
84 const char *name = crm_element_value(child, XML_NVPAIR_ATTR_NAME);
85 const char *value = crm_element_value(child, XML_NVPAIR_ATTR_VALUE);
86
87 if (value == NULL) {
88 value = "";
89 }
90 g_hash_table_insert(entry->envvars, strdup(name), strdup(value));
91 crm_trace("Alert %s: added environment variable %s='%s'",
92 entry->id, name, value);
93 }
94 }
95
96 static void
97 unpack_alert_filter(xmlNode *basenode, pcmk__alert_t *entry)
98 {
99 xmlNode *select = first_named_child(basenode, XML_CIB_TAG_ALERT_SELECT);
100 xmlNode *event_type = NULL;
101 uint32_t flags = pcmk__alert_none;
102
103 for (event_type = pcmk__xe_first_child(select); event_type != NULL;
104 event_type = pcmk__xe_next(event_type)) {
105
106 const char *tagname = crm_element_name(event_type);
107
108 if (tagname == NULL) {
109 continue;
110
111 } else if (!strcmp(tagname, XML_CIB_TAG_ALERT_FENCING)) {
112 flags |= pcmk__alert_fencing;
113
114 } else if (!strcmp(tagname, XML_CIB_TAG_ALERT_NODES)) {
115 flags |= pcmk__alert_node;
116
117 } else if (!strcmp(tagname, XML_CIB_TAG_ALERT_RESOURCES)) {
118 flags |= pcmk__alert_resource;
119
120 } else if (!strcmp(tagname, XML_CIB_TAG_ALERT_ATTRIBUTES)) {
121 xmlNode *attr;
122 const char *attr_name;
123 int nattrs = 0;
124
125 flags |= pcmk__alert_attribute;
126 for (attr = first_named_child(event_type, XML_CIB_TAG_ALERT_ATTR);
127 attr != NULL;
128 attr = crm_next_same_xml(attr)) {
129
130 attr_name = crm_element_value(attr, XML_NVPAIR_ATTR_NAME);
131 if (attr_name) {
132 if (nattrs == 0) {
133 g_strfreev(entry->select_attribute_name);
134 entry->select_attribute_name = NULL;
135 }
136 ++nattrs;
137 entry->select_attribute_name = pcmk__realloc(entry->select_attribute_name,
138 (nattrs + 1) * sizeof(char*));
139 entry->select_attribute_name[nattrs - 1] = strdup(attr_name);
140 entry->select_attribute_name[nattrs] = NULL;
141 }
142 }
143 }
144 }
145
146 if (flags != pcmk__alert_none) {
147 entry->flags = flags;
148 crm_debug("Alert %s receives events: attributes:%s%s%s%s",
149 entry->id,
150 (pcmk_is_set(flags, pcmk__alert_attribute)?
151 (entry->select_attribute_name? "some" : "all") : "none"),
152 (pcmk_is_set(flags, pcmk__alert_fencing)? " fencing" : ""),
153 (pcmk_is_set(flags, pcmk__alert_node)? " nodes" : ""),
154 (pcmk_is_set(flags, pcmk__alert_resource)? " resources" : ""));
155 }
156 }
157
158 static void
159 unpack_alert(xmlNode *alert, pcmk__alert_t *entry, guint *max_timeout)
160 {
161 get_envvars_from_cib(alert, entry);
162 get_meta_attrs_from_cib(alert, entry, max_timeout);
163 unpack_alert_filter(alert, entry);
164 }
165
166
167
168
169
170
171
172
173
174
175
176
177 GList *
178 pe_unpack_alerts(xmlNode *alerts)
179 {
180 xmlNode *alert;
181 pcmk__alert_t *entry;
182 guint max_timeout = 0;
183 GList *alert_list = NULL;
184
185 if (alerts == NULL) {
186 return alert_list;
187 }
188
189 for (alert = first_named_child(alerts, XML_CIB_TAG_ALERT);
190 alert != NULL; alert = crm_next_same_xml(alert)) {
191
192 xmlNode *recipient;
193 int recipients = 0;
194 const char *alert_id = ID(alert);
195 const char *alert_path = crm_element_value(alert, XML_ALERT_ATTR_PATH);
196
197
198 if ((alert_id == NULL) || (alert_path == NULL)) {
199 crm_warn("Ignoring invalid alert without id and path");
200 continue;
201 }
202
203 entry = pcmk__alert_new(alert_id, alert_path);
204
205 unpack_alert(alert, entry, &max_timeout);
206
207 if (entry->tstamp_format == NULL) {
208 entry->tstamp_format = strdup(PCMK__ALERT_DEFAULT_TSTAMP_FORMAT);
209 }
210
211 crm_debug("Alert %s: path=%s timeout=%dms tstamp-format='%s' %u vars",
212 entry->id, entry->path, entry->timeout, entry->tstamp_format,
213 (entry->envvars? g_hash_table_size(entry->envvars) : 0));
214
215 for (recipient = first_named_child(alert, XML_CIB_TAG_ALERT_RECIPIENT);
216 recipient != NULL; recipient = crm_next_same_xml(recipient)) {
217
218 pcmk__alert_t *recipient_entry = pcmk__dup_alert(entry);
219
220 recipients++;
221 recipient_entry->recipient = strdup(crm_element_value(recipient,
222 XML_ALERT_ATTR_REC_VALUE));
223 unpack_alert(recipient, recipient_entry, &max_timeout);
224 alert_list = g_list_prepend(alert_list, recipient_entry);
225 crm_debug("Alert %s has recipient %s with value %s and %d envvars",
226 entry->id, ID(recipient), recipient_entry->recipient,
227 (recipient_entry->envvars?
228 g_hash_table_size(recipient_entry->envvars) : 0));
229 }
230
231 if (recipients == 0) {
232 alert_list = g_list_prepend(alert_list, entry);
233 } else {
234 pcmk__free_alert(entry);
235 }
236 }
237 return alert_list;
238 }
239
240
241
242
243
244
245
246 void
247 pe_free_alert_list(GList *alert_list)
248 {
249 if (alert_list) {
250 g_list_free_full(alert_list, (GDestroyNotify) pcmk__free_alert);
251 }
252 }