1 /*
2  * Copyright 2004-2021 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 PE_TYPES__H
11 #  define PE_TYPES__H
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 /*!
18  * \file
19  * \brief Data types for cluster status
20  * \ingroup pengine
21  */
22 
23 #  include <stdbool.h>              // bool
24 #  include <sys/types.h>            // time_t
25 #  include <libxml/tree.h>          // xmlNode
26 #  include <glib.h>                 // gboolean, guint, GList, GHashTable
27 #  include <crm/common/iso8601.h>
28 #  include <crm/pengine/common.h>
29 
30 typedef struct pe_node_s pe_node_t;
31 typedef struct pe_action_s pe_action_t;
32 typedef struct pe_resource_s pe_resource_t;
33 typedef struct pe_working_set_s pe_working_set_t;
34 
35 enum pe_obj_types {
36     pe_unknown = -1,
37     pe_native = 0,
38     pe_group = 1,
39     pe_clone = 2,
40     pe_container = 3,
41 };
42 
43 typedef struct resource_object_functions_s {
44     gboolean (*unpack) (pe_resource_t*, pe_working_set_t*);
45     pe_resource_t *(*find_rsc) (pe_resource_t *parent, const char *search,
46                                 const pe_node_t *node, int flags);
47     /* parameter result must be free'd */
48     char *(*parameter) (pe_resource_t*, pe_node_t*, gboolean, const char*,
49                         pe_working_set_t*);
50     //! \deprecated will be removed in a future release
51     void (*print) (pe_resource_t*, const char*, long, void*);
52     gboolean (*active) (pe_resource_t*, gboolean);
53     enum rsc_role_e (*state) (const pe_resource_t*, gboolean);
54     pe_node_t *(*location) (const pe_resource_t*, GList**, int);
55     void (*free) (pe_resource_t*);
56     void (*count) (pe_resource_t*);
57     gboolean (*is_filtered) (pe_resource_t*, GList *, gboolean);
58 } resource_object_functions_t;
59 
60 typedef struct resource_alloc_functions_s resource_alloc_functions_t;
61 
62 enum pe_quorum_policy {
63     no_quorum_freeze,
64     no_quorum_stop,
65     no_quorum_ignore,
66     no_quorum_suicide,
67     no_quorum_demote
68 };
69 
70 enum node_type {
71     node_ping,
72     node_member,
73     node_remote
74 };
75 
76 //! \deprecated will be removed in a future release
77 enum pe_restart {
78     pe_restart_restart,
79     pe_restart_ignore
80 };
81 
82 //! Determine behavior of pe_find_resource_with_flags()
83 enum pe_find {
84     pe_find_renamed  = 0x001, //!< match resource ID or LRM history ID
85     pe_find_anon     = 0x002, //!< match base name of anonymous clone instances
86     pe_find_clone    = 0x004, //!< match only clone instances
87     pe_find_current  = 0x008, //!< match resource active on specified node
88     pe_find_inactive = 0x010, //!< match resource not running anywhere
89     pe_find_any      = 0x020, //!< match base name of any clone instance
90 };
91 
92 // @TODO Make these an enum
93 
94 #  define pe_flag_have_quorum           0x00000001ULL
95 #  define pe_flag_symmetric_cluster     0x00000002ULL
96 #  define pe_flag_maintenance_mode      0x00000008ULL
97 
98 #  define pe_flag_stonith_enabled       0x00000010ULL
99 #  define pe_flag_have_stonith_resource 0x00000020ULL
100 #  define pe_flag_enable_unfencing      0x00000040ULL
101 #  define pe_flag_concurrent_fencing    0x00000080ULL
102 
103 #  define pe_flag_stop_rsc_orphans      0x00000100ULL
104 #  define pe_flag_stop_action_orphans   0x00000200ULL
105 #  define pe_flag_stop_everything       0x00000400ULL
106 
107 #  define pe_flag_start_failure_fatal   0x00001000ULL
108 
109 //! \deprecated
110 #  define pe_flag_remove_after_stop     0x00002000ULL
111 
112 #  define pe_flag_startup_fencing       0x00004000ULL
113 #  define pe_flag_shutdown_lock         0x00008000ULL
114 
115 #  define pe_flag_startup_probes        0x00010000ULL
116 #  define pe_flag_have_status           0x00020000ULL
117 #  define pe_flag_have_remote_nodes     0x00040000ULL
118 
119 #  define pe_flag_quick_location        0x00100000ULL
120 #  define pe_flag_sanitized             0x00200000ULL
121 
122 //! \deprecated
123 #  define pe_flag_stdout                0x00400000ULL
124 
125 //! Don't count total, disabled and blocked resource instances
126 #  define pe_flag_no_counts             0x00800000ULL
127 
128 /*! Skip deprecated code that is kept solely for backward API compatibility.
129  * (Internal code should always set this.)
130  */
131 #  define pe_flag_no_compat             0x01000000ULL
132 
133 #  define pe_flag_show_scores           0x02000000ULL
134 #  define pe_flag_show_utilization      0x04000000ULL
135 
136 struct pe_working_set_s {
137     xmlNode *input;
138     crm_time_t *now;
139 
140     /* options extracted from the input */
141     char *dc_uuid;
142     pe_node_t *dc_node;
143     const char *stonith_action;
144     const char *placement_strategy;
145 
146     unsigned long long flags;
147 
148     int stonith_timeout;
149     enum pe_quorum_policy no_quorum_policy;
150 
151     GHashTable *config_hash;
152     GHashTable *tickets;
153 
154     // Actions for which there can be only one (e.g. fence nodeX)
155     GHashTable *singletons;
156 
157     GList *nodes;
158     GList *resources;
159     GList *placement_constraints;
160     GList *ordering_constraints;
161     GList *colocation_constraints;
162     GList *ticket_constraints;
163 
164     GList *actions;
165     xmlNode *failed;
166     xmlNode *op_defaults;
167     xmlNode *rsc_defaults;
168 
169     /* stats */
170     int num_synapse;
171     int max_valid_nodes;    //! Deprecated (will be removed in a future release)
172     int order_id;
173     int action_id;
174 
175     /* final output */
176     xmlNode *graph;
177 
178     GHashTable *template_rsc_sets;
179     const char *localhost;
180     GHashTable *tags;
181 
182     int blocked_resources;
183     int disabled_resources;
184 
185     GList *param_check; // History entries that need to be checked
186     GList *stop_needed; // Containers that need stop actions
187     time_t recheck_by;  // Hint to controller to re-run scheduler by this time
188     int ninstances;     // Total number of resource instances
189     guint shutdown_lock;// How long (seconds) to lock resources to shutdown node
190     int priority_fencing_delay; // Priority fencing delay
191 
192     void *priv;
193 };
194 
195 enum pe_check_parameters {
196     /* Clear fail count if parameters changed for un-expired start or monitor
197      * last_failure.
198      */
199     pe_check_last_failure,
200 
201     /* Clear fail count if parameters changed for start, monitor, promote, or
202      * migrate_from actions for active resources.
203      */
204     pe_check_active,
205 };
206 
207 struct pe_node_shared_s {
208     const char *id;
209     const char *uname;
210     enum node_type type;
211 
212     /* @TODO convert these flags into a bitfield */
213     gboolean online;
214     gboolean standby;
215     gboolean standby_onfail;
216     gboolean pending;
217     gboolean unclean;
218     gboolean unseen;
219     gboolean shutdown;
220     gboolean expected_up;
221     gboolean is_dc;
222     gboolean maintenance;
223     gboolean rsc_discovery_enabled;
224     gboolean remote_requires_reset;
225     gboolean remote_was_fenced;
226     gboolean remote_maintenance; /* what the remote-rsc is thinking */
227     gboolean unpacked;
228 
229     int num_resources;
230     pe_resource_t *remote_rsc;
231     GList *running_rsc;       /* pe_resource_t* */
232     GList *allocated_rsc;     /* pe_resource_t* */
233 
234     GHashTable *attrs;          /* char* => char* */
235     GHashTable *utilization;
236     GHashTable *digest_cache;   //!< cache of calculated resource digests
237     int priority; // calculated based on the priority of resources running on the node
238 };
239 
240 struct pe_node_s {
241     int weight;
242     gboolean fixed;
243     int count;
244     struct pe_node_shared_s *details;
245     int rsc_discover_mode;
246 };
247 
248 #  define pe_rsc_orphan                     0x00000001ULL
249 #  define pe_rsc_managed                    0x00000002ULL
250 #  define pe_rsc_block                      0x00000004ULL
251 #  define pe_rsc_orphan_container_filler    0x00000008ULL
252 
253 #  define pe_rsc_notify                     0x00000010ULL
254 #  define pe_rsc_unique                     0x00000020ULL
255 #  define pe_rsc_fence_device               0x00000040ULL
256 #  define pe_rsc_promotable                 0x00000080ULL
257 
258 #  define pe_rsc_provisional                0x00000100ULL
259 #  define pe_rsc_allocating                 0x00000200ULL
260 #  define pe_rsc_merging                    0x00000400ULL
261 
262 #  define pe_rsc_stop                       0x00001000ULL
263 #  define pe_rsc_reload                     0x00002000ULL
264 #  define pe_rsc_allow_remote_remotes       0x00004000ULL
265 #  define pe_rsc_critical                   0x00008000ULL
266 
267 #  define pe_rsc_failed                     0x00010000ULL
268 #  define pe_rsc_runnable                   0x00040000ULL
269 #  define pe_rsc_start_pending              0x00080000ULL
270 
271 #  define pe_rsc_starting                   0x00100000ULL
272 #  define pe_rsc_stopping                   0x00200000ULL
273 #  define pe_rsc_allow_migrate              0x00800000ULL
274 
275 #  define pe_rsc_failure_ignored            0x01000000ULL
276 #  define pe_rsc_maintenance                0x04000000ULL
277 #  define pe_rsc_is_container               0x08000000ULL
278 
279 #  define pe_rsc_needs_quorum               0x10000000ULL
280 #  define pe_rsc_needs_fencing              0x20000000ULL
281 #  define pe_rsc_needs_unfencing            0x40000000ULL
282 
283 enum pe_graph_flags {
284     pe_graph_none = 0x00000,
285     pe_graph_updated_first = 0x00001,
286     pe_graph_updated_then = 0x00002,
287     pe_graph_disable = 0x00004,
288 };
289 
290 /* *INDENT-OFF* */
291 enum pe_action_flags {
292     pe_action_pseudo = 0x00001,
293     pe_action_runnable = 0x00002,
294     pe_action_optional = 0x00004,
295     pe_action_print_always = 0x00008,
296 
297     pe_action_have_node_attrs = 0x00010,
298     pe_action_implied_by_stonith = 0x00040,
299     pe_action_migrate_runnable =   0x00080,
300 
301     pe_action_dumped = 0x00100,
302     pe_action_processed = 0x00200,
303 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
304     pe_action_clear = 0x00400, //! \deprecated Unused
305 #endif
306     pe_action_dangle = 0x00800,
307 
308     /* This action requires one or more of its dependencies to be runnable.
309      * We use this to clear the runnable flag before checking dependencies.
310      */
311     pe_action_requires_any = 0x01000,
312 
313     pe_action_reschedule = 0x02000,
314     pe_action_tracking = 0x04000,
315     pe_action_dedup = 0x08000, //! Internal state tracking when creating graph
316 
317     pe_action_dc = 0x10000,         //! Action may run on DC instead of target
318 };
319 /* *INDENT-ON* */
320 
321 struct pe_resource_s {
322     char *id;
323     char *clone_name;
324     xmlNode *xml;
325     xmlNode *orig_xml;
326     xmlNode *ops_xml;
327 
328     pe_working_set_t *cluster;
329     pe_resource_t *parent;
330 
331     enum pe_obj_types variant;
332     void *variant_opaque;
333     resource_object_functions_t *fns;
334     resource_alloc_functions_t *cmds;
335 
336     enum rsc_recovery_type recovery_type;
337 
338     // @TODO only pe_restart_restart is of interest, so merge into flags
339     enum pe_restart restart_type; //!< \deprecated will be removed in future release
340 
341     int priority;
342     int stickiness;
343     int sort_index;
344     int failure_timeout;
345     int migration_threshold;
346     guint remote_reconnect_ms;
347     char *pending_task;
348 
349     unsigned long long flags;
350 
351     // @TODO merge these into flags
352     gboolean is_remote_node;
353     gboolean exclusive_discover;
354 
355     //!@{
356     //! This field should be treated as internal to Pacemaker
357     GList *rsc_cons_lhs;      // List of pcmk__colocation_t*
358     GList *rsc_cons;          // List of pcmk__colocation_t*
359     GList *rsc_location;      // List of pe__location_t*
360     GList *actions;           // List of pe_action_t*
361     GList *rsc_tickets;       // List of rsc_ticket*
362     //!@}
363 
364     pe_node_t *allocated_to;
365     pe_node_t *partial_migration_target;
366     pe_node_t *partial_migration_source;
367     GList *running_on;        /* pe_node_t*   */
368     GHashTable *known_on;       /* pe_node_t*   */
369     GHashTable *allowed_nodes;  /* pe_node_t*   */
370 
371     enum rsc_role_e role;
372     enum rsc_role_e next_role;
373 
374     GHashTable *meta;
375     GHashTable *parameters; //! \deprecated Use pe_rsc_params() instead
376     GHashTable *utilization;
377 
378     GList *children;          /* pe_resource_t*   */
379     GList *dangling_migrations;       /* pe_node_t*       */
380 
381     pe_resource_t *container;
382     GList *fillers;
383 
384     pe_node_t *pending_node;    // Node on which pending_task is happening
385     pe_node_t *lock_node;       // Resource is shutdown-locked to this node
386     time_t lock_time;           // When shutdown lock started
387 
388     /* Resource parameters may have node-attribute-based rules, which means the
389      * values can vary by node. This table is a cache of parameter name/value
390      * tables for each node (as needed). Use pe_rsc_params() to get the table
391      * for a given node.
392      */
393     GHashTable *parameter_cache; // Key = node name, value = parameters table
394 #if ENABLE_VERSIONED_ATTRS
395     xmlNode *versioned_parameters;
396 #endif
397 };
398 
399 #if ENABLE_VERSIONED_ATTRS
400 // Used as action->action_details if action->rsc is not NULL
401 typedef struct pe_rsc_action_details_s {
402     xmlNode *versioned_parameters;
403     xmlNode *versioned_meta;
404 } pe_rsc_action_details_t;
405 #endif
406 
407 struct pe_action_s {
408     int id;
409     int priority;
410 
411     pe_resource_t *rsc;
412     pe_node_t *node;
413     xmlNode *op_entry;
414 
415     char *task;
416     char *uuid;
417     char *cancel_task;
418     char *reason;
419 
420     enum pe_action_flags flags;
421     enum rsc_start_requirement needs;
422     enum action_fail_response on_fail;
423     enum rsc_role_e fail_role;
424 
425     GHashTable *meta;
426     GHashTable *extra;
427 
428     /*
429      * These two varables are associated with the constraint logic
430      * that involves first having one or more actions runnable before
431      * then allowing this action to execute.
432      *
433      * These varables are used with features such as 'clone-min' which
434      * requires at minimum X number of cloned instances to be running
435      * before an order dependency can run. Another option that uses
436      * this is 'require-all=false' in ordering constrants. This option
437      * says "only require one instance of a resource to start before
438      * allowing dependencies to start" -- basically, require-all=false is
439      * the same as clone-min=1.
440      */
441 
442     /* current number of known runnable actions in the before list. */
443     int runnable_before;
444     /* the number of "before" runnable actions required for this action
445      * to be considered runnable */
446     int required_runnable_before;
447 
448     GList *actions_before;    /* pe_action_wrapper_t* */
449     GList *actions_after;     /* pe_action_wrapper_t* */
450 
451     /* Some of the above fields could be moved to the details,
452      * except for API backward compatibility.
453      */
454     void *action_details; // varies by type of action
455 };
456 
457 typedef struct pe_ticket_s {
458     char *id;
459     gboolean granted;
460     time_t last_granted;
461     gboolean standby;
462     GHashTable *state;
463 } pe_ticket_t;
464 
465 typedef struct pe_tag_s {
466     char *id;
467     GList *refs;
468 } pe_tag_t;
469 
470 //! Internal tracking for transition graph creation
471 enum pe_link_state {
472     pe_link_not_dumped, //! Internal tracking for transition graph creation
473     pe_link_dumped,     //! Internal tracking for transition graph creation
474     pe_link_dup,        //! \deprecated No longer used by Pacemaker
475 };
476 
477 enum pe_discover_e {
478     pe_discover_always = 0,
479     pe_discover_never,
480     pe_discover_exclusive,
481 };
482 
483 /* *INDENT-OFF* */
484 enum pe_ordering {
485     pe_order_none                  = 0x0,       /* deleted */
486     pe_order_optional              = 0x1,       /* pure ordering, nothing implied */
487     pe_order_apply_first_non_migratable = 0x2,  /* Only apply this constraint's ordering if first is not migratable. */
488 
489     pe_order_implies_first         = 0x10,      /* If 'then' is required, ensure 'first' is too */
490     pe_order_implies_then          = 0x20,      /* If 'first' is required, ensure 'then' is too */
491     pe_order_promoted_implies_first = 0x40,     /* If 'then' is required and then's rsc is promoted, ensure 'first' becomes required too */
492 
493     /* first requires then to be both runnable and migrate runnable. */
494     pe_order_implies_first_migratable  = 0x80,
495 
496     pe_order_runnable_left         = 0x100,     /* 'then' requires 'first' to be runnable */
497 
498     pe_order_pseudo_left           = 0x200,     /* 'then' can only be pseudo if 'first' is runnable */
499     pe_order_implies_then_on_node  = 0x400,     /* If 'first' is required on 'nodeX',
500                                                  * ensure instances of 'then' on 'nodeX' are too.
501                                                  * Only really useful if 'then' is a clone and 'first' is not
502                                                  */
503     pe_order_probe                 = 0x800,     /* If 'first->rsc' is
504                                                  *  - running but about to stop, ignore the constraint
505                                                  *  - otherwise, behave as runnable_left
506                                                  */
507 
508     pe_order_restart               = 0x1000,    /* 'then' is runnable if 'first' is optional or runnable */
509     pe_order_stonith_stop          = 0x2000,    /* only applies if the action is non-pseudo */
510     pe_order_serialize_only        = 0x4000,    /* serialize */
511     pe_order_same_node             = 0x8000,    /* applies only if 'first' and 'then' are on same node */
512 
513     pe_order_implies_first_printed = 0x10000,   /* Like ..implies_first but only ensures 'first' is printed, not mandatory */
514     pe_order_implies_then_printed  = 0x20000,   /* Like ..implies_then but only ensures 'then' is printed, not mandatory */
515 
516     pe_order_asymmetrical          = 0x100000,  /* Indicates asymmetrical one way ordering constraint. */
517     pe_order_load                  = 0x200000,  /* Only relevant if... */
518     pe_order_one_or_more           = 0x400000,  /* 'then' is runnable only if one or more of its dependencies are too */
519     pe_order_anti_colocation       = 0x800000,
520 
521     pe_order_preserve              = 0x1000000, /* Hack for breaking user ordering constraints with container resources */
522     pe_order_then_cancels_first    = 0x2000000, // if 'then' becomes required, 'first' becomes optional
523     pe_order_trace                 = 0x4000000, /* test marker */
524 
525 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
526     // \deprecated Use pe_order_promoted_implies_first instead
527     pe_order_implies_first_master  = pe_order_promoted_implies_first,
528 #endif
529 };
530 /* *INDENT-ON* */
531 
532 typedef struct pe_action_wrapper_s {
533     enum pe_ordering type;
534     enum pe_link_state state;
535     pe_action_t *action;
536 } pe_action_wrapper_t;
537 
538 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
539 #include <crm/pengine/pe_types_compat.h>
540 #endif
541 
542 #ifdef __cplusplus
543 }
544 #endif
545 
546 #endif // PE_TYPES__H
547