This source file includes following definitions.
- unpack_action
- unpack_synapse
- unpack_graph
- destroy_action
- destroy_synapse
- destroy_graph
- convert_graph_action
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <sys/param.h>
13 #include <sys/stat.h>
14
15 #include <crm/crm.h>
16 #include <crm/msg_xml.h>
17 #include <crm/common/xml.h>
18 #include <crm/common/xml_internal.h>
19 #include <pacemaker-internal.h>
20
21 static crm_action_t *
22 unpack_action(synapse_t * parent, xmlNode * xml_action)
23 {
24 crm_action_t *action = NULL;
25 const char *value = crm_element_value(xml_action, XML_ATTR_ID);
26
27 if (value == NULL) {
28 crm_err("Actions must have an id!");
29 crm_log_xml_trace(xml_action, "Action with missing id");
30 return NULL;
31 }
32
33 action = calloc(1, sizeof(crm_action_t));
34 if (action == NULL) {
35 crm_perror(LOG_CRIT, "Cannot unpack action");
36 crm_log_xml_trace(xml_action, "Lost action");
37 return NULL;
38 }
39
40 pcmk__scan_min_int(value, &(action->id), -1);
41 action->type = action_type_rsc;
42 action->xml = copy_xml(xml_action);
43 action->synapse = parent;
44
45 if (pcmk__str_eq(crm_element_name(action->xml), XML_GRAPH_TAG_RSC_OP, pcmk__str_casei)) {
46 action->type = action_type_rsc;
47
48 } else if (pcmk__str_eq(crm_element_name(action->xml), XML_GRAPH_TAG_PSEUDO_EVENT, pcmk__str_casei)) {
49 action->type = action_type_pseudo;
50
51 } else if (pcmk__str_eq(crm_element_name(action->xml), XML_GRAPH_TAG_CRM_EVENT, pcmk__str_casei)) {
52 action->type = action_type_crm;
53 }
54
55 action->params = xml2list(action->xml);
56
57 value = g_hash_table_lookup(action->params, "CRM_meta_timeout");
58 pcmk__scan_min_int(value, &(action->timeout), 0);
59
60
61 value = g_hash_table_lookup(action->params, "CRM_meta_start_delay");
62 {
63 int start_delay;
64
65 pcmk__scan_min_int(value, &start_delay, 0);
66 action->timeout += start_delay;
67 }
68
69 if (pcmk__guint_from_hash(action->params,
70 CRM_META "_" XML_LRM_ATTR_INTERVAL, 0,
71 &(action->interval_ms)) != pcmk_rc_ok) {
72 action->interval_ms = 0;
73 }
74
75 value = g_hash_table_lookup(action->params, "CRM_meta_can_fail");
76 if (value != NULL) {
77 crm_str_to_boolean(value, &(action->can_fail));
78 #ifndef PCMK__COMPAT_2_0
79 if (action->can_fail) {
80 crm_warn("Support for the can_fail meta-attribute is deprecated"
81 " and will be removed in a future release");
82 }
83 #endif
84 }
85
86 crm_trace("Action %d has timer set to %dms", action->id, action->timeout);
87
88 return action;
89 }
90
91 static synapse_t *
92 unpack_synapse(crm_graph_t * new_graph, xmlNode * xml_synapse)
93 {
94 const char *value = NULL;
95 xmlNode *inputs = NULL;
96 xmlNode *action_set = NULL;
97 synapse_t *new_synapse = NULL;
98
99 CRM_CHECK(xml_synapse != NULL, return NULL);
100 crm_trace("looking in synapse %s", ID(xml_synapse));
101
102 new_synapse = calloc(1, sizeof(synapse_t));
103 pcmk__scan_min_int(ID(xml_synapse), &(new_synapse->id), 0);
104
105 value = crm_element_value(xml_synapse, XML_CIB_ATTR_PRIORITY);
106 pcmk__scan_min_int(value, &(new_synapse->priority), 0);
107
108 CRM_CHECK(new_synapse->id >= 0, free(new_synapse);
109 return NULL);
110
111 new_graph->num_synapses++;
112
113 crm_trace("look for actions in synapse %s", crm_element_value(xml_synapse, XML_ATTR_ID));
114
115 for (action_set = pcmk__xml_first_child(xml_synapse); action_set != NULL;
116 action_set = pcmk__xml_next(action_set)) {
117
118 if (pcmk__str_eq((const char *)action_set->name, "action_set",
119 pcmk__str_none)) {
120 xmlNode *action = NULL;
121
122 for (action = pcmk__xml_first_child(action_set); action != NULL;
123 action = pcmk__xml_next(action)) {
124 crm_action_t *new_action = unpack_action(new_synapse, action);
125
126 if (new_action == NULL) {
127 continue;
128 }
129
130 new_graph->num_actions++;
131
132 crm_trace("Adding action %d to synapse %d", new_action->id, new_synapse->id);
133
134 new_synapse->actions = g_list_append(new_synapse->actions, new_action);
135 }
136 }
137 }
138
139 crm_trace("look for inputs in synapse %s", ID(xml_synapse));
140
141 for (inputs = pcmk__xml_first_child(xml_synapse); inputs != NULL;
142 inputs = pcmk__xml_next(inputs)) {
143
144 if (pcmk__str_eq((const char *)inputs->name, "inputs", pcmk__str_none)) {
145 xmlNode *trigger = NULL;
146
147 for (trigger = pcmk__xml_first_child(inputs); trigger != NULL;
148 trigger = pcmk__xml_next(trigger)) {
149 xmlNode *input = NULL;
150
151 for (input = pcmk__xml_first_child(trigger); input != NULL;
152 input = pcmk__xml_next(input)) {
153 crm_action_t *new_input = unpack_action(new_synapse, input);
154
155 if (new_input == NULL) {
156 continue;
157 }
158
159 crm_trace("Adding input %d to synapse %d", new_input->id, new_synapse->id);
160
161 new_synapse->inputs = g_list_append(new_synapse->inputs, new_input);
162 }
163 }
164 }
165 }
166
167 return new_synapse;
168 }
169
170 static void destroy_action(crm_action_t * action);
171
172 crm_graph_t *
173 unpack_graph(xmlNode * xml_graph, const char *reference)
174 {
175
176
177
178
179
180
181
182
183
184
185 crm_graph_t *new_graph = NULL;
186 const char *t_id = NULL;
187 const char *time = NULL;
188 xmlNode *synapse = NULL;
189
190 new_graph = calloc(1, sizeof(crm_graph_t));
191
192 new_graph->id = -1;
193 new_graph->abort_priority = 0;
194 new_graph->network_delay = 0;
195 new_graph->stonith_timeout = 0;
196 new_graph->completion_action = tg_done;
197
198 if (reference) {
199 new_graph->source = strdup(reference);
200 } else {
201 new_graph->source = strdup("unknown");
202 }
203
204 if (xml_graph != NULL) {
205 t_id = crm_element_value(xml_graph, "transition_id");
206 CRM_CHECK(t_id != NULL, free(new_graph);
207 return NULL);
208 pcmk__scan_min_int(t_id, &(new_graph->id), -1);
209
210 time = crm_element_value(xml_graph, "cluster-delay");
211 CRM_CHECK(time != NULL, free(new_graph);
212 return NULL);
213 new_graph->network_delay = crm_parse_interval_spec(time);
214
215 time = crm_element_value(xml_graph, "stonith-timeout");
216 if (time == NULL) {
217 new_graph->stonith_timeout = new_graph->network_delay;
218 } else {
219 new_graph->stonith_timeout = crm_parse_interval_spec(time);
220 }
221
222
223 t_id = crm_element_value(xml_graph, "batch-limit");
224 if ((t_id == NULL)
225 || (pcmk__scan_min_int(t_id, &(new_graph->batch_limit),
226 -1) != pcmk_rc_ok)) {
227 new_graph->batch_limit = 0;
228 }
229
230 t_id = crm_element_value(xml_graph, "migration-limit");
231 pcmk__scan_min_int(t_id, &(new_graph->migration_limit), -1);
232 }
233
234 for (synapse = pcmk__xml_first_child(xml_graph); synapse != NULL;
235 synapse = pcmk__xml_next(synapse)) {
236
237 if (pcmk__str_eq((const char *)synapse->name, "synapse", pcmk__str_none)) {
238 synapse_t *new_synapse = unpack_synapse(new_graph, synapse);
239
240 if (new_synapse != NULL) {
241 new_graph->synapses = g_list_append(new_graph->synapses, new_synapse);
242 }
243 }
244 }
245
246 crm_debug("Unpacked transition %d: %d actions in %d synapses",
247 new_graph->id, new_graph->num_actions, new_graph->num_synapses);
248
249 return new_graph;
250 }
251
252 static void
253 destroy_action(crm_action_t * action)
254 {
255 if (action->timer && action->timer->source_id != 0) {
256 crm_warn("Cancelling timer for action %d (src=%d)", action->id, action->timer->source_id);
257 g_source_remove(action->timer->source_id);
258 }
259 if (action->params) {
260 g_hash_table_destroy(action->params);
261 }
262 free_xml(action->xml);
263 free(action->timer);
264 free(action);
265 }
266
267 static void
268 destroy_synapse(synapse_t * synapse)
269 {
270 while (synapse->actions != NULL) {
271 crm_action_t *action = g_list_nth_data(synapse->actions, 0);
272
273 synapse->actions = g_list_remove(synapse->actions, action);
274 destroy_action(action);
275 }
276
277 while (synapse->inputs != NULL) {
278 crm_action_t *action = g_list_nth_data(synapse->inputs, 0);
279
280 synapse->inputs = g_list_remove(synapse->inputs, action);
281 destroy_action(action);
282 }
283 free(synapse);
284 }
285
286 void
287 destroy_graph(crm_graph_t * graph)
288 {
289 if (graph == NULL) {
290 return;
291 }
292 while (graph->synapses != NULL) {
293 synapse_t *synapse = g_list_nth_data(graph->synapses, 0);
294
295 graph->synapses = g_list_remove(graph->synapses, synapse);
296 destroy_synapse(synapse);
297 }
298
299 free(graph->source);
300 free(graph);
301 }
302
303 lrmd_event_data_t *
304 convert_graph_action(xmlNode * resource, crm_action_t * action, int status, int rc)
305 {
306 xmlNode *xop = NULL;
307 lrmd_event_data_t *op = NULL;
308 GHashTableIter iter;
309 const char *name = NULL;
310 const char *value = NULL;
311 xmlNode *action_resource = NULL;
312
313 CRM_CHECK(action != NULL, return NULL);
314 CRM_CHECK(action->type == action_type_rsc, return NULL);
315
316 action_resource = first_named_child(action->xml, XML_CIB_TAG_RESOURCE);
317 CRM_CHECK(action_resource != NULL, crm_log_xml_warn(action->xml, "Bad");
318 return NULL);
319
320 op = lrmd_new_event(ID(action_resource),
321 crm_element_value(action->xml, XML_LRM_ATTR_TASK),
322 action->interval_ms);
323 op->rc = rc;
324 op->op_status = status;
325 op->t_run = time(NULL);
326 op->t_rcchange = op->t_run;
327 op->params = pcmk__strkey_table(free, free);
328
329 g_hash_table_iter_init(&iter, action->params);
330 while (g_hash_table_iter_next(&iter, (void **)&name, (void **)&value)) {
331 g_hash_table_insert(op->params, strdup(name), strdup(value));
332 }
333
334 for (xop = pcmk__xml_first_child(resource); xop != NULL;
335 xop = pcmk__xml_next(xop)) {
336 int tmp = 0;
337
338 crm_element_value_int(xop, XML_LRM_ATTR_CALLID, &tmp);
339 crm_debug("Got call_id=%d for %s", tmp, ID(resource));
340 if (tmp > op->call_id) {
341 op->call_id = tmp;
342 }
343 }
344
345 op->call_id++;
346 return op;
347 }