This source file includes following definitions.
- pcmk_new_scheduler
- pcmk__set_scheduler_defaults
- pcmk_reset_scheduler
- pcmk_free_scheduler
- pcmk_get_dc
- pcmk_get_no_quorum_policy
- pcmk_set_scheduler_cib
- pcmk_has_quorum
- pcmk_find_node
- pcmk__scheduler_epoch_time
- pcmk__update_recheck_time
- pcmk__add_param_check
- pcmk__foreach_param_check
- pcmk__free_param_checks
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <stdint.h>
13 #include <errno.h>
14 #include <glib.h>
15 #include <libxml/tree.h>
16
17 #include <crm/common/scheduler.h>
18
19 uint32_t pcmk__warnings = 0;
20
21
22
23
24
25
26
27
28
29
30
31 pcmk_scheduler_t *
32 pcmk_new_scheduler(void)
33 {
34 pcmk_scheduler_t *scheduler = calloc(1, sizeof(pcmk_scheduler_t));
35
36 if (scheduler == NULL) {
37 return NULL;
38 }
39 scheduler->priv = calloc(1, sizeof(pcmk__scheduler_private_t));
40 if (scheduler->priv == NULL) {
41 free(scheduler);
42 return NULL;
43 }
44 pcmk__set_scheduler_defaults(scheduler);
45 return scheduler;
46 }
47
48
49
50
51
52
53
54
55
56 void
57 pcmk__set_scheduler_defaults(pcmk_scheduler_t *scheduler)
58 {
59 pcmk__assert(scheduler != NULL);
60 scheduler->flags = 0U;
61 #if PCMK__CONCURRENT_FENCING_DEFAULT_TRUE
62 pcmk__set_scheduler_flags(scheduler,
63 pcmk__sched_symmetric_cluster
64 |pcmk__sched_concurrent_fencing
65 |pcmk__sched_stop_removed_resources
66 |pcmk__sched_cancel_removed_actions);
67 #else
68 pcmk__set_scheduler_flags(scheduler,
69 pcmk__sched_symmetric_cluster
70 |pcmk__sched_stop_removed_resources
71 |pcmk__sched_cancel_removed_actions);
72 #endif
73 scheduler->no_quorum_policy = pcmk_no_quorum_stop;
74 scheduler->priv->next_action_id = 1;
75 scheduler->priv->next_ordering_id = 1;
76 }
77
78
79
80
81
82
83
84
85
86 void
87 pcmk_reset_scheduler(pcmk_scheduler_t *scheduler)
88 {
89 if (scheduler == NULL) {
90 return;
91 }
92
93
94
95
96
97
98
99
100 scheduler->dc_node = NULL;
101
102 g_list_free_full(scheduler->nodes, pcmk__free_node);
103 scheduler->nodes = NULL;
104
105
106
107 crm_time_free(scheduler->priv->now);
108 scheduler->priv->now = NULL;
109
110 if (scheduler->priv->options != NULL) {
111 g_hash_table_destroy(scheduler->priv->options);
112 scheduler->priv->options = NULL;
113 }
114
115 scheduler->priv->fence_action = NULL;
116 scheduler->priv->fence_timeout_ms = 0U;
117 scheduler->priv->priority_fencing_ms = 0U;
118 scheduler->priv->shutdown_lock_ms = 0U;
119 scheduler->priv->node_pending_ms = 0U;
120 scheduler->priv->placement_strategy = NULL;
121 scheduler->priv->rsc_defaults = NULL;
122 scheduler->priv->op_defaults = NULL;
123
124 g_list_free_full(scheduler->priv->resources, pcmk__free_resource);
125 scheduler->priv->resources = NULL;
126
127 if (scheduler->priv->templates != NULL) {
128 g_hash_table_destroy(scheduler->priv->templates);
129 scheduler->priv->templates = NULL;
130 }
131 if (scheduler->priv->tags != NULL) {
132 g_hash_table_destroy(scheduler->priv->tags);
133 scheduler->priv->tags = NULL;
134 }
135
136 g_list_free_full(scheduler->priv->actions, pcmk__free_action);
137 scheduler->priv->actions = NULL;
138
139 if (scheduler->priv->singletons != NULL) {
140 g_hash_table_destroy(scheduler->priv->singletons);
141 scheduler->priv->singletons = NULL;
142 }
143
144 pcmk__xml_free(scheduler->priv->failed);
145 scheduler->priv->failed = NULL;
146
147 pcmk__free_param_checks(scheduler);
148
149 g_list_free(scheduler->priv->stop_needed);
150 scheduler->priv->stop_needed = NULL;
151
152 g_list_free_full(scheduler->priv->location_constraints,
153 pcmk__free_location);
154 scheduler->priv->location_constraints = NULL;
155
156 g_list_free_full(scheduler->priv->colocation_constraints, free);
157 scheduler->priv->colocation_constraints = NULL;
158
159 g_list_free_full(scheduler->priv->ordering_constraints,
160 pcmk__free_action_relation);
161 scheduler->priv->ordering_constraints = NULL;
162
163 if (scheduler->priv->ticket_constraints != NULL) {
164 g_hash_table_destroy(scheduler->priv->ticket_constraints);
165 scheduler->priv->ticket_constraints = NULL;
166 }
167
168 scheduler->priv->ninstances = 0;
169 scheduler->priv->blocked_resources = 0;
170 scheduler->priv->disabled_resources = 0;
171 scheduler->priv->recheck_by = 0;
172
173 pcmk__xml_free(scheduler->priv->graph);
174 scheduler->priv->graph = NULL;
175
176 scheduler->priv->synapse_count = 0;
177
178 pcmk__xml_free(scheduler->input);
179 scheduler->input = NULL;
180
181 pcmk__set_scheduler_defaults(scheduler);
182
183 pcmk__config_has_error = false;
184 pcmk__config_has_warning = false;
185 }
186
187
188
189
190
191
192 void
193 pcmk_free_scheduler(pcmk_scheduler_t *scheduler)
194 {
195 if (scheduler != NULL) {
196 pcmk_reset_scheduler(scheduler);
197 free(scheduler->priv->local_node_name);
198 free(scheduler->priv);
199 free(scheduler);
200 }
201 }
202
203
204
205
206
207
208
209
210
211 pcmk_node_t *
212 pcmk_get_dc(const pcmk_scheduler_t *scheduler)
213 {
214 return (scheduler == NULL)? NULL : scheduler->dc_node;
215 }
216
217
218
219
220
221
222
223
224
225 enum pe_quorum_policy
226 pcmk_get_no_quorum_policy(const pcmk_scheduler_t *scheduler)
227 {
228 if (scheduler == NULL) {
229 return pcmk_no_quorum_stop;
230 }
231 return scheduler->no_quorum_policy;
232 }
233
234
235
236
237
238
239
240
241
242
243
244
245 int
246 pcmk_set_scheduler_cib(pcmk_scheduler_t *scheduler, xmlNode *cib)
247 {
248 if (scheduler == NULL) {
249 return EINVAL;
250 }
251 scheduler->input = cib;
252 return pcmk_rc_ok;
253 }
254
255
256
257
258
259
260
261
262
263 bool
264 pcmk_has_quorum(const pcmk_scheduler_t *scheduler)
265 {
266 if (scheduler == NULL) {
267 return false;
268 }
269 return pcmk_is_set(scheduler->flags, pcmk__sched_quorate);
270 }
271
272
273
274
275
276
277
278
279
280
281 pcmk_node_t *
282 pcmk_find_node(const pcmk_scheduler_t *scheduler, const char *node_name)
283 {
284 if ((scheduler == NULL) || (node_name == NULL)) {
285 return NULL;
286 }
287 return pcmk__find_node_in_list(scheduler->nodes, node_name);
288 }
289
290
291
292
293
294
295
296
297
298
299 time_t
300 pcmk__scheduler_epoch_time(pcmk_scheduler_t *scheduler)
301 {
302 if (scheduler == NULL) {
303 return time(NULL);
304 }
305 if (scheduler->priv->now == NULL) {
306 crm_trace("Scheduler 'now' set to current time");
307 scheduler->priv->now = crm_time_new(NULL);
308 }
309 return crm_time_get_seconds_since_epoch(scheduler->priv->now);
310 }
311
312
313
314
315
316
317
318
319
320 void
321 pcmk__update_recheck_time(time_t recheck, pcmk_scheduler_t *scheduler,
322 const char *reason)
323 {
324 pcmk__assert(scheduler != NULL);
325
326 if ((recheck > pcmk__scheduler_epoch_time(scheduler))
327 && ((scheduler->priv->recheck_by == 0)
328 || (scheduler->priv->recheck_by > recheck))) {
329 scheduler->priv->recheck_by = recheck;
330 crm_debug("Updated next scheduler recheck to %s for %s",
331 pcmk__trim(ctime(&recheck)),
332 pcmk__s(reason, "some reason"));
333 }
334 }
335
336
337
338
339
340
341
342
343 struct param_check {
344 const xmlNode *rsc_history;
345 pcmk_resource_t *rsc;
346 pcmk_node_t *node;
347 enum pcmk__check_parameters check_type;
348 };
349
350
351
352
353
354
355
356
357
358
359 void
360 pcmk__add_param_check(const xmlNode *rsc_history, pcmk_resource_t *rsc,
361 pcmk_node_t *node, enum pcmk__check_parameters flag)
362 {
363 struct param_check *param_check = NULL;
364
365 CRM_CHECK((rsc_history != NULL) && (rsc != NULL) && (node != NULL), return);
366
367 crm_trace("Deferring checks of %s until after assignment",
368 pcmk__xe_id(rsc_history));
369 param_check = pcmk__assert_alloc(1, sizeof(struct param_check));
370 param_check->rsc_history = rsc_history;
371 param_check->rsc = rsc;
372 param_check->node = node;
373 param_check->check_type = flag;
374
375 rsc->priv->scheduler->priv->param_check =
376 g_list_prepend(rsc->priv->scheduler->priv->param_check, param_check);
377 }
378
379
380
381
382
383
384
385
386 void
387 pcmk__foreach_param_check(pcmk_scheduler_t *scheduler,
388 void (*cb)(pcmk_resource_t*, pcmk_node_t*,
389 const xmlNode*,
390 enum pcmk__check_parameters))
391 {
392 CRM_CHECK((scheduler != NULL) && (cb != NULL), return);
393
394 for (GList *item = scheduler->priv->param_check;
395 item != NULL; item = item->next) {
396 struct param_check *param_check = item->data;
397
398 cb(param_check->rsc, param_check->node, param_check->rsc_history,
399 param_check->check_type);
400 }
401 }
402
403
404
405
406
407
408
409 void
410 pcmk__free_param_checks(pcmk_scheduler_t *scheduler)
411 {
412 if ((scheduler != NULL) && (scheduler->priv->param_check != NULL)) {
413 g_list_free_full(scheduler->priv->param_check, free);
414 scheduler->priv->param_check = NULL;
415 }
416 }