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 action->id = crm_parse_int(value, NULL);
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 if (value != NULL) {
59 action->timeout = crm_parse_int(value, NULL);
60 }
61
62
63 value = g_hash_table_lookup(action->params, "CRM_meta_start_delay");
64 if (value != NULL) {
65 action->timeout += crm_parse_int(value, NULL);
66 }
67
68 if (pcmk__guint_from_hash(action->params,
69 CRM_META "_" XML_LRM_ATTR_INTERVAL, 0,
70 &(action->interval_ms)) != pcmk_rc_ok) {
71 action->interval_ms = 0;
72 }
73
74 value = g_hash_table_lookup(action->params, "CRM_meta_can_fail");
75 if (value != NULL) {
76 crm_str_to_boolean(value, &(action->can_fail));
77 }
78
79 crm_trace("Action %d has timer set to %dms", action->id, action->timeout);
80
81 return action;
82 }
83
84 static synapse_t *
85 unpack_synapse(crm_graph_t * new_graph, xmlNode * xml_synapse)
86 {
87 const char *value = NULL;
88 xmlNode *inputs = NULL;
89 xmlNode *action_set = NULL;
90 synapse_t *new_synapse = NULL;
91
92 CRM_CHECK(xml_synapse != NULL, return NULL);
93 crm_trace("looking in synapse %s", ID(xml_synapse));
94
95 new_synapse = calloc(1, sizeof(synapse_t));
96 new_synapse->id = crm_parse_int(ID(xml_synapse), NULL);
97
98 value = crm_element_value(xml_synapse, XML_CIB_ATTR_PRIORITY);
99 if (value != NULL) {
100 new_synapse->priority = crm_parse_int(value, NULL);
101 }
102
103 CRM_CHECK(new_synapse->id >= 0, free(new_synapse);
104 return NULL);
105
106 new_graph->num_synapses++;
107
108 crm_trace("look for actions in synapse %s", crm_element_value(xml_synapse, XML_ATTR_ID));
109
110 for (action_set = pcmk__xml_first_child(xml_synapse); action_set != NULL;
111 action_set = pcmk__xml_next(action_set)) {
112
113 if (pcmk__str_eq((const char *)action_set->name, "action_set",
114 pcmk__str_none)) {
115 xmlNode *action = NULL;
116
117 for (action = pcmk__xml_first_child(action_set); action != NULL;
118 action = pcmk__xml_next(action)) {
119 crm_action_t *new_action = unpack_action(new_synapse, action);
120
121 if (new_action == NULL) {
122 continue;
123 }
124
125 new_graph->num_actions++;
126
127 crm_trace("Adding action %d to synapse %d", new_action->id, new_synapse->id);
128
129 new_synapse->actions = g_list_append(new_synapse->actions, new_action);
130 }
131 }
132 }
133
134 crm_trace("look for inputs in synapse %s", ID(xml_synapse));
135
136 for (inputs = pcmk__xml_first_child(xml_synapse); inputs != NULL;
137 inputs = pcmk__xml_next(inputs)) {
138
139 if (pcmk__str_eq((const char *)inputs->name, "inputs", pcmk__str_none)) {
140 xmlNode *trigger = NULL;
141
142 for (trigger = pcmk__xml_first_child(inputs); trigger != NULL;
143 trigger = pcmk__xml_next(trigger)) {
144 xmlNode *input = NULL;
145
146 for (input = pcmk__xml_first_child(trigger); input != NULL;
147 input = pcmk__xml_next(input)) {
148 crm_action_t *new_input = unpack_action(new_synapse, input);
149
150 if (new_input == NULL) {
151 continue;
152 }
153
154 crm_trace("Adding input %d to synapse %d", new_input->id, new_synapse->id);
155
156 new_synapse->inputs = g_list_append(new_synapse->inputs, new_input);
157 }
158 }
159 }
160 }
161
162 return new_synapse;
163 }
164
165 static void destroy_action(crm_action_t * action);
166
167 crm_graph_t *
168 unpack_graph(xmlNode * xml_graph, const char *reference)
169 {
170
171
172
173
174
175
176
177
178
179
180 crm_graph_t *new_graph = NULL;
181 const char *t_id = NULL;
182 const char *time = NULL;
183 xmlNode *synapse = NULL;
184
185 new_graph = calloc(1, sizeof(crm_graph_t));
186
187 new_graph->id = -1;
188 new_graph->abort_priority = 0;
189 new_graph->network_delay = 0;
190 new_graph->stonith_timeout = 0;
191 new_graph->completion_action = tg_done;
192
193 if (reference) {
194 new_graph->source = strdup(reference);
195 } else {
196 new_graph->source = strdup("unknown");
197 }
198
199 if (xml_graph != NULL) {
200 t_id = crm_element_value(xml_graph, "transition_id");
201 CRM_CHECK(t_id != NULL, free(new_graph);
202 return NULL);
203 new_graph->id = crm_parse_int(t_id, "-1");
204
205 time = crm_element_value(xml_graph, "cluster-delay");
206 CRM_CHECK(time != NULL, free(new_graph);
207 return NULL);
208 new_graph->network_delay = crm_parse_interval_spec(time);
209
210 time = crm_element_value(xml_graph, "stonith-timeout");
211 if (time == NULL) {
212 new_graph->stonith_timeout = new_graph->network_delay;
213 } else {
214 new_graph->stonith_timeout = crm_parse_interval_spec(time);
215 }
216
217 t_id = crm_element_value(xml_graph, "batch-limit");
218 new_graph->batch_limit = crm_parse_int(t_id, "0");
219
220 t_id = crm_element_value(xml_graph, "migration-limit");
221 new_graph->migration_limit = crm_parse_int(t_id, "-1");
222 }
223
224 for (synapse = pcmk__xml_first_child(xml_graph); synapse != NULL;
225 synapse = pcmk__xml_next(synapse)) {
226
227 if (pcmk__str_eq((const char *)synapse->name, "synapse", pcmk__str_none)) {
228 synapse_t *new_synapse = unpack_synapse(new_graph, synapse);
229
230 if (new_synapse != NULL) {
231 new_graph->synapses = g_list_append(new_graph->synapses, new_synapse);
232 }
233 }
234 }
235
236 crm_debug("Unpacked transition %d: %d actions in %d synapses",
237 new_graph->id, new_graph->num_actions, new_graph->num_synapses);
238
239 return new_graph;
240 }
241
242 static void
243 destroy_action(crm_action_t * action)
244 {
245 if (action->timer && action->timer->source_id != 0) {
246 crm_warn("Cancelling timer for action %d (src=%d)", action->id, action->timer->source_id);
247 g_source_remove(action->timer->source_id);
248 }
249 if (action->params) {
250 g_hash_table_destroy(action->params);
251 }
252 free_xml(action->xml);
253 free(action->timer);
254 free(action);
255 }
256
257 static void
258 destroy_synapse(synapse_t * synapse)
259 {
260 while (synapse->actions != NULL) {
261 crm_action_t *action = g_list_nth_data(synapse->actions, 0);
262
263 synapse->actions = g_list_remove(synapse->actions, action);
264 destroy_action(action);
265 }
266
267 while (synapse->inputs != NULL) {
268 crm_action_t *action = g_list_nth_data(synapse->inputs, 0);
269
270 synapse->inputs = g_list_remove(synapse->inputs, action);
271 destroy_action(action);
272 }
273 free(synapse);
274 }
275
276 void
277 destroy_graph(crm_graph_t * graph)
278 {
279 if (graph == NULL) {
280 return;
281 }
282 while (graph->synapses != NULL) {
283 synapse_t *synapse = g_list_nth_data(graph->synapses, 0);
284
285 graph->synapses = g_list_remove(graph->synapses, synapse);
286 destroy_synapse(synapse);
287 }
288
289 free(graph->source);
290 free(graph);
291 }
292
293 lrmd_event_data_t *
294 convert_graph_action(xmlNode * resource, crm_action_t * action, int status, int rc)
295 {
296 xmlNode *xop = NULL;
297 lrmd_event_data_t *op = NULL;
298 GHashTableIter iter;
299 const char *name = NULL;
300 const char *value = NULL;
301 xmlNode *action_resource = NULL;
302
303 CRM_CHECK(action != NULL, return NULL);
304 CRM_CHECK(action->type == action_type_rsc, return NULL);
305
306 action_resource = first_named_child(action->xml, XML_CIB_TAG_RESOURCE);
307 CRM_CHECK(action_resource != NULL, crm_log_xml_warn(action->xml, "Bad");
308 return NULL);
309
310 op = lrmd_new_event(ID(action_resource),
311 crm_element_value(action->xml, XML_LRM_ATTR_TASK),
312 action->interval_ms);
313 op->rc = rc;
314 op->op_status = status;
315 op->t_run = time(NULL);
316 op->t_rcchange = op->t_run;
317
318 op->params = g_hash_table_new_full(crm_str_hash, g_str_equal, free, free);
319
320 g_hash_table_iter_init(&iter, action->params);
321 while (g_hash_table_iter_next(&iter, (void **)&name, (void **)&value)) {
322 g_hash_table_insert(op->params, strdup(name), strdup(value));
323 }
324
325 for (xop = pcmk__xml_first_child(resource); xop != NULL;
326 xop = pcmk__xml_next(xop)) {
327 int tmp = 0;
328
329 crm_element_value_int(xop, XML_LRM_ATTR_CALLID, &tmp);
330 crm_debug("Got call_id=%d for %s", tmp, ID(resource));
331 if (tmp > op->call_id) {
332 op->call_id = tmp;
333 }
334 }
335
336 op->call_id++;
337 return op;
338 }