1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
|
/*
* Copyright 2004-2023 the Pacemaker project contributors
*
* The version control history for this file may have further details.
*
* This source code is licensed under the GNU Lesser General Public License
* version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
*/
#ifndef PCMK__CRM_COMMON_RESOURCES__H
# define PCMK__CRM_COMMON_RESOURCES__H
#include <sys/types.h> // time_t
#include <libxml/tree.h> // xmlNode
#include <glib.h> // gboolean, guint, GList, GHashTable
#include <crm/common/roles.h> // enum rsc_role_e
#include <crm/common/scheduler_types.h> // pcmk_resource_t, etc.
#ifdef __cplusplus
extern "C" {
#endif
/*!
* \file
* \brief Scheduler API for resources
* \ingroup core
*/
//! Resource variants supported by Pacemaker
enum pe_obj_types {
// Order matters: some code compares greater or lesser than
pcmk_rsc_variant_unknown = -1, //!< Unknown resource variant
pcmk_rsc_variant_primitive = 0, //!< Primitive resource
pcmk_rsc_variant_group = 1, //!< Group resource
pcmk_rsc_variant_clone = 2, //!< Clone resource
pcmk_rsc_variant_bundle = 3, //!< Bundle resource
#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
//! \deprecated Use pcmk_rsc_variant_unknown instead
pe_unknown = pcmk_rsc_variant_unknown,
//! \deprecated Use pcmk_rsc_variant_primitive instead
pe_native = pcmk_rsc_variant_primitive,
//! \deprecated Use pcmk_rsc_variant_group instead
pe_group = pcmk_rsc_variant_group,
//! \deprecated Use pcmk_rsc_variant_clone instead
pe_clone = pcmk_rsc_variant_clone,
//! \deprecated Use pcmk_rsc_variant_bundle instead
pe_container = pcmk_rsc_variant_bundle,
#endif
};
//! What resource needs before it can be recovered from a failed node
enum rsc_start_requirement {
pcmk_requires_nothing = 0, //!< Resource can be recovered immediately
pcmk_requires_quorum = 1, //!< Resource can be recovered if quorate
pcmk_requires_fencing = 2, //!< Resource can be recovered after fencing
#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
//! \deprecated Use pcmk_requires_nothing instead
rsc_req_nothing = pcmk_requires_nothing,
//! \deprecated Use pcmk_requires_quorum instead
rsc_req_quorum = pcmk_requires_quorum,
//! \deprecated Use pcmk_requires_fencing instead
rsc_req_stonith = pcmk_requires_fencing,
#endif
};
//! How to recover a resource that is incorrectly active on multiple nodes
enum rsc_recovery_type {
pcmk_multiply_active_restart = 0, //!< Stop on all, start on desired
pcmk_multiply_active_stop = 1, //!< Stop on all and leave stopped
pcmk_multiply_active_block = 2, //!< Do nothing to resource
pcmk_multiply_active_unexpected = 3, //!< Stop unexpected instances
#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
//! \deprecated Use pcmk_multiply_active_restart instead
recovery_stop_start = pcmk_multiply_active_restart,
//! \deprecated Use pcmk_multiply_active_stop instead
recovery_stop_only = pcmk_multiply_active_stop,
//! \deprecated Use pcmk_multiply_active_block instead
recovery_block = pcmk_multiply_active_block,
//! \deprecated Use pcmk_multiply_active_unexpected instead
recovery_stop_unexpected = pcmk_multiply_active_unexpected,
#endif
};
//! Resource scheduling flags
enum pcmk_rsc_flags {
//! No resource flags set (compare with equality rather than bit set)
pcmk_no_rsc_flags = 0ULL,
//! Whether resource has been removed from the configuration
pcmk_rsc_removed = (1ULL << 0),
//! Whether resource is managed
pcmk_rsc_managed = (1ULL << 1),
//! Whether resource is blocked from further action
pcmk_rsc_blocked = (1ULL << 2),
//! Whether resource has been removed but has a container
pcmk_rsc_removed_filler = (1ULL << 3),
//! Whether resource has clone notifications enabled
pcmk_rsc_notify = (1ULL << 4),
//! Whether resource is not an anonymous clone instance
pcmk_rsc_unique = (1ULL << 5),
//! Whether resource's class is "stonith"
pcmk_rsc_fence_device = (1ULL << 6),
//! Whether resource can be promoted and demoted
pcmk_rsc_promotable = (1ULL << 7),
//! Whether resource has not yet been assigned to a node
pcmk_rsc_unassigned = (1ULL << 8),
//! Whether resource is in the process of being assigned to a node
pcmk_rsc_assigning = (1ULL << 9),
//! Whether resource is in the process of modifying allowed node scores
pcmk_rsc_updating_nodes = (1ULL << 10),
//! Whether resource is in the process of scheduling actions to restart
pcmk_rsc_restarting = (1ULL << 11),
//! Whether resource must be stopped (instead of demoted) if it is failed
pcmk_rsc_stop_if_failed = (1ULL << 12),
//! Whether a reload action has been scheduled for resource
pcmk_rsc_reload = (1ULL << 13),
//! Whether resource is a remote connection allowed to run on a remote node
pcmk_rsc_remote_nesting_allowed = (1ULL << 14),
//! Whether resource has "critical" meta-attribute enabled
pcmk_rsc_critical = (1ULL << 15),
//! Whether resource is considered failed
pcmk_rsc_failed = (1ULL << 16),
//! Flag for non-scheduler code to use to detect recursion loops
pcmk_rsc_detect_loop = (1ULL << 17),
//! \deprecated Do not use
pcmk_rsc_runnable = (1ULL << 18),
//! Whether resource has pending start action in history
pcmk_rsc_start_pending = (1ULL << 19),
//! \deprecated Do not use
pcmk_rsc_starting = (1ULL << 20),
//! \deprecated Do not use
pcmk_rsc_stopping = (1ULL << 21),
//! Whether resource is multiply active with recovery set to stop_unexpected
pcmk_rsc_stop_unexpected = (1ULL << 22),
//! Whether resource is allowed to live-migrate
pcmk_rsc_migratable = (1ULL << 23),
//! Whether resource has an ignorable failure
pcmk_rsc_ignore_failure = (1ULL << 24),
//! Whether resource is an implicit container resource for a bundle replica
pcmk_rsc_replica_container = (1ULL << 25),
//! Whether resource, its node, or entire cluster is in maintenance mode
pcmk_rsc_maintenance = (1ULL << 26),
//! \deprecated Do not use
pcmk_rsc_has_filler = (1ULL << 27),
//! Whether resource can be started or promoted only on quorate nodes
pcmk_rsc_needs_quorum = (1ULL << 28),
//! Whether resource requires fencing before recovery if on unclean node
pcmk_rsc_needs_fencing = (1ULL << 29),
//! Whether resource can be started or promoted only on unfenced nodes
pcmk_rsc_needs_unfencing = (1ULL << 30),
};
//! Search options for resources (exact resource ID always matches)
enum pe_find {
//! Also match clone instance ID from resource history
pcmk_rsc_match_history = (1 << 0),
//! Also match anonymous clone instances by base name
pcmk_rsc_match_anon_basename = (1 << 1),
//! Match only clones and their instances, by either clone or instance ID
pcmk_rsc_match_clone_only = (1 << 2),
//! If matching by node, compare current node instead of assigned node
pcmk_rsc_match_current_node = (1 << 3),
//! \deprecated Do not use
pe_find_inactive = (1 << 4),
//! Match clone instances (even unique) by base name as well as exact ID
pcmk_rsc_match_basename = (1 << 5),
#if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
//! \deprecated Use pcmk_rsc_match_history instead
pe_find_renamed = pcmk_rsc_match_history,
//! \deprecated Use pcmk_rsc_match_anon_basename instead
pe_find_anon = pcmk_rsc_match_anon_basename,
//! \deprecated Use pcmk_rsc_match_clone_only instead
pe_find_clone = pcmk_rsc_match_clone_only,
//! \deprecated Use pcmk_rsc_match_current_node instead
pe_find_current = pcmk_rsc_match_current_node,
//! \deprecated Use pcmk_rsc_match_basename instead
pe_find_any = pcmk_rsc_match_basename,
#endif
};
//!@{
//! \deprecated Do not use
enum pe_restart {
pe_restart_restart,
pe_restart_ignore,
};
enum pe_print_options {
pe_print_log = (1 << 0),
pe_print_html = (1 << 1),
pe_print_ncurses = (1 << 2),
pe_print_printf = (1 << 3),
pe_print_dev = (1 << 4), // Ignored
pe_print_details = (1 << 5), // Ignored
pe_print_max_details = (1 << 6), // Ignored
pe_print_rsconly = (1 << 7),
pe_print_ops = (1 << 8),
pe_print_suppres_nl = (1 << 9),
pe_print_xml = (1 << 10),
pe_print_brief = (1 << 11),
pe_print_pending = (1 << 12),
pe_print_clone_details = (1 << 13),
pe_print_clone_active = (1 << 14), // Print clone instances only if active
pe_print_implicit = (1 << 15) // Print implicitly created resources
};
//!@}
// Resource assignment methods (implementation defined by libpacemaker)
//! This type should be considered internal to Pacemaker
typedef struct resource_alloc_functions_s pcmk_assignment_methods_t;
//! Resource object methods
typedef struct resource_object_functions_s {
/*!
* \brief Parse variant-specific resource XML from CIB into struct members
*
* \param[in,out] rsc Partially unpacked resource
* \param[in,out] scheduler Scheduler data
*
* \return TRUE if resource was unpacked successfully, otherwise FALSE
*/
gboolean (*unpack)(pcmk_resource_t *rsc, pcmk_scheduler_t *scheduler);
/*!
* \brief Search for a resource ID in a resource and its children
*
* \param[in] rsc Search this resource and its children
* \param[in] id Search for this resource ID
* \param[in] on_node If not NULL, limit search to resources on this node
* \param[in] flags Group of enum pe_find flags
*
* \return Resource that matches search criteria if any, otherwise NULL
*/
pcmk_resource_t *(*find_rsc)(pcmk_resource_t *rsc, const char *search,
const pcmk_node_t *node, int flags);
/*!
* \brief Get value of a resource instance attribute
*
* \param[in,out] rsc Resource to check
* \param[in] node Node to use to evaluate rules
* \param[in] create Ignored
* \param[in] name Name of instance attribute to check
* \param[in,out] scheduler Scheduler data
*
* \return Value of requested attribute if available, otherwise NULL
* \note The caller is responsible for freeing the result using free().
*/
char *(*parameter)(pcmk_resource_t *rsc, pcmk_node_t *node, gboolean create,
const char *name, pcmk_scheduler_t *scheduler);
//! \deprecated Do not use
void (*print)(pcmk_resource_t *rsc, const char *pre_text, long options,
void *print_data);
/*!
* \brief Check whether a resource is active
*
* \param[in] rsc Resource to check
* \param[in] all If \p rsc is collective, all instances must be active
*
* \return TRUE if \p rsc is active, otherwise FALSE
*/
gboolean (*active)(pcmk_resource_t *rsc, gboolean all);
/*!
* \brief Get resource's current or assigned role
*
* \param[in] rsc Resource to check
* \param[in] current If TRUE, check current role, otherwise assigned role
*
* \return Current or assigned role of \p rsc
*/
enum rsc_role_e (*state)(const pcmk_resource_t *rsc, gboolean current);
/*!
* \brief List nodes where a resource (or any of its children) is
*
* \param[in] rsc Resource to check
* \param[out] list List to add result to
* \param[in] current If 0, list nodes where \p rsc is assigned;
* if 1, where active; if 2, where active or pending
*
* \return If list contains only one node, that node, otherwise NULL
*/
pcmk_node_t *(*location)(const pcmk_resource_t *rsc, GList **list,
int current);
/*!
* \brief Free all memory used by a resource
*
* \param[in,out] rsc Resource to free
*/
void (*free)(pcmk_resource_t *rsc);
/*!
* \brief Increment cluster's instance counts for a resource
*
* Given a resource, increment its cluster's ninstances, disabled_resources,
* and blocked_resources counts for the resource and its descendants.
*
* \param[in,out] rsc Resource to count
*/
void (*count)(pcmk_resource_t *rsc);
/*!
* \brief Check whether a given resource is in a list of resources
*
* \param[in] rsc Resource ID to check for
* \param[in] only_rsc List of resource IDs to check
* \param[in] check_parent If TRUE, check top ancestor as well
*
* \return TRUE if \p rsc, its top parent if requested, or '*' is in
* \p only_rsc, otherwise FALSE
*/
gboolean (*is_filtered)(const pcmk_resource_t *rsc, GList *only_rsc,
gboolean check_parent);
/*!
* \brief Find a node (and optionally count all) where resource is active
*
* \param[in] rsc Resource to check
* \param[out] count_all If not NULL, set this to count of active nodes
* \param[out] count_clean If not NULL, set this to count of clean nodes
*
* \return A node where the resource is active, preferring the source node
* if the resource is involved in a partial migration, or a clean,
* online node if the resource's "requires" is "quorum" or
* "nothing", otherwise NULL.
*/
pcmk_node_t *(*active_node)(const pcmk_resource_t *rsc,
unsigned int *count_all,
unsigned int *count_clean);
/*!
* \brief Get maximum resource instances per node
*
* \param[in] rsc Resource to check
*
* \return Maximum number of \p rsc instances that can be active on one node
*/
unsigned int (*max_per_node)(const pcmk_resource_t *rsc);
} pcmk_rsc_methods_t;
//! Implementation of pcmk_resource_t
struct pe_resource_s {
char *id; //!< Resource ID in configuration
char *clone_name; //!< Resource instance ID in history
//! Resource configuration (possibly expanded from template)
xmlNode *xml;
//! Original resource configuration, if using template
xmlNode *orig_xml;
//! Configuration of resource operations (possibly expanded from template)
xmlNode *ops_xml;
pcmk_scheduler_t *cluster; //!< Cluster that resource is part of
pcmk_resource_t *parent; //!< Resource's parent resource, if any
enum pe_obj_types variant; //!< Resource variant
void *variant_opaque; //!< Variant-specific (and private) data
pcmk_rsc_methods_t *fns; //!< Resource object methods
pcmk_assignment_methods_t *cmds; //!< Resource assignment methods
enum rsc_recovery_type recovery_type; //!< How to recover if failed
enum pe_restart restart_type; //!< \deprecated Do not use
int priority; //!< Configured priority
int stickiness; //!< Extra preference for current node
int sort_index; //!< Promotion score on assigned node
int failure_timeout; //!< Failure timeout
int migration_threshold; //!< Migration threshold
guint remote_reconnect_ms; //!< Retry interval for remote connections
char *pending_task; //!< Pending action in history, if any
unsigned long long flags; //!< Group of enum pcmk_rsc_flags
// @TODO Merge these into flags
gboolean is_remote_node; //!< Whether this is a remote connection
gboolean exclusive_discover; //!< Whether exclusive probing is enabled
/* Pay special attention to whether you want to use rsc_cons_lhs and
* rsc_cons directly, which include only colocations explicitly involving
* this resource, or call libpacemaker's pcmk__with_this_colocations() and
* pcmk__this_with_colocations() functions, which may return relevant
* colocations involving the resource's ancestors as well.
*/
//!@{
//! This field should be treated as internal to Pacemaker
GList *rsc_cons_lhs; // Colocations of other resources with this one
GList *rsc_cons; // Colocations of this resource with others
GList *rsc_location; // Location constraints for resource
GList *actions; // Actions scheduled for resource
GList *rsc_tickets; // Ticket constraints for resource
//!@}
pcmk_node_t *allocated_to; //!< Node resource is assigned to
//! The destination node, if migrate_to completed but migrate_from has not
pcmk_node_t *partial_migration_target;
//! The source node, if migrate_to completed but migrate_from has not
pcmk_node_t *partial_migration_source;
//! Nodes where resource may be active
GList *running_on;
//! Nodes where resource has been probed (key is node ID, not name)
GHashTable *known_on;
//! Nodes where resource may run (key is node ID, not name)
GHashTable *allowed_nodes;
enum rsc_role_e role; //!< Resource's current role
enum rsc_role_e next_role; //!< Resource's scheduled next role
GHashTable *meta; //!< Resource's meta-attributes
GHashTable *parameters; //!< \deprecated Use pe_rsc_params() instead
GHashTable *utilization; //!< Resource's utilization attributes
GList *children; //!< Resource's child resources, if any
// Source nodes where stop is needed after migrate_from and migrate_to
GList *dangling_migrations;
pcmk_resource_t *container; //!< Resource containing this one, if any
GList *fillers; //!< Resources contained by this one, if any
// @COMPAT These should be made const at next API compatibility break
pcmk_node_t *pending_node; //!< Node on which pending_task is happening
pcmk_node_t *lock_node; //!< Resource shutdown-locked to this node
time_t lock_time; //!< When shutdown lock started
/*!
* Resource parameters may have node-attribute-based rules, which means the
* values can vary by node. This table has node names as keys and parameter
* name/value tables as values. Use pe_rsc_params() to get the table for a
* given node rather than use this directly.
*/
GHashTable *parameter_cache;
};
#ifdef __cplusplus
}
#endif
#endif // PCMK__CRM_COMMON_RESOURCES__H
|