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