This source file includes following definitions.
- pe_new_working_set
- pe_free_working_set
- cluster_status
- pe_free_resources
- pe_free_actions
- pe_free_nodes
- pe__free_ordering
- pe__free_location
- cleanup_calculations
- pe_reset_working_set
- set_working_set_defaults
- pe_find_resource
- pe_find_resource_with_flags
- pe_find_node_any
- pe_find_node_id
- pe_find_node
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <sys/param.h>
13
14 #include <crm/crm.h>
15 #include <crm/msg_xml.h>
16 #include <crm/common/xml.h>
17
18 #include <glib.h>
19
20 #include <crm/pengine/internal.h>
21 #include <pe_status_private.h>
22
23
24
25
26
27
28
29
30
31
32
33 pe_working_set_t *
34 pe_new_working_set()
35 {
36 pe_working_set_t *data_set = calloc(1, sizeof(pe_working_set_t));
37
38 if (data_set != NULL) {
39 set_working_set_defaults(data_set);
40 }
41 return data_set;
42 }
43
44
45
46
47
48
49 void
50 pe_free_working_set(pe_working_set_t *data_set)
51 {
52 if (data_set != NULL) {
53 pe_reset_working_set(data_set);
54 data_set->priv = NULL;
55 free(data_set);
56 }
57 }
58
59
60
61
62
63
64
65
66
67
68
69
70 gboolean
71 cluster_status(pe_working_set_t * data_set)
72 {
73 xmlNode *config = get_xpath_object("//"XML_CIB_TAG_CRMCONFIG, data_set->input, LOG_TRACE);
74 xmlNode *cib_nodes = get_xpath_object("//"XML_CIB_TAG_NODES, data_set->input, LOG_TRACE);
75 xmlNode *cib_resources = get_xpath_object("//"XML_CIB_TAG_RESOURCES, data_set->input, LOG_TRACE);
76 xmlNode *cib_status = get_xpath_object("//"XML_CIB_TAG_STATUS, data_set->input, LOG_TRACE);
77 xmlNode *cib_tags = get_xpath_object("//" XML_CIB_TAG_TAGS, data_set->input,
78 LOG_NEVER);
79 const char *value = crm_element_value(data_set->input, XML_ATTR_HAVE_QUORUM);
80
81 crm_trace("Beginning unpack");
82
83
84 data_set->failed = create_xml_node(NULL, "failed-ops");
85
86 if (data_set->input == NULL) {
87 return FALSE;
88 }
89
90 if (data_set->now == NULL) {
91 data_set->now = crm_time_new(NULL);
92 }
93
94 if (data_set->dc_uuid == NULL) {
95 data_set->dc_uuid = crm_element_value_copy(data_set->input,
96 XML_ATTR_DC_UUID);
97 }
98
99 if (crm_is_true(value)) {
100 pe__set_working_set_flags(data_set, pe_flag_have_quorum);
101 } else {
102 pe__clear_working_set_flags(data_set, pe_flag_have_quorum);
103 }
104
105 data_set->op_defaults = get_xpath_object("//" XML_CIB_TAG_OPCONFIG,
106 data_set->input, LOG_NEVER);
107 data_set->rsc_defaults = get_xpath_object("//" XML_CIB_TAG_RSCCONFIG,
108 data_set->input, LOG_NEVER);
109
110 unpack_config(config, data_set);
111
112 if (!pcmk_any_flags_set(data_set->flags,
113 pe_flag_quick_location|pe_flag_have_quorum)
114 && (data_set->no_quorum_policy != no_quorum_ignore)) {
115 crm_warn("Fencing and resource management disabled due to lack of quorum");
116 }
117
118 unpack_nodes(cib_nodes, data_set);
119
120 if (!pcmk_is_set(data_set->flags, pe_flag_quick_location)) {
121 unpack_remote_nodes(cib_resources, data_set);
122 }
123
124 unpack_resources(cib_resources, data_set);
125 unpack_tags(cib_tags, data_set);
126
127 if (!pcmk_is_set(data_set->flags, pe_flag_quick_location)) {
128 unpack_status(cib_status, data_set);
129 }
130
131 if (!pcmk_is_set(data_set->flags, pe_flag_no_counts)) {
132 for (GList *item = data_set->resources; item != NULL;
133 item = item->next) {
134 ((pe_resource_t *) (item->data))->fns->count(item->data);
135 }
136 }
137
138 pe__set_working_set_flags(data_set, pe_flag_have_status);
139 return TRUE;
140 }
141
142
143
144
145
146
147
148
149
150
151
152
153 static void
154 pe_free_resources(GList *resources)
155 {
156 pe_resource_t *rsc = NULL;
157 GList *iterator = resources;
158
159 while (iterator != NULL) {
160 rsc = (pe_resource_t *) iterator->data;
161 iterator = iterator->next;
162 rsc->fns->free(rsc);
163 }
164 if (resources != NULL) {
165 g_list_free(resources);
166 }
167 }
168
169 static void
170 pe_free_actions(GList *actions)
171 {
172 GList *iterator = actions;
173
174 while (iterator != NULL) {
175 pe_free_action(iterator->data);
176 iterator = iterator->next;
177 }
178 if (actions != NULL) {
179 g_list_free(actions);
180 }
181 }
182
183 static void
184 pe_free_nodes(GList *nodes)
185 {
186 for (GList *iterator = nodes; iterator != NULL; iterator = iterator->next) {
187 pe_node_t *node = (pe_node_t *) iterator->data;
188
189
190 if (node == NULL) {
191 continue;
192 }
193 if (node->details == NULL) {
194 free(node);
195 continue;
196 }
197
198
199
200
201 crm_trace("Freeing node %s", (pe__is_guest_or_remote_node(node)?
202 "(guest or remote)" : node->details->uname));
203
204 if (node->details->attrs != NULL) {
205 g_hash_table_destroy(node->details->attrs);
206 }
207 if (node->details->utilization != NULL) {
208 g_hash_table_destroy(node->details->utilization);
209 }
210 if (node->details->digest_cache != NULL) {
211 g_hash_table_destroy(node->details->digest_cache);
212 }
213 g_list_free(node->details->running_rsc);
214 g_list_free(node->details->allocated_rsc);
215 free(node->details);
216 free(node);
217 }
218 if (nodes != NULL) {
219 g_list_free(nodes);
220 }
221 }
222
223 static void
224 pe__free_ordering(GList *constraints)
225 {
226 GList *iterator = constraints;
227
228 while (iterator != NULL) {
229 pe__ordering_t *order = iterator->data;
230
231 iterator = iterator->next;
232
233 free(order->lh_action_task);
234 free(order->rh_action_task);
235 free(order);
236 }
237 if (constraints != NULL) {
238 g_list_free(constraints);
239 }
240 }
241
242 static void
243 pe__free_location(GList *constraints)
244 {
245 GList *iterator = constraints;
246
247 while (iterator != NULL) {
248 pe__location_t *cons = iterator->data;
249
250 iterator = iterator->next;
251
252 g_list_free_full(cons->node_list_rh, free);
253 free(cons->id);
254 free(cons);
255 }
256 if (constraints != NULL) {
257 g_list_free(constraints);
258 }
259 }
260
261
262
263
264
265
266
267
268
269 void
270 cleanup_calculations(pe_working_set_t * data_set)
271 {
272 if (data_set == NULL) {
273 return;
274 }
275
276 pe__clear_working_set_flags(data_set, pe_flag_have_status);
277 if (data_set->config_hash != NULL) {
278 g_hash_table_destroy(data_set->config_hash);
279 }
280
281 if (data_set->singletons != NULL) {
282 g_hash_table_destroy(data_set->singletons);
283 }
284
285 if (data_set->tickets) {
286 g_hash_table_destroy(data_set->tickets);
287 }
288
289 if (data_set->template_rsc_sets) {
290 g_hash_table_destroy(data_set->template_rsc_sets);
291 }
292
293 if (data_set->tags) {
294 g_hash_table_destroy(data_set->tags);
295 }
296
297 free(data_set->dc_uuid);
298
299 crm_trace("deleting resources");
300 pe_free_resources(data_set->resources);
301
302 crm_trace("deleting actions");
303 pe_free_actions(data_set->actions);
304
305 crm_trace("deleting nodes");
306 pe_free_nodes(data_set->nodes);
307
308 pe__free_param_checks(data_set);
309 g_list_free(data_set->stop_needed);
310 free_xml(data_set->graph);
311 crm_time_free(data_set->now);
312 free_xml(data_set->input);
313 free_xml(data_set->failed);
314
315 set_working_set_defaults(data_set);
316
317 CRM_CHECK(data_set->ordering_constraints == NULL,;
318 );
319 CRM_CHECK(data_set->placement_constraints == NULL,;
320 );
321 }
322
323
324
325
326
327
328 void
329 pe_reset_working_set(pe_working_set_t *data_set)
330 {
331 if (data_set == NULL) {
332 return;
333 }
334
335 crm_trace("Deleting %d ordering constraints",
336 g_list_length(data_set->ordering_constraints));
337 pe__free_ordering(data_set->ordering_constraints);
338 data_set->ordering_constraints = NULL;
339
340 crm_trace("Deleting %d location constraints",
341 g_list_length(data_set->placement_constraints));
342 pe__free_location(data_set->placement_constraints);
343 data_set->placement_constraints = NULL;
344
345 crm_trace("Deleting %d colocation constraints",
346 g_list_length(data_set->colocation_constraints));
347 g_list_free_full(data_set->colocation_constraints, free);
348 data_set->colocation_constraints = NULL;
349
350 crm_trace("Deleting %d ticket constraints",
351 g_list_length(data_set->ticket_constraints));
352 g_list_free_full(data_set->ticket_constraints, free);
353 data_set->ticket_constraints = NULL;
354
355 cleanup_calculations(data_set);
356 }
357
358 void
359 set_working_set_defaults(pe_working_set_t * data_set)
360 {
361 void *priv = data_set->priv;
362
363 memset(data_set, 0, sizeof(pe_working_set_t));
364
365 data_set->priv = priv;
366 data_set->order_id = 1;
367 data_set->action_id = 1;
368 data_set->no_quorum_policy = no_quorum_stop;
369
370 data_set->flags = 0x0ULL;
371
372 pe__set_working_set_flags(data_set,
373 pe_flag_stop_rsc_orphans
374 |pe_flag_symmetric_cluster
375 |pe_flag_stop_action_orphans);
376 if (!strcmp(PCMK__CONCURRENT_FENCING_DEFAULT, "true")) {
377 pe__set_working_set_flags(data_set, pe_flag_concurrent_fencing);
378 }
379 }
380
381 pe_resource_t *
382 pe_find_resource(GList *rsc_list, const char *id)
383 {
384 return pe_find_resource_with_flags(rsc_list, id, pe_find_renamed);
385 }
386
387 pe_resource_t *
388 pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags)
389 {
390 GList *rIter = NULL;
391
392 for (rIter = rsc_list; id && rIter; rIter = rIter->next) {
393 pe_resource_t *parent = rIter->data;
394
395 pe_resource_t *match =
396 parent->fns->find_rsc(parent, id, NULL, flags);
397 if (match != NULL) {
398 return match;
399 }
400 }
401 crm_trace("No match for %s", id);
402 return NULL;
403 }
404
405 pe_node_t *
406 pe_find_node_any(GList *nodes, const char *id, const char *uname)
407 {
408 pe_node_t *match = pe_find_node_id(nodes, id);
409
410 if (match) {
411 return match;
412 }
413 crm_trace("Looking up %s via its uname instead", uname);
414 return pe_find_node(nodes, uname);
415 }
416
417 pe_node_t *
418 pe_find_node_id(GList *nodes, const char *id)
419 {
420 GList *gIter = nodes;
421
422 for (; gIter != NULL; gIter = gIter->next) {
423 pe_node_t *node = (pe_node_t *) gIter->data;
424
425 if (node && pcmk__str_eq(node->details->id, id, pcmk__str_casei)) {
426 return node;
427 }
428 }
429
430 return NULL;
431 }
432
433 pe_node_t *
434 pe_find_node(GList *nodes, const char *uname)
435 {
436 GList *gIter = nodes;
437
438 for (; gIter != NULL; gIter = gIter->next) {
439 pe_node_t *node = (pe_node_t *) gIter->data;
440
441 if (node && pcmk__str_eq(node->details->uname, uname, pcmk__str_casei)) {
442 return node;
443 }
444 }
445
446 return NULL;
447 }