47 ticket_role_matches(
const pcmk_resource_t *rsc,
const rsc_ticket_t *rsc_ticket)
50 || (rsc_ticket->role == rsc->
role)) {
53 pe_rsc_trace(rsc,
"Skipping constraint: \"%s\" state filter",
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) {
76 pe_rsc_trace(rsc,
"Processing ticket dependencies from %s", rsc->
id);
77 for (iter = rsc->
children; iter != NULL; iter = iter->next) {
83 pe_rsc_trace(rsc,
"%s: Processing ticket dependency on %s (%s, %s)",
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) {
99 "__loss_of_ticket__", rsc->
cluster);
104 if (!ticket_role_matches(rsc, rsc_ticket)) {
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) {
136 }
else if (rsc_ticket->ticket->standby) {
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;
178 "' for ticket '%s' to 'stop' " 179 "because fencing is not configured", ticket->
id);
180 loss_policy =
"stop";
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);
247 if (set_id == NULL) {
262 if (resource == NULL) {
264 set_id,
ID(xml_rsc));
267 pe_rsc_trace(resource,
"Resource '%s' depends on ticket '%s'",
268 resource->
id, ticket->
id);
269 rsc_ticket_new(set_id, resource, ticket, role, loss_policy);
278 const char *
id = NULL;
295 if (instance != NULL) {
298 "deprecated and will be removed in a future release.");
310 if (ticket_str == NULL) {
318 if (ticket == NULL) {
320 "does not exist",
id, ticket_str);
324 if (rsc_id == NULL) {
333 "does not exist",
id, rsc_id);
336 }
else if ((instance != NULL) && !pe_rsc_is_clone(rsc)) {
338 "is not a clone but instance '%s' was requested",
339 id, rsc_id, instance);
343 if (instance != NULL) {
347 "does not have an instance '%s'",
348 "'%s'",
id, rsc_id, instance);
353 rsc_ticket_new(
id, rsc, ticket, state, loss_policy);
358 unpack_rsc_ticket_tags(xmlNode *xml_obj, xmlNode **expanded_xml,
361 const char *
id = NULL;
362 const char *rsc_id = NULL;
363 const char *state = NULL;
368 xmlNode *rsc_set = NULL;
370 *expanded_xml = NULL;
372 CRM_CHECK(xml_obj != NULL,
return EINVAL);
383 if (*expanded_xml != NULL) {
389 if (rsc_id == NULL) {
395 "valid resource or tag",
id, rsc_id);
398 }
else if (rsc != NULL) {
411 *expanded_xml = NULL;
415 if (rsc_set != NULL) {
424 *expanded_xml = NULL;
434 bool any_sets =
false;
436 const char *
id = NULL;
437 const char *ticket_str = NULL;
441 xmlNode *orig_xml = NULL;
442 xmlNode *expanded_xml = NULL;
458 if (ticket_str == NULL) {
465 if (ticket == NULL) {
467 if (ticket == NULL) {
472 if (unpack_rsc_ticket_tags(xml_obj, &expanded_xml,
476 if (expanded_xml != NULL) {
478 xml_obj = expanded_xml;
484 const char *loss_policy = NULL;
491 || (unpack_rsc_ticket_set(
set, ticket, loss_policy,
493 if (expanded_xml != NULL) {
506 unpack_simple_rsc_ticket(xml_obj,
scheduler);
522 for (GList *item = rsc->
rsc_tickets; item != NULL; item = item->next) {
523 rsc_ticket_t *rsc_ticket = (rsc_ticket_t *) item->data;
526 && (!rsc_ticket->ticket->granted || rsc_ticket->ticket->standby)) {
528 "__stateful_without_ticket__", rsc->
cluster);
#define CRM_CHECK(expr, failure_action)
pcmk_ticket_t * ticket_new(const char *ticket_id, pcmk_scheduler_t *scheduler)
pcmk_scheduler_t * cluster
Cluster that resource is part of.
#define PCMK__ROLE_STARTED
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)
enum rsc_role_e role
Resource's current role.
#define pcmk__config_warn(fmt...)
GList * children
Resource's child resources, if any.
xmlNode * first_named_child(const xmlNode *parent, const char *name)
#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.
Implementation of pcmk_scheduler_t.
#define XML_CONS_TAG_RSC_SET
#define pe__set_resource_flags(resource, flags_to_set)
GList * resources
Resources in cluster.
xmlNode * copy_xml(xmlNode *src_node)
const char * role2text(enum rsc_role_e role)
GList * ticket_constraints
#define PCMK_ACTION_DEMOTE
Implementation of pcmk_resource_t.
#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.
void resource_location(pcmk_resource_t *rsc, const pcmk_node_t *node, int score, const char *tag, pcmk_scheduler_t *scheduler)
#define pe_warn_once(pe_wo_bit, fmt...)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
xmlNode * expand_idref(xmlNode *input, xmlNode *top)
Ticket constraint object.
#define XML_COLOC_ATTR_SOURCE_INSTANCE
#define XML_TAG_RESOURCE_REF
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)
Whether resource is blocked from further action.
Implementation of pcmk_node_t.
enum rsc_role_e text2role(const char *role)
#define XML_COLOC_ATTR_SOURCE_ROLE
char * id
XML ID of ticket constraint or state.
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
Whether fencing is enabled (via stonith-enabled property)
pcmk_scheduler_t * scheduler
void xml_remove_prop(xmlNode *obj, const char *name)
Configuration tag object.
#define pe__clear_resource_flags(resource, flags_to_clear)
GList * running_on
Nodes where resource may be active.
void destroy_ticket(gpointer data)
#define crm_log_xml_trace(xml, text)
#define XML_TICKET_ATTR_TICKET
Resource role is unknown.
#define pe_rsc_trace(rsc, fmt, args...)
unsigned long long flags
Group of enum pcmk_scheduler_flags.
pcmk_resource_t * find_clone_instance(const pcmk_resource_t *rsc, const char *sub_id)
Whether resource is managed.
G_GNUC_INTERNAL xmlNode * pcmk__expand_tags_in_sets(xmlNode *xml_obj, const pcmk_scheduler_t *scheduler)
#define XML_COLOC_ATTR_SOURCE
void pcmk__unpack_rsc_ticket(xmlNode *xml_obj, pcmk_scheduler_t *scheduler)
char * id
Resource ID in configuration.
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.
#define XML_TICKET_ATTR_LOSS_POLICY