1 /*
2 * Copyright 2004-2024 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU Lesser General Public License
7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8 */
9
10 #ifndef PCMK__CRM_COMMON_SCHEDULER_INTERNAL__H
11 #define PCMK__CRM_COMMON_SCHEDULER_INTERNAL__H
12
13 #include <crm/common/action_relation_internal.h>
14 #include <crm/common/actions_internal.h>
15 #include <crm/common/attrs_internal.h>
16 #include <crm/common/bundles_internal.h>
17 #include <crm/common/clone_internal.h>
18 #include <crm/common/digest_internal.h>
19 #include <crm/common/failcounts_internal.h>
20 #include <crm/common/group_internal.h>
21 #include <crm/common/history_internal.h>
22 #include <crm/common/location_internal.h>
23 #include <crm/common/nodes_internal.h>
24 #include <crm/common/primitive_internal.h>
25 #include <crm/common/remote_internal.h>
26 #include <crm/common/resources_internal.h>
27 #include <crm/common/roles_internal.h>
28 #include <crm/common/rules_internal.h>
29 #include <crm/common/tickets_internal.h>
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 enum pcmk__check_parameters {
36 /* Clear fail count if parameters changed for un-expired start or monitor
37 * last_failure.
38 */
39 pcmk__check_last_failure,
40
41 /* Clear fail count if parameters changed for start, monitor, promote, or
42 * migrate_from actions for active resources.
43 */
44 pcmk__check_active,
45 };
46
47 // Scheduling options and conditions
48 enum pcmk__scheduler_flags {
49 // No scheduler flags set (compare with equality rather than bit set)
50 pcmk__sched_none = 0ULL,
51
52 /* These flags are dynamically determined conditions */
53
54 // Whether partition has quorum (via \c PCMK_XA_HAVE_QUORUM attribute)
55 //! \deprecated Call pcmk_has_quorum() to check quorum instead
56 pcmk__sched_quorate = (1ULL << 0),
57
58 // Whether cluster is symmetric (via symmetric-cluster property)
59 pcmk__sched_symmetric_cluster = (1ULL << 1),
60
61 // Whether scheduling encountered a non-configuration error
62 pcmk__sched_processing_error = (1ULL << 2),
63
64 // Whether cluster is in maintenance mode (via maintenance-mode property)
65 pcmk__sched_in_maintenance = (1ULL << 3),
66
67 // Whether fencing is enabled (via stonith-enabled property)
68 pcmk__sched_fencing_enabled = (1ULL << 4),
69
70 // Whether cluster has a fencing resource (via CIB resources)
71 /*! \deprecated To indicate the cluster has a fencing resource, add either a
72 * fencing resource configuration or the have-watchdog cluster option to the
73 * input CIB
74 */
75 pcmk__sched_have_fencing = (1ULL << 5),
76
77 // Whether any resource provides or requires unfencing (via CIB resources)
78 pcmk__sched_enable_unfencing = (1ULL << 6),
79
80 // Whether concurrent fencing is allowed (via concurrent-fencing property)
81 pcmk__sched_concurrent_fencing = (1ULL << 7),
82
83 /*
84 * Whether resources removed from the configuration should be stopped (via
85 * stop-orphan-resources property)
86 */
87 pcmk__sched_stop_removed_resources = (1ULL << 8),
88
89 /*
90 * Whether recurring actions removed from the configuration should be
91 * cancelled (via stop-orphan-actions property)
92 */
93 pcmk__sched_cancel_removed_actions = (1ULL << 9),
94
95 // Whether to stop all resources (via stop-all-resources property)
96 pcmk__sched_stop_all = (1ULL << 10),
97
98 // Whether scheduler processing encountered a warning
99 pcmk__sched_processing_warning = (1ULL << 11),
100
101 /*
102 * Whether start failure should be treated as if
103 * \c PCMK_META_MIGRATION_THRESHOLD is 1 (via
104 * \c PCMK_OPT_START_FAILURE_IS_FATAL property)
105 */
106 pcmk__sched_start_failure_fatal = (1ULL << 12),
107
108 // Whether unseen nodes should be fenced (via startup-fencing property)
109 pcmk__sched_startup_fencing = (1ULL << 14),
110
111 /*
112 * Whether resources should be left stopped when their node shuts down
113 * cleanly (via shutdown-lock property)
114 */
115 pcmk__sched_shutdown_lock = (1ULL << 15),
116
117 /*
118 * Whether resources' current state should be probed (when unknown) before
119 * scheduling any other actions (via the enable-startup-probes property)
120 */
121 pcmk__sched_probe_resources = (1ULL << 16),
122
123 // Whether the CIB status section has been parsed yet
124 pcmk__sched_have_status = (1ULL << 17),
125
126 // Whether the cluster includes any Pacemaker Remote nodes (via CIB)
127 pcmk__sched_have_remote_nodes = (1ULL << 18),
128
129
130 /* The remaining flags are scheduling options that must be set explicitly */
131
132 /*
133 * Whether to skip unpacking the CIB status section and stop the scheduling
134 * sequence after applying node-specific location criteria (skipping
135 * assignment, ordering, actions, etc.).
136 */
137 pcmk__sched_location_only = (1ULL << 20),
138
139 // Whether sensitive resource attributes have been masked
140 pcmk__sched_sanitized = (1ULL << 21),
141
142 // Skip counting of total, disabled, and blocked resource instances
143 pcmk__sched_no_counts = (1ULL << 23),
144
145 // Whether node scores should be output instead of logged
146 pcmk__sched_output_scores = (1ULL << 25),
147
148 // Whether to show node and resource utilization (in log or output)
149 pcmk__sched_show_utilization = (1ULL << 26),
150
151 /*
152 * Whether to stop the scheduling sequence after unpacking the CIB,
153 * calculating cluster status, and applying node health (skipping
154 * applying node-specific location criteria, assignment, etc.)
155 */
156 pcmk__sched_validate_only = (1ULL << 27),
157 };
158
159 // Implementation of pcmk__scheduler_private_t
160 struct pcmk__scheduler_private {
161 // Be careful about when each piece of information is available and final
162
163 char *local_node_name; // Name of node running scheduler (if known)
164 crm_time_t *now; // Time to use when evaluating rules
165 pcmk__output_t *out; // Output object for displaying messages
166 GHashTable *options; // Cluster options
167 const char *fence_action; // Default fencing action
168 guint fence_timeout_ms; // Default fencing action timeout (in ms)
169 guint priority_fencing_ms; // Priority-based fencing delay (in ms)
170 guint shutdown_lock_ms; // How long to lock resources (in ms)
171 guint node_pending_ms; // Pending join times out after this (in ms)
172 const char *placement_strategy; // Value of placement-strategy property
173 xmlNode *rsc_defaults; // Configured resource defaults
174 xmlNode *op_defaults; // Configured operation defaults
175 GList *resources; // Resources in cluster
176 GHashTable *templates; // Key = template ID, value = resource list
177 GHashTable *tags; // Key = tag ID, value = element list
178 GList *actions; // All scheduled actions
179 GHashTable *singletons; // Scheduled non-resource actions
180 int next_action_id; // Counter used as ID for actions
181 xmlNode *failed; // History entries of failed actions
182 GList *param_check; // History entries that need to be checked
183 GList *stop_needed; // Containers that need stop actions
184 GList *location_constraints; // Location constraints
185 GList *colocation_constraints; // Colocation constraints
186 GList *ordering_constraints; // Ordering constraints
187 GHashTable *ticket_constraints; // Key = ticket ID, value = pcmk__ticket_t
188 int next_ordering_id; // Counter used as ID for orderings
189 int ninstances; // Total number of resource instances
190 int blocked_resources; // Number of blocked resources in cluster
191 int disabled_resources; // Number of disabled resources in cluster
192 time_t recheck_by; // Hint to controller when to reschedule
193 xmlNode *graph; // Transition graph
194 int synapse_count; // Number of transition graph synapses
195 };
196
197 // Group of enum pcmk__warnings flags for warnings we want to log once
198 extern uint32_t pcmk__warnings;
199
200 /*!
201 * \internal
202 * \brief Log a resource-tagged message at info severity
203 *
204 * \param[in] rsc Tag message with this resource's ID
205 * \param[in] fmt... printf(3)-style format and arguments
206 */
207 #define pcmk__rsc_info(rsc, fmt, args...) \
208 crm_log_tag(LOG_INFO, ((rsc) == NULL)? "<NULL>" : (rsc)->id, (fmt), ##args)
209
210 /*!
211 * \internal
212 * \brief Log a resource-tagged message at debug severity
213 *
214 * \param[in] rsc Tag message with this resource's ID
215 * \param[in] fmt... printf(3)-style format and arguments
216 */
217 #define pcmk__rsc_debug(rsc, fmt, args...) \
218 crm_log_tag(LOG_DEBUG, ((rsc) == NULL)? "<NULL>" : (rsc)->id, (fmt), ##args)
219
220 /*!
221 * \internal
222 * \brief Log a resource-tagged message at trace severity
223 *
224 * \param[in] rsc Tag message with this resource's ID
225 * \param[in] fmt... printf(3)-style format and arguments
226 */
227 #define pcmk__rsc_trace(rsc, fmt, args...) \
228 crm_log_tag(LOG_TRACE, ((rsc) == NULL)? "<NULL>" : (rsc)->id, (fmt), ##args)
229
230 /*!
231 * \internal
232 * \brief Log an error and remember that current scheduler input has errors
233 *
234 * \param[in,out] scheduler Scheduler data
235 * \param[in] fmt... printf(3)-style format and arguments
236 */
237 #define pcmk__sched_err(scheduler, fmt...) do { \
238 pcmk__set_scheduler_flags((scheduler), \
239 pcmk__sched_processing_error); \
240 crm_err(fmt); \
241 } while (0)
242
243 /*!
244 * \internal
245 * \brief Log a warning and remember that current scheduler input has warnings
246 *
247 * \param[in,out] scheduler Scheduler data
248 * \param[in] fmt... printf(3)-style format and arguments
249 */
250 #define pcmk__sched_warn(scheduler, fmt...) do { \
251 pcmk__set_scheduler_flags((scheduler), \
252 pcmk__sched_processing_warning); \
253 crm_warn(fmt); \
254 } while (0)
255
256 /*!
257 * \internal
258 * \brief Set scheduler flags
259 *
260 * \param[in,out] scheduler Scheduler data
261 * \param[in] flags_to_set Group of enum pcmk__scheduler_flags to set
262 */
263 #define pcmk__set_scheduler_flags(scheduler, flags_to_set) do { \
264 (scheduler)->flags = pcmk__set_flags_as(__func__, __LINE__, \
265 LOG_TRACE, "Scheduler", crm_system_name, \
266 (scheduler)->flags, (flags_to_set), #flags_to_set); \
267 } while (0)
268
269 /*!
270 * \internal
271 * \brief Clear scheduler flags
272 *
273 * \param[in,out] scheduler Scheduler data
274 * \param[in] flags_to_clear Group of enum pcmk__scheduler_flags to clear
275 */
276 #define pcmk__clear_scheduler_flags(scheduler, flags_to_clear) do { \
277 (scheduler)->flags = pcmk__clear_flags_as(__func__, __LINE__, \
278 LOG_TRACE, "Scheduler", crm_system_name, \
279 (scheduler)->flags, (flags_to_clear), #flags_to_clear); \
280 } while (0)
281
282 #ifdef __cplusplus
283 }
284 #endif
285
286 #endif // PCMK__CRM_COMMON_SCHEDULER_INTERNAL__H