This source file includes following definitions.
- check_for_deprecated_rules
- cluster_status
- pe_find_resource
- pe_find_resource_with_flags
- pe_find_node_any
- pe_find_node_id
- pe_new_working_set
- pe_reset_working_set
- cleanup_calculations
- set_working_set_defaults
- pe_free_working_set
- pe_find_node
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <stdint.h>
13 #include <sys/param.h>
14
15 #include <glib.h>
16 #include <libxml/tree.h>
17
18 #include <crm/crm.h>
19 #include <crm/common/xml.h>
20 #include <crm/common/cib_internal.h>
21
22 #include <crm/pengine/internal.h>
23 #include <pe_status_private.h>
24
25 #define XPATH_DEPRECATED_RULES \
26 "//" PCMK_XE_OP_DEFAULTS "//" PCMK_XE_EXPRESSION \
27 "|//" PCMK_XE_OP "//" PCMK_XE_EXPRESSION
28
29
30
31
32
33
34
35 static void
36 check_for_deprecated_rules(pcmk_scheduler_t *scheduler)
37 {
38
39 xmlNode *deprecated = pcmk__xpath_find_one(scheduler->input->doc,
40 XPATH_DEPRECATED_RULES,
41 LOG_NEVER);
42
43 if (deprecated != NULL) {
44 pcmk__warn_once(pcmk__wo_op_attr_expr,
45 "Support for rules with node attribute expressions in "
46 PCMK_XE_OP " or " PCMK_XE_OP_DEFAULTS " is deprecated "
47 "and will be dropped in a future release");
48 }
49 }
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72 gboolean
73 cluster_status(pcmk_scheduler_t * scheduler)
74 {
75
76 const char *new_version = NULL;
77 xmlNode *section = NULL;
78
79 if ((scheduler == NULL) || (scheduler->input == NULL)) {
80 return FALSE;
81 }
82
83 if (pcmk_is_set(scheduler->flags, pcmk__sched_have_status)) {
84
85
86
87
88
89
90
91 return TRUE;
92 }
93
94 new_version = crm_element_value(scheduler->input, PCMK_XA_CRM_FEATURE_SET);
95
96 if (pcmk__check_feature_set(new_version) != pcmk_rc_ok) {
97 pcmk__config_err("Can't process CIB with feature set '%s' greater than our own '%s'",
98 new_version, CRM_FEATURE_SET);
99 return FALSE;
100 }
101
102 crm_trace("Beginning unpack");
103
104 pcmk__xml_free(scheduler->priv->failed);
105 scheduler->priv->failed = pcmk__xe_create(NULL, "failed-ops");
106
107 if (scheduler->priv->now == NULL) {
108 scheduler->priv->now = crm_time_new(NULL);
109 }
110
111 if (pcmk__xe_attr_is_true(scheduler->input, PCMK_XA_HAVE_QUORUM)) {
112 pcmk__set_scheduler_flags(scheduler, pcmk__sched_quorate);
113 } else {
114 pcmk__clear_scheduler_flags(scheduler, pcmk__sched_quorate);
115 }
116
117 scheduler->priv->op_defaults =
118 pcmk__xpath_find_one(scheduler->input->doc, "//" PCMK_XE_OP_DEFAULTS,
119 LOG_NEVER);
120 check_for_deprecated_rules(scheduler);
121
122 scheduler->priv->rsc_defaults =
123 pcmk__xpath_find_one(scheduler->input->doc, "//" PCMK_XE_RSC_DEFAULTS,
124 LOG_NEVER);
125
126 section = pcmk__xpath_find_one(scheduler->input->doc,
127 "//" PCMK_XE_CRM_CONFIG, LOG_TRACE);
128 unpack_config(section, scheduler);
129
130 if (!pcmk_any_flags_set(scheduler->flags,
131 pcmk__sched_location_only|pcmk__sched_quorate)
132 && (scheduler->no_quorum_policy != pcmk_no_quorum_ignore)) {
133 pcmk__sched_warn(scheduler,
134 "Fencing and resource management disabled "
135 "due to lack of quorum");
136 }
137
138 section = pcmk__xpath_find_one(scheduler->input->doc, "//" PCMK_XE_NODES,
139 LOG_TRACE);
140 unpack_nodes(section, scheduler);
141
142 section = pcmk__xpath_find_one(scheduler->input->doc,
143 "//" PCMK_XE_RESOURCES, LOG_TRACE);
144 if (!pcmk_is_set(scheduler->flags, pcmk__sched_location_only)) {
145 unpack_remote_nodes(section, scheduler);
146 }
147 unpack_resources(section, scheduler);
148
149 section = pcmk__xpath_find_one(scheduler->input->doc,
150 "//" PCMK_XE_FENCING_TOPOLOGY, LOG_TRACE);
151 pcmk__validate_fencing_topology(section);
152
153 section = pcmk__xpath_find_one(scheduler->input->doc, "//" PCMK_XE_TAGS,
154 LOG_NEVER);
155 unpack_tags(section, scheduler);
156
157 if (!pcmk_is_set(scheduler->flags, pcmk__sched_location_only)) {
158 section = pcmk__xpath_find_one(scheduler->input->doc,
159 "//" PCMK_XE_STATUS, LOG_TRACE);
160 unpack_status(section, scheduler);
161 }
162
163 if (!pcmk_is_set(scheduler->flags, pcmk__sched_no_counts)) {
164 for (GList *item = scheduler->priv->resources;
165 item != NULL; item = item->next) {
166
167 pcmk_resource_t *rsc = item->data;
168
169 rsc->priv->fns->count(item->data);
170 }
171 crm_trace("Cluster resource count: %d (%d disabled, %d blocked)",
172 scheduler->priv->ninstances,
173 scheduler->priv->disabled_resources,
174 scheduler->priv->blocked_resources);
175 }
176
177 if ((scheduler->priv->local_node_name != NULL)
178 && (pcmk_find_node(scheduler,
179 scheduler->priv->local_node_name) == NULL)) {
180 crm_info("Creating a fake local node for %s",
181 scheduler->priv->local_node_name);
182 pe_create_node(scheduler->priv->local_node_name,
183 scheduler->priv->local_node_name, NULL, 0, scheduler);
184 }
185
186 pcmk__set_scheduler_flags(scheduler, pcmk__sched_have_status);
187 return TRUE;
188 }
189
190 pcmk_resource_t *
191 pe_find_resource(GList *rsc_list, const char *id)
192 {
193 return pe_find_resource_with_flags(rsc_list, id, pcmk_rsc_match_history);
194 }
195
196 pcmk_resource_t *
197 pe_find_resource_with_flags(GList *rsc_list, const char *id, enum pe_find flags)
198 {
199 GList *rIter = NULL;
200
201 for (rIter = rsc_list; id && rIter; rIter = rIter->next) {
202 pcmk_resource_t *parent = rIter->data;
203 pcmk_resource_t *match = parent->priv->fns->find_rsc(parent, id, NULL,
204 (uint32_t) flags);
205
206 if (match != NULL) {
207 return match;
208 }
209 }
210 crm_trace("No match for %s", id);
211 return NULL;
212 }
213
214
215
216
217
218
219
220
221
222
223
224
225 pcmk_node_t *
226 pe_find_node_any(const GList *nodes, const char *id, const char *uname)
227 {
228 pcmk_node_t *match = NULL;
229
230 if (id != NULL) {
231 match = pe_find_node_id(nodes, id);
232 }
233 if ((match == NULL) && (uname != NULL)) {
234 match = pcmk__find_node_in_list(nodes, uname);
235 }
236 return match;
237 }
238
239
240
241
242
243
244
245
246
247 pcmk_node_t *
248 pe_find_node_id(const GList *nodes, const char *id)
249 {
250 for (const GList *iter = nodes; iter != NULL; iter = iter->next) {
251 pcmk_node_t *node = (pcmk_node_t *) iter->data;
252
253
254
255
256
257 if (pcmk__str_eq(node->priv->id, id, pcmk__str_casei)) {
258 return node;
259 }
260 }
261 return NULL;
262 }
263
264
265
266
267 #include <crm/pengine/status_compat.h>
268
269 pcmk_scheduler_t *
270 pe_new_working_set(void)
271 {
272 return pcmk_new_scheduler();
273 }
274
275 void
276 pe_reset_working_set(pcmk_scheduler_t *scheduler)
277 {
278 if (scheduler == NULL) {
279 return;
280 }
281 pcmk_reset_scheduler(scheduler);
282 }
283
284 void
285 cleanup_calculations(pcmk_scheduler_t *scheduler)
286 {
287 if (scheduler == NULL) {
288 return;
289 }
290
291 pcmk__clear_scheduler_flags(scheduler, pcmk__sched_have_status);
292 if (scheduler->priv->options != NULL) {
293 g_hash_table_destroy(scheduler->priv->options);
294 }
295
296 if (scheduler->priv->singletons != NULL) {
297 g_hash_table_destroy(scheduler->priv->singletons);
298 }
299
300 if (scheduler->priv->ticket_constraints != NULL) {
301 g_hash_table_destroy(scheduler->priv->ticket_constraints);
302 }
303
304 if (scheduler->priv->templates != NULL) {
305 g_hash_table_destroy(scheduler->priv->templates);
306 }
307
308 if (scheduler->priv->tags != NULL) {
309 g_hash_table_destroy(scheduler->priv->tags);
310 }
311
312 crm_trace("deleting resources");
313 g_list_free_full(scheduler->priv->resources, pcmk__free_resource);
314
315 crm_trace("deleting actions");
316 g_list_free_full(scheduler->priv->actions, pcmk__free_action);
317
318 crm_trace("deleting nodes");
319 g_list_free_full(scheduler->nodes, pcmk__free_node);
320 scheduler->nodes = NULL;
321
322 pcmk__free_param_checks(scheduler);
323 g_list_free(scheduler->priv->stop_needed);
324 crm_time_free(scheduler->priv->now);
325 pcmk__xml_free(scheduler->input);
326 pcmk__xml_free(scheduler->priv->failed);
327 pcmk__xml_free(scheduler->priv->graph);
328
329 set_working_set_defaults(scheduler);
330
331 CRM_LOG_ASSERT((scheduler->priv->location_constraints == NULL)
332 && (scheduler->priv->ordering_constraints == NULL));
333 }
334
335 void
336 set_working_set_defaults(pcmk_scheduler_t *scheduler)
337 {
338
339 pcmk__scheduler_private_t *priv = scheduler->priv;
340 pcmk__output_t *out = priv->out;
341 char *local_node_name = scheduler->priv->local_node_name;
342
343
344 memset(scheduler, 0, sizeof(pcmk_scheduler_t));
345 memset(priv, 0, sizeof(pcmk__scheduler_private_t));
346
347
348 scheduler->priv = priv;
349 scheduler->priv->out = out;
350 scheduler->priv->local_node_name = local_node_name;
351
352
353 pcmk__set_scheduler_defaults(scheduler);
354 }
355
356 void
357 pe_free_working_set(pcmk_scheduler_t *scheduler)
358 {
359 pcmk_free_scheduler(scheduler);
360 }
361
362 pcmk_node_t *
363 pe_find_node(const GList *nodes, const char *node_name)
364 {
365 return pcmk__find_node_in_list(nodes, node_name);
366 }
367
368
369