40 xe_interval(
const xmlNode *xml)
60 const char *
id = NULL;
68 || (xe_interval(op) != interval_ms)) {
80 "same name and interval combination more " 81 "than once per resource)",
ID(op),
id);
105 op_cannot_recur(
const char *
name)
123 is_recurring_history(
const pe_resource_t *rsc,
const xmlNode *xml,
124 struct op_history *op)
126 const char *role = NULL;
128 op->interval_ms = xe_interval(xml);
129 if (op->interval_ms == 0) {
134 if (pcmk__str_empty(op->id)) {
140 if (op_cannot_recur(op->name)) {
142 op->id, pcmk__s(op->name,
"unnamed"));
147 if (is_op_dup(rsc, op->name, op->interval_ms)) {
166 crm_trace(
"Not creating recurring action %s for disabled resource %s",
187 active_recurring_should_be_optional(
const pe_resource_t *rsc,
191 GList *possible_matches = NULL;
194 pe_rsc_trace(rsc,
"%s will be mandatory because resource is unmanaged",
207 if (possible_matches == NULL) {
208 pe_rsc_trace(rsc,
"%s will be mandatory because it is not active on %s",
209 key, pe__node_name(node));
213 for (GList *iter = possible_matches; iter != NULL; iter = iter->next) {
218 "%s will be mandatory because " 219 "it needs to be rescheduled", key);
220 g_list_free(possible_matches);
225 g_list_free(possible_matches);
240 const pe_node_t *node,
const struct op_history *op)
243 bool is_optional =
true;
250 is_optional = active_recurring_should_be_optional(rsc, node, op->key,
259 char *after_key = NULL;
289 "%s recurring action %s because %s configured for %s role " 291 (is_optional?
"Cancelling" :
"Ignoring"), op->key, op->id,
298 "Creating %s recurring action %s for %s (%s %s on %s)",
299 (is_optional?
"optional" :
"mandatory"), op->key,
301 pe__node_name(node));
303 mon =
custom_action(rsc, strdup(op->key), op->name, node, is_optional, TRUE,
312 pe_rsc_trace(rsc,
"%s is unrunnable because no node is available",
317 pe_rsc_info(rsc,
"Start %s-interval %s for %s on %s",
319 rsc->
id, pe__node_name(node));
329 NULL, strdup(mon->
uuid), mon,
334 NULL, strdup(mon->
uuid), mon,
365 const char *
name, guint interval_ms)
370 if (possible_matches == NULL) {
373 g_list_free(possible_matches);
393 "Cancelling %s-interval %s action for %s on %s because " 413 for (GList *iter = probes; iter != NULL; iter = iter->next) {
434 for (GList *iter = stop_ops; iter != NULL; iter = iter->next) {
441 action->uuid, pe__node_name(node));
446 crm_debug(
"%s unrunnable on %s: stop is unrunnable",
447 action->uuid, pe__node_name(node));
458 g_list_free(stop_ops);
471 const struct op_history *op)
473 GList *possible_matches = NULL;
482 " role are not supported for anonymous clones)", op->id);
486 pe_rsc_trace(rsc,
"Creating recurring action %s for %s on nodes " 487 "where it should not be running", op->id, rsc->
id);
489 for (GList *iter = rsc->
cluster->
nodes; iter != NULL; iter = iter->next) {
492 bool is_optional =
true;
499 cancel_if_running(rsc, node, op->key, op->name, op->interval_ms);
505 is_optional = (possible_matches != NULL);
506 g_list_free(possible_matches);
509 "Creating %s recurring action %s for %s (%s " 511 (is_optional?
"optional" :
"mandatory"),
512 op->key, op->id, rsc->
id, pe__node_name(stop_node));
514 stopped_mon =
custom_action(rsc, strdup(op->key), op->name, stop_node,
515 is_optional, TRUE, rsc->
cluster);
520 order_after_probes(rsc, stop_node, stopped_mon);
526 order_after_stops(rsc, stop_node, stopped_mon);
529 pe_rsc_debug(rsc,
"%s unrunnable on %s: node unavailable)",
530 stopped_mon->uuid, pe__node_name(stop_node));
536 crm_notice(
"Start recurring %s-interval %s for " 539 stopped_mon->task, rsc->
id, pe__node_name(stop_node));
556 pe_rsc_trace(rsc,
"Skipping recurring actions for blocked resource %s",
563 "in maintenance mode", rsc->
id);
572 "Skipping recurring actions for %s on %s " 573 "in maintenance mode",
582 pe_rsc_trace(rsc,
"Creating any recurring actions needed for %s", rsc->
id);
587 struct op_history op_history = { NULL, };
589 if (!is_recurring_history(rsc, op, &op_history)) {
594 recurring_op_for_active(rsc, start, rsc->
allocated_to, &op_history);
596 recurring_op_for_inactive(rsc, rsc->
allocated_to, &op_history);
598 free(op_history.key);
619 char *interval_ms_s = NULL;
621 CRM_ASSERT((rsc != NULL) && (task != NULL) && (node != NULL));
653 guint interval_ms,
const pe_node_t *node,
658 CRM_CHECK((rsc != NULL) && (task != NULL)
659 && (node != NULL) && (reason != NULL),
662 crm_info(
"Recurring %s-interval %s for %s will be stopped on %s: %s",
664 pe__node_name(node), reason);
691 task, node, TRUE, TRUE, rsc->
cluster);
706 guint interval_ms = 0;
713 return (interval_ms > 0);
#define CRM_CHECK(expr, failure_action)
xmlNode * find_rsc_op_entry(const pe_resource_t *rsc, const char *key)
pe_action_t * pcmk__new_cancel_action(pe_resource_t *rsc, const char *task, guint interval_ms, const pe_node_t *node)
#define crm_notice(fmt, args...)
#define CRMD_ACTION_MIGRATED
#define pe_rsc_debug(rsc, fmt, args...)
#define pe__set_action_flags(action, flags_to_set)
resource_alloc_functions_t * cmds
xmlNode * first_named_child(const xmlNode *parent, const char *name)
Service active and promoted.
enum rsc_role_e next_role
#define pcmk__config_err(fmt...)
#define XML_LRM_ATTR_INTERVAL
void pcmk__schedule_cancel(pe_resource_t *rsc, const char *call_id, const char *task, guint interval_ms, const pe_node_t *node, const char *reason)
enum pe_action_flags(* action_flags)(pe_action_t *action, const pe_node_t *node)
void trigger_unfencing(pe_resource_t *rsc, pe_node_t *node, const char *reason, pe_action_t *dependency, pe_working_set_t *data_set)
void pcmk__reschedule_recurring(pe_resource_t *rsc, const char *task, guint interval_ms, pe_node_t *node)
#define XML_LRM_ATTR_TASK
const char * role2text(enum rsc_role_e role)
#define CRMD_ACTION_RELOAD_AGENT
int pcmk__guint_from_hash(GHashTable *table, const char *key, guint default_val, guint *result)
#define crm_debug(fmt, args...)
bool pcmk__action_is_recurring(const pe_action_t *action)
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
void pe__add_action_expected_result(pe_action_t *action, int expected_result)
#define pe__clear_action_flags(action, flags_to_clear)
#define crm_trace(fmt, args...)
#define do_crm_log(level, fmt, args...)
Log a message.
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
struct pe_node_shared_s * details
gboolean order_actions(pe_action_t *lh_action, pe_action_t *rh_action, enum pe_ordering order)
void pcmk__str_update(char **str, const char *value)
G_GNUC_INTERNAL void pcmk__new_ordering(pe_resource_t *first_rsc, char *first_task, pe_action_t *first_action, pe_resource_t *then_rsc, char *then_task, pe_action_t *then_action, uint32_t flags, pe_working_set_t *data_set)
enum rsc_role_e text2role(const char *role)
bool pcmk__str_any_of(const char *s,...) G_GNUC_NULL_TERMINATED
char * pcmk__op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key (RESOURCE_ACTION_INTERVAL)
void pcmk__create_recurring_actions(pe_resource_t *rsc)
void add_hash_param(GHashTable *hash, const char *name, const char *value)
#define start_action(rsc, node, optional)
char guint crm_parse_interval_spec(const char *input)
Parse milliseconds from a Pacemaker interval specification.
#define XML_LRM_ATTR_INTERVAL_MS
#define XML_LRM_ATTR_CALLID
#define CRMD_ACTION_MIGRATE
#define RSC_ROLE_STOPPED_S
rsc_role_e
Possible roles that a resource can be in.
enum pe_action_flags flags
#define pe_rsc_maintenance
pe_working_set_t * cluster
const char * pcmk__readable_interval(guint interval_ms)
GList * find_actions_exact(GList *input, const char *key, const pe_node_t *on_node)
#define pe_rsc_trace(rsc, fmt, args...)
GList * pe__resource_actions(const pe_resource_t *rsc, const pe_node_t *node, const char *task, bool require_node)
Find all actions of given type for a resource.
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, const pe_node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Create or update an action object.
#define crm_info(fmt, args...)
#define pe_rsc_info(rsc, fmt, args...)
xmlNode * crm_next_same_xml(const xmlNode *sibling)
Get next instance of same XML tag.