This source file includes following definitions.
- pe_new_working_set
- pe_free_working_set
- check_for_deprecated_rules
- 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/common/xml.h>
16 #include <crm/common/cib_internal.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 pcmk_scheduler_t *
34 pe_new_working_set(void)
35 {
36 pcmk_scheduler_t *scheduler = calloc(1, sizeof(pcmk_scheduler_t));
37
38 if (scheduler != NULL) {
39 set_working_set_defaults(scheduler);
40 }
41 return scheduler;
42 }
43
44
45
46
47
48
49 void
50 pe_free_working_set(pcmk_scheduler_t *scheduler)
51 {
52 if (scheduler != NULL) {
53 pe_reset_working_set(scheduler);
54 scheduler->priv = NULL;
55 free(scheduler);
56 }
57 }
58
59 #define XPATH_DEPRECATED_RULES \
60 "//" PCMK_XE_OP_DEFAULTS "//" PCMK_XE_EXPRESSION \
61 "|//" PCMK_XE_OP "//" PCMK_XE_EXPRESSION
62
63
64
65
66
67
68
69 static void
70 check_for_deprecated_rules(pcmk_scheduler_t *scheduler)
71 {
72
73 xmlNode *deprecated = get_xpath_object(XPATH_DEPRECATED_RULES,
74 scheduler->input, LOG_NEVER);
75
76 if (deprecated != NULL) {
77 pcmk__warn_once(pcmk__wo_op_attr_expr,
78 "Support for rules with node attribute expressions in "
79 PCMK_XE_OP " or " PCMK_XE_OP_DEFAULTS " is deprecated "
80 "and will be dropped in a future release");
81 }
82 }
83
84
85
86
87
88
89
90
91
92
93
94
95 gboolean
96 cluster_status(pcmk_scheduler_t * scheduler)
97 {
98 const char *new_version = NULL;
99 xmlNode *section = NULL;
100
101 if ((scheduler == NULL) || (scheduler->input == NULL)) {
102 return FALSE;
103 }
104
105 new_version = crm_element_value(scheduler->input, PCMK_XA_CRM_FEATURE_SET);
106
107 if (pcmk__check_feature_set(new_version) != pcmk_rc_ok) {
108 pcmk__config_err("Can't process CIB with feature set '%s' greater than our own '%s'",
109 new_version, CRM_FEATURE_SET);
110 return FALSE;
111 }
112
113 crm_trace("Beginning unpack");
114
115 if (scheduler->failed != NULL) {
116 free_xml(scheduler->failed);
117 }
118 scheduler->failed = pcmk__xe_create(NULL, "failed-ops");
119
120 if (scheduler->now == NULL) {
121 scheduler->now = crm_time_new(NULL);
122 }
123
124 if (scheduler->dc_uuid == NULL) {
125 scheduler->dc_uuid = crm_element_value_copy(scheduler->input,
126 PCMK_XA_DC_UUID);
127 }
128
129 if (pcmk__xe_attr_is_true(scheduler->input, PCMK_XA_HAVE_QUORUM)) {
130 pcmk__set_scheduler_flags(scheduler, pcmk_sched_quorate);
131 } else {
132 pcmk__clear_scheduler_flags(scheduler, pcmk_sched_quorate);
133 }
134
135 scheduler->op_defaults = get_xpath_object("//" PCMK_XE_OP_DEFAULTS,
136 scheduler->input, LOG_NEVER);
137 check_for_deprecated_rules(scheduler);
138
139 scheduler->rsc_defaults = get_xpath_object("//" PCMK_XE_RSC_DEFAULTS,
140 scheduler->input, LOG_NEVER);
141
142 section = get_xpath_object("//" PCMK_XE_CRM_CONFIG, scheduler->input,
143 LOG_TRACE);
144 unpack_config(section, scheduler);
145
146 if (!pcmk_any_flags_set(scheduler->flags,
147 pcmk_sched_location_only|pcmk_sched_quorate)
148 && (scheduler->no_quorum_policy != pcmk_no_quorum_ignore)) {
149 pcmk__sched_warn("Fencing and resource management disabled "
150 "due to lack of quorum");
151 }
152
153 section = get_xpath_object("//" PCMK_XE_NODES, scheduler->input, LOG_TRACE);
154 unpack_nodes(section, scheduler);
155
156 section = get_xpath_object("//" PCMK_XE_RESOURCES, scheduler->input,
157 LOG_TRACE);
158 if (!pcmk_is_set(scheduler->flags, pcmk_sched_location_only)) {
159 unpack_remote_nodes(section, scheduler);
160 }
161 unpack_resources(section, scheduler);
162
163 section = get_xpath_object("//" PCMK_XE_FENCING_TOPOLOGY, scheduler->input,
164 LOG_TRACE);
165 pcmk__unpack_fencing_topology(section, scheduler);
166
167 section = get_xpath_object("//" PCMK_XE_TAGS, scheduler->input, LOG_NEVER);
168 unpack_tags(section, scheduler);
169
170 if (!pcmk_is_set(scheduler->flags, pcmk_sched_location_only)) {
171 section = get_xpath_object("//" PCMK_XE_STATUS, scheduler->input,
172 LOG_TRACE);
173 unpack_status(section, scheduler);
174 }
175
176 if (!pcmk_is_set(scheduler->flags, pcmk_sched_no_counts)) {
177 for (GList *item = scheduler->resources; item != NULL;
178 item = item->next) {
179 ((pcmk_resource_t *) (item->data))->fns->count(item->data);
180 }
181 crm_trace("Cluster resource count: %d (%d disabled, %d blocked)",
182 scheduler->ninstances, scheduler->disabled_resources,
183 scheduler->blocked_resources);
184 }
185
186 pcmk__set_scheduler_flags(scheduler, pcmk_sched_have_status);
187 return TRUE;
188 }
189
190
191
192
193
194
195
196
197
198
199
200
201 static void
202 pe_free_resources(GList *resources)
203 {
204 pcmk_resource_t *rsc = NULL;
205 GList *iterator = resources;
206
207 while (iterator != NULL) {
208 rsc = (pcmk_resource_t *) iterator->data;
209 iterator = iterator->next;
210 rsc->fns->free(rsc);
211 }
212 if (resources != NULL) {
213 g_list_free(resources);
214 }
215 }
216
217 static void
218 pe_free_actions(GList *actions)
219 {
220 GList *iterator = actions;
221
222 while (iterator != NULL) {
223 pe_free_action(iterator->data);
224 iterator = iterator->next;
225 }
226 if (actions != NULL) {
227 g_list_free(actions);
228 }
229 }
230
231 static void
232 pe_free_nodes(GList *nodes)
233 {
234 for (GList *iterator = nodes; iterator != NULL; iterator = iterator->next) {
235 pcmk_node_t *node = (pcmk_node_t *) iterator->data;
236
237
238 if (node == NULL) {
239 continue;
240 }
241 if (node->details == NULL) {
242 free(node);
243 continue;
244 }
245
246
247
248
249 crm_trace("Freeing node %s", (pcmk__is_pacemaker_remote_node(node)?
250 "(guest or remote)" : pcmk__node_name(node)));
251
252 if (node->details->attrs != NULL) {
253 g_hash_table_destroy(node->details->attrs);
254 }
255 if (node->details->utilization != NULL) {
256 g_hash_table_destroy(node->details->utilization);
257 }
258 if (node->details->digest_cache != NULL) {
259 g_hash_table_destroy(node->details->digest_cache);
260 }
261 g_list_free(node->details->running_rsc);
262 g_list_free(node->details->allocated_rsc);
263 free(node->details);
264 free(node);
265 }
266 if (nodes != NULL) {
267 g_list_free(nodes);
268 }
269 }
270
271 static void
272 pe__free_ordering(GList *constraints)
273 {
274 GList *iterator = constraints;
275
276 while (iterator != NULL) {
277 pcmk__action_relation_t *order = iterator->data;
278
279 iterator = iterator->next;
280
281 free(order->task1);
282 free(order->task2);
283 free(order);
284 }
285 if (constraints != NULL) {
286 g_list_free(constraints);
287 }
288 }
289
290 static void
291 pe__free_location(GList *constraints)
292 {
293 GList *iterator = constraints;
294
295 while (iterator != NULL) {
296 pcmk__location_t *cons = iterator->data;
297
298 iterator = iterator->next;
299
300 g_list_free_full(cons->nodes, free);
301 free(cons->id);
302 free(cons);
303 }
304 if (constraints != NULL) {
305 g_list_free(constraints);
306 }
307 }
308
309
310
311
312
313
314
315
316
317 void
318 cleanup_calculations(pcmk_scheduler_t *scheduler)
319 {
320 if (scheduler == NULL) {
321 return;
322 }
323
324 pcmk__clear_scheduler_flags(scheduler, pcmk_sched_have_status);
325 if (scheduler->config_hash != NULL) {
326 g_hash_table_destroy(scheduler->config_hash);
327 }
328
329 if (scheduler->singletons != NULL) {
330 g_hash_table_destroy(scheduler->singletons);
331 }
332
333 if (scheduler->tickets) {
334 g_hash_table_destroy(scheduler->tickets);
335 }
336
337 if (scheduler->template_rsc_sets) {
338 g_hash_table_destroy(scheduler->template_rsc_sets);
339 }
340
341 if (scheduler->tags) {
342 g_hash_table_destroy(scheduler->tags);
343 }
344
345 free(scheduler->dc_uuid);
346
347 crm_trace("deleting resources");
348 pe_free_resources(scheduler->resources);
349
350 crm_trace("deleting actions");
351 pe_free_actions(scheduler->actions);
352
353 crm_trace("deleting nodes");
354 pe_free_nodes(scheduler->nodes);
355
356 pe__free_param_checks(scheduler);
357 g_list_free(scheduler->stop_needed);
358 free_xml(scheduler->graph);
359 crm_time_free(scheduler->now);
360 free_xml(scheduler->input);
361 free_xml(scheduler->failed);
362
363 set_working_set_defaults(scheduler);
364
365 CRM_CHECK(scheduler->ordering_constraints == NULL,;
366 );
367 CRM_CHECK(scheduler->placement_constraints == NULL,;
368 );
369 }
370
371
372
373
374
375
376 void
377 pe_reset_working_set(pcmk_scheduler_t *scheduler)
378 {
379 if (scheduler == NULL) {
380 return;
381 }
382
383 crm_trace("Deleting %d ordering constraints",
384 g_list_length(scheduler->ordering_constraints));
385 pe__free_ordering(scheduler->ordering_constraints);
386 scheduler->ordering_constraints = NULL;
387
388 crm_trace("Deleting %d location constraints",
389 g_list_length(scheduler->placement_constraints));
390 pe__free_location(scheduler->placement_constraints);
391 scheduler->placement_constraints = NULL;
392
393 crm_trace("Deleting %d colocation constraints",
394 g_list_length(scheduler->colocation_constraints));
395 g_list_free_full(scheduler->colocation_constraints, free);
396 scheduler->colocation_constraints = NULL;
397
398 crm_trace("Deleting %d ticket constraints",
399 g_list_length(scheduler->ticket_constraints));
400 g_list_free_full(scheduler->ticket_constraints, free);
401 scheduler->ticket_constraints = NULL;
402
403 cleanup_calculations(scheduler);
404 }
405
406 void
407 set_working_set_defaults(pcmk_scheduler_t *scheduler)
408 {
409 void *priv = scheduler->priv;
410
411 memset(scheduler, 0, sizeof(pcmk_scheduler_t));
412
413 scheduler->priv = priv;
414 scheduler->order_id = 1;
415 scheduler->action_id = 1;
416 scheduler->no_quorum_policy = pcmk_no_quorum_stop;
417
418 scheduler->flags = 0x0ULL;
419
420 pcmk__set_scheduler_flags(scheduler,
421 pcmk_sched_symmetric_cluster
422 |pcmk_sched_stop_removed_resources
423 |pcmk_sched_cancel_removed_actions);
424 if (!strcmp(PCMK__CONCURRENT_FENCING_DEFAULT, PCMK_VALUE_TRUE)) {
425 pcmk__set_scheduler_flags(scheduler, pcmk_sched_concurrent_fencing);
426 }
427 }
428
429 pcmk_resource_t *
430 pe_find_resource(GList *rsc_list, const char *id)
431 {
432 return pe_find_resource_with_flags(rsc_list, id, pcmk_rsc_match_history);
433 }
434
435 pcmk_resource_t *
436 pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags)
437 {
438 GList *rIter = NULL;
439
440 for (rIter = rsc_list; id && rIter; rIter = rIter->next) {
441 pcmk_resource_t *parent = rIter->data;
442
443 pcmk_resource_t *match =
444 parent->fns->find_rsc(parent, id, NULL, flags);
445 if (match != NULL) {
446 return match;
447 }
448 }
449 crm_trace("No match for %s", id);
450 return NULL;
451 }
452
453
454
455
456
457
458
459
460
461
462
463
464 pcmk_node_t *
465 pe_find_node_any(const GList *nodes, const char *id, const char *uname)
466 {
467 pcmk_node_t *match = NULL;
468
469 if (id != NULL) {
470 match = pe_find_node_id(nodes, id);
471 }
472 if ((match == NULL) && (uname != NULL)) {
473 match = pcmk__find_node_in_list(nodes, uname);
474 }
475 return match;
476 }
477
478
479
480
481
482
483
484
485
486 pcmk_node_t *
487 pe_find_node_id(const GList *nodes, const char *id)
488 {
489 for (const GList *iter = nodes; iter != NULL; iter = iter->next) {
490 pcmk_node_t *node = (pcmk_node_t *) iter->data;
491
492
493
494
495
496 if (pcmk__str_eq(node->details->id, id, pcmk__str_casei)) {
497 return node;
498 }
499 }
500 return NULL;
501 }
502
503
504
505
506 #include <crm/pengine/status_compat.h>
507
508
509
510
511
512
513
514
515
516 pcmk_node_t *
517 pe_find_node(const GList *nodes, const char *node_name)
518 {
519 return pcmk__find_node_in_list(nodes, node_name);
520 }
521
522
523