1 /* 2 * Copyright 2004-2025 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 /* Can Pacemaker Remote nodes be fenced even from a node that doesn't 159 * have quorum? 160 */ 161 pcmk__sched_fence_remote_no_quorum = (1ULL << 28), 162 }; 163 164 // Implementation of pcmk__scheduler_private_t 165 struct pcmk__scheduler_private { 166 // Be careful about when each piece of information is available and final 167 168 char *local_node_name; // Name of node running scheduler (if known) 169 crm_time_t *now; // Time to use when evaluating rules 170 pcmk__output_t *out; // Output object for displaying messages 171 GHashTable *options; // Cluster options 172 const char *fence_action; // Default fencing action 173 guint fence_timeout_ms; // Default fencing action timeout (in ms) 174 guint priority_fencing_ms; // Priority-based fencing delay (in ms) 175 guint shutdown_lock_ms; // How long to lock resources (in ms) 176 guint node_pending_ms; // Pending join times out after this (in ms) 177 178 // @TODO convert to enum 179 const char *placement_strategy; // Value of placement-strategy property 180 181 xmlNode *rsc_defaults; // Configured resource defaults 182 xmlNode *op_defaults; // Configured operation defaults 183 GList *resources; // Resources in cluster 184 GHashTable *templates; // Key = template ID, value = resource list 185 GHashTable *tags; // Key = tag ID, value = element list 186 GList *actions; // All scheduled actions 187 GHashTable *singletons; // Scheduled non-resource actions 188 int next_action_id; // Counter used as ID for actions 189 xmlNode *failed; // History entries of failed actions 190 GList *param_check; // History entries that need to be checked 191 GList *stop_needed; // Containers that need stop actions 192 GList *location_constraints; // Location constraints 193 GList *colocation_constraints; // Colocation constraints 194 GList *ordering_constraints; // Ordering constraints 195 GHashTable *ticket_constraints; // Key = ticket ID, value = pcmk__ticket_t 196 int next_ordering_id; // Counter used as ID for orderings 197 int ninstances; // Total number of resource instances 198 int blocked_resources; // Number of blocked resources in cluster 199 int disabled_resources; // Number of disabled resources in cluster 200 time_t recheck_by; // Hint to controller when to reschedule 201 xmlNode *graph; // Transition graph 202 int synapse_count; // Number of transition graph synapses 203 }; 204 205 // Group of enum pcmk__warnings flags for warnings we want to log once 206 extern uint32_t pcmk__warnings; 207 208 /*! 209 * \internal 210 * \brief Log a resource-tagged message at info severity 211 * 212 * \param[in] rsc Tag message with this resource's ID 213 * \param[in] fmt... printf(3)-style format and arguments 214 */ 215 #define pcmk__rsc_info(rsc, fmt, args...) \ 216 crm_log_tag(LOG_INFO, ((rsc) == NULL)? "<NULL>" : (rsc)->id, (fmt), ##args) 217 218 /*! 219 * \internal 220 * \brief Log a resource-tagged message at debug severity 221 * 222 * \param[in] rsc Tag message with this resource's ID 223 * \param[in] fmt... printf(3)-style format and arguments 224 */ 225 #define pcmk__rsc_debug(rsc, fmt, args...) \ 226 crm_log_tag(LOG_DEBUG, ((rsc) == NULL)? "<NULL>" : (rsc)->id, (fmt), ##args) 227 228 /*! 229 * \internal 230 * \brief Log a resource-tagged message at trace severity 231 * 232 * \param[in] rsc Tag message with this resource's ID 233 * \param[in] fmt... printf(3)-style format and arguments 234 */ 235 #define pcmk__rsc_trace(rsc, fmt, args...) \ 236 crm_log_tag(LOG_TRACE, ((rsc) == NULL)? "<NULL>" : (rsc)->id, (fmt), ##args) 237 238 /*! 239 * \internal 240 * \brief Log an error and remember that current scheduler input has errors 241 * 242 * \param[in,out] scheduler Scheduler data 243 * \param[in] fmt... printf(3)-style format and arguments 244 */ 245 #define pcmk__sched_err(scheduler, fmt...) do { \ 246 pcmk__set_scheduler_flags((scheduler), \ 247 pcmk__sched_processing_error); \ 248 crm_err(fmt); \ 249 } while (0) 250 251 /*! 252 * \internal 253 * \brief Log a warning and remember that current scheduler input has warnings 254 * 255 * \param[in,out] scheduler Scheduler data 256 * \param[in] fmt... printf(3)-style format and arguments 257 */ 258 #define pcmk__sched_warn(scheduler, fmt...) do { \ 259 pcmk__set_scheduler_flags((scheduler), \ 260 pcmk__sched_processing_warning); \ 261 crm_warn(fmt); \ 262 } while (0) 263 264 /*! 265 * \internal 266 * \brief Set scheduler flags 267 * 268 * \param[in,out] scheduler Scheduler data 269 * \param[in] flags_to_set Group of enum pcmk__scheduler_flags to set 270 */ 271 #define pcmk__set_scheduler_flags(scheduler, flags_to_set) do { \ 272 (scheduler)->flags = pcmk__set_flags_as(__func__, __LINE__, \ 273 LOG_TRACE, "Scheduler", crm_system_name, \ 274 (scheduler)->flags, (flags_to_set), #flags_to_set); \ 275 } while (0) 276 277 /*! 278 * \internal 279 * \brief Clear scheduler flags 280 * 281 * \param[in,out] scheduler Scheduler data 282 * \param[in] flags_to_clear Group of enum pcmk__scheduler_flags to clear 283 */ 284 #define pcmk__clear_scheduler_flags(scheduler, flags_to_clear) do { \ 285 (scheduler)->flags = pcmk__clear_flags_as(__func__, __LINE__, \ 286 LOG_TRACE, "Scheduler", crm_system_name, \ 287 (scheduler)->flags, (flags_to_clear), #flags_to_clear); \ 288 } while (0) 289 290 void pcmk__set_scheduler_defaults(pcmk_scheduler_t *scheduler); 291 time_t pcmk__scheduler_epoch_time(pcmk_scheduler_t *scheduler); 292 void pcmk__update_recheck_time(time_t recheck, pcmk_scheduler_t *scheduler, 293 const char *reason); 294 295 void pcmk__add_param_check(const xmlNode *rsc_op, pcmk_resource_t *rsc, 296 pcmk_node_t *node, enum pcmk__check_parameters); 297 void pcmk__foreach_param_check(pcmk_scheduler_t *scheduler, 298 void (*cb)(pcmk_resource_t*, pcmk_node_t*, 299 const xmlNode*, 300 enum pcmk__check_parameters)); 301 void pcmk__free_param_checks(pcmk_scheduler_t *scheduler); 302 303 #ifdef __cplusplus 304 } 305 #endif 306 307 #endif // PCMK__CRM_COMMON_SCHEDULER_INTERNAL__H