18 typedef struct notify_entry_s {
37 compare_notify_entries(gconstpointer a, gconstpointer b)
44 if ((entry_a == NULL) && (entry_b == NULL)) {
47 if (entry_a == NULL) {
50 if (entry_b == NULL) {
55 if ((entry_a->rsc == NULL) && (entry_b->rsc == NULL)) {
58 if (entry_a->rsc == NULL) {
61 if (entry_b->rsc == NULL) {
66 tmp = strcmp(entry_a->rsc->id, entry_b->rsc->id);
72 if ((entry_a->node == NULL) && (entry_b->node == NULL)) {
75 if (entry_a->node == NULL) {
78 if (entry_b->node == NULL) {
83 return strcmp(entry_a->node->details->id, entry_b->node->details->id);
101 dup->rsc = entry->rsc;
102 dup->node = entry->node;
120 get_node_names(
const GList *list, GString **all_node_names,
121 GString **host_node_names)
123 if (all_node_names != NULL) {
124 *all_node_names = NULL;
126 if (host_node_names != NULL) {
127 *host_node_names = NULL;
130 for (
const GList *iter = list; iter != NULL; iter = iter->next) {
138 if (all_node_names != NULL) {
139 pcmk__add_word(all_node_names, 1024, node->
details->
uname);
143 if (host_node_names != NULL) {
151 pcmk__add_word(host_node_names, 1024, node->
details->
uname);
155 if ((all_node_names != NULL) && (*all_node_names == NULL)) {
156 *all_node_names = g_string_new(
" ");
158 if ((host_node_names != NULL) && (*host_node_names == NULL)) {
159 *host_node_names = g_string_new(
" ");
178 notify_entries_to_strings(GList *list, GString **rsc_names,
179 GString **node_names)
181 const char *last_rsc_id = NULL;
184 if (rsc_names != NULL) {
187 if (node_names != NULL) {
192 list = g_list_sort(list, compare_notify_entries);
194 for (GList *gIter = list; gIter != NULL; gIter = gIter->next) {
199 && (entry->rsc->id != NULL));
200 if ((entry == NULL) || (entry->rsc == NULL)
201 || (entry->rsc->id == NULL)) {
207 if ((node_names != NULL) && (entry->node == NULL)) {
215 last_rsc_id = entry->rsc->id;
217 if (rsc_names != NULL) {
218 pcmk__add_word(rsc_names, 1024, entry->rsc->id);
220 if ((node_names != NULL) && (entry->node->details->uname != NULL)) {
221 pcmk__add_word(node_names, 1024, entry->node->details->uname);
226 if ((rsc_names != NULL) && (*rsc_names == NULL)) {
227 *rsc_names = g_string_new(
" ");
229 if ((node_names != NULL) && (*node_names == NULL)) {
230 *node_names = g_string_new(
" ");
245 copy_meta_to_notify(gpointer key, gpointer value, gpointer user_data)
252 if (g_hash_table_lookup(notify->
meta, (
const char *) key) != NULL) {
256 g_hash_table_insert(notify->
meta, strdup((
const char *) key),
257 strdup((
const char *) value));
264 for (
const GSList *item = n_data->
keys; item; item = item->next) {
284 const char *notif_action,
const char *notif_type)
318 const char *value = NULL;
319 const char *task = NULL;
320 const char *skip_reason = NULL;
322 CRM_CHECK((rsc != NULL) && (node != NULL),
return NULL);
326 skip_reason =
"no action";
327 }
else if (notify_done == NULL) {
328 skip_reason =
"no parent notification";
330 skip_reason =
"node offline";
332 skip_reason =
"original action not runnable";
334 if (skip_reason != NULL) {
335 pe_rsc_trace(rsc,
"Skipping notify action for %s on %s: %s",
336 rsc->
id, pe__node_name(node), skip_reason);
340 value = g_hash_table_lookup(op->
meta,
"notify_type");
341 task = g_hash_table_lookup(op->
meta,
"notify_operation");
343 pe_rsc_trace(rsc,
"Creating notify action for %s on %s (%s-%s)",
344 rsc->
id, pe__node_name(node), value, task);
353 g_hash_table_foreach(op->
meta, copy_meta_to_notify, notify_action);
354 add_notify_data_to_action_meta(n_data, notify_action);
359 return notify_action;
379 notify = new_notify_action(rsc, node, n_data->
post, n_data->
post_done,
381 if (notify != NULL) {
389 for (GList *iter = rsc->
actions; iter != NULL; iter = iter->next) {
391 const char *interval_ms_s = NULL;
393 interval_ms_s = g_hash_table_lookup(mon->
meta,
465 "notify_operation", n_data->
action);
472 if (complete != NULL) {
475 n_data->
post = new_notify_pseudo_action(rsc, complete,
487 n_data->
post_done = new_notify_pseudo_action(rsc, complete,
498 "notify_operation", n_data->
action);
507 if ((
action != NULL) && (complete != NULL)) {
546 const GList *iter = NULL;
550 if (n_data == NULL) {
560 for (iter = rsc->
children; iter != NULL; iter = iter->next) {
563 collect_resource_data(child, activity, n_data);
573 entry = new_notify_entry(rsc, node);
588 dup_notify_entry(entry));
594 dup_notify_entry(entry));
598 crm_err(
"Resource %s role on %s (%s) is not supported for " 599 "notifications (bug?)",
610 for (iter = rsc->
actions; iter != NULL; iter = iter->next) {
614 && (op->
node != NULL)) {
623 entry = new_notify_entry(rsc, op->
node);
627 n_data->
start = g_list_prepend(n_data->
start, entry);
630 n_data->
stop = g_list_prepend(n_data->
stop, entry);
647 #define add_notify_env(n_data, key, value) do { \ 648 n_data->keys = pcmk_prepend_nvpair(n_data->keys, key, value); \ 652 #define add_notify_env_gs(n_data, key, value) do { \ 653 n_data->keys = pcmk_prepend_nvpair(n_data->keys, key, \ 654 (const char *) value->str); \ 658 #define add_notify_env_free_gs(n_data, key, value) do { \ 659 n_data->keys = pcmk_prepend_nvpair(n_data->keys, key, \ 660 (const char *) value->str); \ 661 g_string_free(value, TRUE); value = NULL; \ 674 bool required =
false;
675 GString *rsc_list = NULL;
676 GString *node_list = NULL;
677 GString *metal_list = NULL;
678 const char *source = NULL;
681 n_data->
stop = notify_entries_to_strings(n_data->
stop,
682 &rsc_list, &node_list);
683 if ((strcmp(
" ", (
const char *) rsc_list->str) != 0)
690 if ((n_data->
start != NULL)
694 n_data->
start = notify_entries_to_strings(n_data->
start,
695 &rsc_list, &node_list);
699 if ((n_data->
demote != NULL)
703 n_data->
demote = notify_entries_to_strings(n_data->
demote,
704 &rsc_list, &node_list);
713 &rsc_list, &node_list);
717 n_data->
active = notify_entries_to_strings(n_data->
active,
718 &rsc_list, &node_list);
723 &rsc_list, &node_list);
732 &rsc_list, &node_list);
752 get_node_names(nodes, &node_list, NULL);
758 get_node_names(rsc->
cluster->
nodes, &node_list, &metal_list);
765 if (required && (n_data->
pre != NULL)) {
770 if (required && (n_data->
post != NULL)) {
790 if (remote_rsc != NULL) {
816 g_list_foreach(rsc->
children, (GFunc) create_notify_actions, n_data);
821 for (iter = rsc->
actions; iter != NULL; iter = iter->next) {
825 && (op->
node != NULL)) {
831 add_notify_data_to_action_meta(n_data, op);
842 if (n_data->
start == NULL) {
858 if (n_data->
demote == NULL) {
879 for (iter = rsc->
running_on; iter != NULL; iter = iter->next) {
892 new_notify_action(rsc, current_node, n_data->
pre,
897 new_post_notify_action(rsc, current_node, n_data);
910 if ((remote_start != NULL)
921 pe_proc_err(
"Next role '%s' but %s is not allocated",
945 if ((rsc == NULL) || (n_data == NULL)) {
948 collect_resource_data(rsc,
true, n_data);
949 add_notif_keys(rsc, n_data);
950 create_notify_actions(rsc, n_data);
962 if (n_data == NULL) {
965 g_list_free_full(n_data->
stop, free);
966 g_list_free_full(n_data->
start, free);
967 g_list_free_full(n_data->
demote, free);
968 g_list_free_full(n_data->
promote, free);
969 g_list_free_full(n_data->
promoted, free);
971 g_list_free_full(n_data->
active, free);
972 g_list_free_full(n_data->
inactive, free);
997 crm_info(
"Ordering notifications for implied %s after fencing", stop->
uuid);
1001 if (n_data != NULL) {
1002 collect_resource_data(rsc,
false, n_data);
#define CRM_CHECK(expr, failure_action)
Whether resource has clone notifications enabled.
pcmk_scheduler_t * cluster
Cluster that resource is part of.
Whether action should not be executed.
#define pe__set_action_flags(action, flags_to_set)
void pcmk_free_nvpairs(GSList *nvpairs)
Free a list of name/value pairs.
pcmk_resource_t * uber_parent(pcmk_resource_t *rsc)
GHashTable * allowed_nodes
enum rsc_role_e role
Resource's current role.
gint pe__cmp_node_name(gconstpointer a, gconstpointer b)
GList * children
Resource's child resources, if any.
#define add_notify_env_free_gs(n_data, key, value)
gboolean order_actions(pcmk_action_t *lh_action, pcmk_action_t *rh_action, uint32_t flags)
enum rsc_role_e next_role
Resource's scheduled next role.
Implementation of pcmk_action_t.
GHashTable * meta
Resource's meta-attributes.
action_tasks
Possible actions (including some pseudo-actions)
enum action_tasks text2task(const char *task)
#define CRM_LOG_ASSERT(expr)
void pe__order_notifs_after_fencing(const pcmk_action_t *stop, pcmk_resource_t *rsc, pcmk_action_t *stonith_op)
#define add_notify_env_gs(n_data, key, value)
pcmk_resource_t * container
Resource containing this one, if any.
#define XML_RSC_ATTR_TARGET
#define pe_proc_err(fmt...)
gboolean remote_requires_reset
GList * nodes
Nodes in cluster.
const char * role2text(enum rsc_role_e role)
#define PCMK_ACTION_DEMOTE
pcmk_node_t * node
Node to execute action on, if any.
void pe__free_action_notification_data(notify_data_t *n_data)
Implementation of pcmk_resource_t.
Actions are ordered (optionally, if no other flags are set)
#define pe__clear_action_flags(action, flags_to_clear)
void pe__create_action_notifications(pcmk_resource_t *rsc, notify_data_t *n_data)
GHashTable * meta
Meta-attributes relevant to action.
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
struct pe_node_shared_s * details
Basic node information.
#define PCMK_ACTION_START
unsigned long long flags
Group of enum pcmk_rsc_flags.
const char * uname
Node name in cluster.
#define PCMK_ACTION_NOTIFIED
pcmk_action_t * post_done
Implementation of pcmk_node_t.
#define PCMK_ACTION_CANCEL
pcmk_action_t * custom_action(pcmk_resource_t *rsc, char *key, const char *task, const pcmk_node_t *on_node, gboolean optional, pcmk_scheduler_t *scheduler)
Create or update an action object.
notify_data_t * pe__action_notif_pseudo_ops(pcmk_resource_t *rsc, const char *task, pcmk_action_t *action, pcmk_action_t *complete)
bool pe__is_guest_node(const pcmk_node_t *node)
char * pcmk__notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
Whether action is runnable.
void add_hash_param(GHashTable *hash, const char *name, const char *value)
pcmk_action_t * find_first_action(const GList *input, const char *uuid, const char *task, const pcmk_node_t *on_node)
#define crm_err(fmt, args...)
Whether action does not require invoking an agent.
#define XML_LRM_ATTR_INTERVAL_MS
pcmk_node_t * allocated_to
Node resource is assigned to.
#define PCMK_ACTION_PROMOTE
GList * running_on
Nodes where resource may be active.
enum pe_action_flags flags
Group of enum pe_action_flags.
struct notify_entry_s notify_entry_t
#define pe_rsc_trace(rsc, fmt, args...)
gboolean unclean
Whether node requires fencing.
#define crm_info(fmt, args...)
#define add_notify_env(n_data, key, value)
gboolean online
Whether online.
pcmk_resource_t * remote_rsc
Remote connection resource for node, if it is a Pacemaker Remote node.
#define PCMK_ACTION_NOTIFY
char * id
Resource ID in configuration.
GHashTable * allowed_nodes
Nodes where resource may run (key is node ID, not name)