47 ticket_role_matches(
const pcmk_resource_t *rsc,
const rsc_ticket_t *rsc_ticket)
50 || (rsc_ticket->role == rsc->
role)) {
65 constraints_for_ticket(
pcmk_resource_t *rsc,
const rsc_ticket_t *rsc_ticket)
69 CRM_CHECK((rsc != NULL) && (rsc_ticket != NULL),
return);
71 if (rsc_ticket->ticket->granted && !rsc_ticket->ticket->standby) {
77 for (iter = rsc->
children; iter != NULL; iter = iter->next) {
84 rsc->
id, rsc_ticket->ticket->id, rsc_ticket->id,
87 if (!rsc_ticket->ticket->granted && (rsc->
running_on != NULL)) {
89 switch (rsc_ticket->loss_policy) {
92 "__loss_of_ticket__", rsc->
cluster);
99 "__loss_of_ticket__", rsc->
cluster);
104 if (!ticket_role_matches(rsc, rsc_ticket)) {
109 "__loss_of_ticket__", rsc->
cluster);
111 for (iter = rsc->
running_on; iter != NULL; iter = iter->next) {
113 "deadman ticket was lost", FALSE);
118 if (!ticket_role_matches(rsc, rsc_ticket)) {
128 }
else if (!rsc_ticket->ticket->granted) {
133 "__no_ticket__", rsc->
cluster);
136 }
else if (rsc_ticket->ticket->standby) {
141 "__ticket_standby__", rsc->
cluster);
148 const char *state,
const char *loss_policy)
150 rsc_ticket_t *new_rsc_ticket = NULL;
154 "does not exist",
id);
158 new_rsc_ticket = calloc(1,
sizeof(rsc_ticket_t));
159 if (new_rsc_ticket == NULL) {
168 new_rsc_ticket->id =
id;
169 new_rsc_ticket->ticket = ticket;
170 new_rsc_ticket->rsc = rsc;
179 "because fencing is not configured", ticket->
id);
185 crm_debug(
"On loss of ticket '%s': Fence the nodes running %s (%s)",
186 new_rsc_ticket->ticket->id, new_rsc_ticket->rsc->id,
190 crm_debug(
"On loss of ticket '%s': Freeze %s (%s)",
191 new_rsc_ticket->ticket->id, new_rsc_ticket->rsc->id,
196 crm_debug(
"On loss of ticket '%s': Demote %s (%s)",
197 new_rsc_ticket->ticket->id, new_rsc_ticket->rsc->id,
202 crm_debug(
"On loss of ticket '%s': Stop %s (%s)",
203 new_rsc_ticket->ticket->id, new_rsc_ticket->rsc->id,
209 crm_debug(
"On loss of ticket '%s': Default to demote %s (%s)",
210 new_rsc_ticket->ticket->id, new_rsc_ticket->rsc->id,
215 crm_debug(
"On loss of ticket '%s': Default to stop %s (%s)",
216 new_rsc_ticket->ticket->id, new_rsc_ticket->rsc->id,
230 if (!(new_rsc_ticket->ticket->granted) || new_rsc_ticket->ticket->standby) {
231 constraints_for_ticket(rsc, new_rsc_ticket);
240 const char *set_id = NULL;
241 const char *role = NULL;
244 CRM_CHECK(ticket != NULL,
return EINVAL);
246 set_id = pcmk__xe_id(
set);
247 if (set_id == NULL) {
262 pcmk__xe_id(xml_rsc));
263 if (resource == NULL) {
265 set_id, pcmk__xe_id(xml_rsc));
269 resource->
id, ticket->
id);
270 rsc_ticket_new(set_id, resource, ticket, role, loss_policy);
279 const char *
id = NULL;
293 if (instance != NULL) {
296 "and will be removed in a future release");
301 id = pcmk__xe_id(xml_obj);
308 if (ticket_str == NULL) {
316 if (ticket == NULL) {
318 "does not exist",
id, ticket_str);
322 if (rsc_id == NULL) {
331 "does not exist",
id, rsc_id);
334 }
else if ((instance != NULL) && !pcmk__is_clone(rsc)) {
336 "is not a clone but instance '%s' was requested",
337 id, rsc_id, instance);
341 if (instance != NULL) {
345 "does not have an instance '%s'",
346 id, rsc_id, instance);
351 rsc_ticket_new(
id, rsc, ticket, state, loss_policy);
356 unpack_rsc_ticket_tags(xmlNode *xml_obj, xmlNode **expanded_xml,
359 const char *
id = NULL;
360 const char *rsc_id = NULL;
361 const char *state = NULL;
366 xmlNode *rsc_set = NULL;
368 *expanded_xml = NULL;
370 CRM_CHECK(xml_obj != NULL,
return EINVAL);
372 id = pcmk__xe_id(xml_obj);
381 if (*expanded_xml != NULL) {
387 if (rsc_id == NULL) {
393 "valid resource or tag",
id, rsc_id);
396 }
else if (rsc != NULL) {
411 *expanded_xml = NULL;
415 if (rsc_set != NULL) {
426 *expanded_xml = NULL;
436 bool any_sets =
false;
438 const char *
id = NULL;
439 const char *ticket_str = NULL;
443 xmlNode *orig_xml = NULL;
444 xmlNode *expanded_xml = NULL;
448 id = pcmk__xe_id(xml_obj);
460 if (ticket_str == NULL) {
467 if (ticket == NULL) {
469 if (ticket == NULL) {
474 if (unpack_rsc_ticket_tags(xml_obj, &expanded_xml,
478 if (expanded_xml != NULL) {
480 xml_obj = expanded_xml;
486 const char *loss_policy = NULL;
493 || (unpack_rsc_ticket_set(
set, ticket, loss_policy,
495 if (expanded_xml != NULL) {
508 unpack_simple_rsc_ticket(xml_obj,
scheduler);
524 for (GList *item = rsc->
rsc_tickets; item != NULL; item = item->next) {
525 rsc_ticket_t *rsc_ticket = (rsc_ticket_t *) item->data;
528 && (!rsc_ticket->ticket->granted || rsc_ticket->ticket->standby)) {
530 "__stateful_without_ticket__", rsc->
cluster);
#define CRM_CHECK(expr, failure_action)
xmlNode * pcmk__xml_copy(xmlNode *parent, xmlNode *src)
pcmk_ticket_t * ticket_new(const char *ticket_id, pcmk_scheduler_t *scheduler)
pcmk_scheduler_t * cluster
const char * pcmk_role_text(enum rsc_role_e role)
Get readable description of a resource role.
G_GNUC_INTERNAL bool pcmk__tag_to_set(xmlNode *xml_obj, xmlNode **rsc_set, const char *attr, bool convert_rsc, const pcmk_scheduler_t *scheduler)
#define pcmk__config_warn(fmt...)
#define pcmk__rsc_trace(rsc, fmt, args...)
#define PCMK_XE_RESOURCE_REF
#define pcmk__config_err(fmt...)
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
void pe_fence_node(pcmk_scheduler_t *scheduler, pcmk_node_t *node, const char *reason, bool priority_delay)
Schedule a fence action for a node.
#define PCMK__XA_RSC_INSTANCE
enum rsc_role_e pcmk_parse_role(const char *role)
Parse a resource role from a string role specification.
GList * ticket_constraints
#define crm_debug(fmt, args...)
G_GNUC_INTERNAL pcmk_resource_t * pcmk__find_constraint_resource(GList *rsc_list, const char *id)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
void resource_location(pcmk_resource_t *rsc, const pcmk_node_t *node, int score, const char *tag, pcmk_scheduler_t *scheduler)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
void pcmk__xe_remove_attr(xmlNode *element, const char *name)
#define pcmk__set_rsc_flags(resource, flags_to_set)
G_GNUC_INTERNAL bool pcmk__valid_resource_or_tag(const pcmk_scheduler_t *scheduler, const char *id, pcmk_resource_t **rsc, pcmk_tag_t **tag)
void free_xml(xmlNode *child)
#define pcmk__warn_once(wo_flag, fmt...)
void pcmk__require_promotion_tickets(pcmk_resource_t *rsc)
Cluster status and scheduling.
GHashTable * pcmk__strkey_table(GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
#define PCMK__ROLE_UNKNOWN
#define PCMK_ROLE_STARTED
pcmk_scheduler_t * scheduler
#define PCMK_XE_RESOURCE_SET
void destroy_ticket(gpointer data)
#define crm_log_xml_trace(xml, text)
Resource role is unknown.
#define PCMK_VALUE_FREEZE
pcmk_resource_t * find_clone_instance(const pcmk_resource_t *rsc, const char *sub_id)
xmlNode * pcmk__xe_next_same(const xmlNode *node)
#define PCMK_XA_LOSS_POLICY
G_GNUC_INTERNAL xmlNode * pcmk__expand_tags_in_sets(xmlNode *xml_obj, const pcmk_scheduler_t *scheduler)
#define pcmk__clear_rsc_flags(resource, flags_to_clear)
#define PCMK_VALUE_DEMOTE
void pcmk__unpack_rsc_ticket(xmlNode *xml_obj, pcmk_scheduler_t *scheduler)
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".