15 typedef struct notify_entry_s {
34 compare_notify_entries(gconstpointer a, gconstpointer b)
41 if ((entry_a == NULL) && (entry_b == NULL)) {
44 if (entry_a == NULL) {
47 if (entry_b == NULL) {
52 if ((entry_a->rsc == NULL) && (entry_b->rsc == NULL)) {
55 if (entry_a->rsc == NULL) {
58 if (entry_b->rsc == NULL) {
63 tmp = strcmp(entry_a->rsc->id, entry_b->rsc->id);
69 if ((entry_a->node == NULL) && (entry_b->node == NULL)) {
72 if (entry_a->node == NULL) {
75 if (entry_b->node == NULL) {
80 return strcmp(entry_a->node->details->id, entry_b->node->details->id);
98 dup->rsc = entry->rsc;
99 dup->node = entry->node;
116 get_node_names(GList *list,
char **all_node_names,
char **host_node_names)
121 if (all_node_names != NULL) {
122 *all_node_names = NULL;
124 if (host_node_names != NULL) {
125 *host_node_names = NULL;
128 for (GList *iter = list; iter != NULL; iter = iter->next) {
136 if (all_node_names != NULL) {
137 pcmk__add_word(all_node_names, &all_len, node->
details->
uname);
141 if (host_node_names != NULL) {
149 pcmk__add_word(host_node_names, &host_len,
154 if ((all_node_names != NULL) && (*all_node_names == NULL)) {
155 *all_node_names = strdup(
" ");
158 if ((host_node_names != NULL) && (*host_node_names == NULL)) {
159 *host_node_names = strdup(
" ");
178 notify_entries_to_strings(GList *list,
char **rsc_names,
char **node_names)
180 const char *last_rsc_id = NULL;
181 size_t rsc_names_len = 0;
182 size_t node_names_len = 0;
185 if (rsc_names != NULL) {
188 if (node_names != NULL) {
193 list = g_list_sort(list, compare_notify_entries);
195 for (GList *gIter = list; gIter != NULL; gIter = gIter->next) {
200 && (entry->rsc->id != NULL));
201 if ((entry == NULL) || (entry->rsc == NULL)
202 || (entry->rsc->id == NULL)) {
208 if ((node_names != NULL) && (entry->node == NULL)) {
216 last_rsc_id = entry->rsc->id;
218 if (rsc_names != NULL) {
219 pcmk__add_word(rsc_names, &rsc_names_len, entry->rsc->id);
221 if ((node_names != NULL) && (entry->node->details->uname != NULL)) {
222 pcmk__add_word(node_names, &node_names_len,
223 entry->node->details->uname);
228 if ((rsc_names != NULL) && (*rsc_names == NULL)) {
229 *rsc_names = strdup(
" ");
232 if ((node_names != NULL) && (*node_names == NULL)) {
233 *node_names = strdup(
" ");
249 copy_meta_to_notify(gpointer key, gpointer value, gpointer user_data)
256 if (g_hash_table_lookup(notify->
meta, (
const char *) key) != NULL) {
260 g_hash_table_insert(notify->
meta, strdup((
const char *) key),
261 strdup((
const char *) value));
267 for (GSList *item = n_data->
keys; item; item = item->next) {
287 const char *notif_action,
const char *notif_type)
320 const char *value = NULL;
321 const char *task = NULL;
322 const char *skip_reason = NULL;
324 CRM_CHECK((rsc != NULL) && (node != NULL),
return NULL);
328 skip_reason =
"no action";
329 }
else if (notify_done == NULL) {
330 skip_reason =
"no parent notification";
332 skip_reason =
"node offline";
334 skip_reason =
"original action not runnable";
336 if (skip_reason != NULL) {
337 pe_rsc_trace(rsc,
"Skipping notify action for %s on %s: %s",
342 value = g_hash_table_lookup(op->
meta,
"notify_type");
343 task = g_hash_table_lookup(op->
meta,
"notify_operation");
345 pe_rsc_trace(rsc,
"Creating notify action for %s on %s (%s-%s)",
355 g_hash_table_foreach(op->
meta, copy_meta_to_notify, notify_action);
356 add_notify_data_to_action_meta(n_data, notify_action);
361 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,
463 "notify_operation", n_data->
action);
470 if (complete != NULL) {
473 n_data->
post = new_notify_pseudo_action(rsc, complete,
RSC_NOTIFY,
485 n_data->
post_done = new_notify_pseudo_action(rsc, complete,
496 "notify_operation", n_data->
action);
504 if ((
action != NULL) && (complete != NULL)) {
552 for (iter = rsc->
children; iter != NULL; iter = iter->next) {
555 collect_resource_data(child, activity, n_data);
565 entry = new_notify_entry(rsc, node);
580 dup_notify_entry(entry));
586 dup_notify_entry(entry));
590 crm_err(
"Resource %s role on %s (%s) is not supported for " 591 "notifications (bug?)",
603 for (iter = rsc->
actions; iter != NULL; iter = iter->next) {
615 entry = new_notify_entry(rsc, op->
node);
619 n_data->
start = g_list_prepend(n_data->
start, entry);
622 n_data->
stop = g_list_prepend(n_data->
stop, entry);
638 #define add_notify_env(n_data, key, value) do { \ 639 n_data->keys = pcmk_prepend_nvpair(n_data->keys, key, value); \ 642 #define add_notify_env_free(n_data, key, value) do { \ 643 n_data->keys = pcmk_prepend_nvpair(n_data->keys, key, value); \ 644 free(value); value = NULL; \ 657 bool required =
false;
658 char *rsc_list = NULL;
659 char *node_list = NULL;
660 char *metal_list = NULL;
661 const char *source = NULL;
664 n_data->
stop = notify_entries_to_strings(n_data->
stop,
665 &rsc_list, &node_list);
673 if ((n_data->
start != NULL)
677 n_data->
start = notify_entries_to_strings(n_data->
start,
678 &rsc_list, &node_list);
682 if ((n_data->
demote != NULL)
686 n_data->
demote = notify_entries_to_strings(n_data->
demote,
687 &rsc_list, &node_list);
696 &rsc_list, &node_list);
700 n_data->
active = notify_entries_to_strings(n_data->
active,
701 &rsc_list, &node_list);
706 &rsc_list, &node_list);
715 &rsc_list, &node_list);
735 get_node_names(nodes, &node_list, NULL);
741 get_node_names(rsc->
cluster->
nodes, &node_list, &metal_list);
748 if (required && (n_data->
pre != NULL)) {
753 if (required && (n_data->
post != NULL)) {
773 if (remote_rsc != NULL) {
798 g_list_foreach(rsc->
children, (GFunc) create_notify_actions, n_data);
803 for (iter = rsc->
actions; iter != NULL; iter = iter->next) {
812 add_notify_data_to_action_meta(n_data, op);
823 if (n_data->
start == NULL) {
839 if (n_data->
demote == NULL) {
860 for (iter = rsc->
running_on; iter != NULL; iter = iter->next) {
872 new_notify_action(rsc, current_node, n_data->
pre,
877 new_post_notify_action(rsc, current_node, n_data);
888 pe_action_t *remote_start = find_remote_start(start);
890 if ((remote_start != NULL)
901 pe_proc_err(
"Next role '%s' but %s is not allocated",
905 if ((task !=
start_rsc) || (start == NULL)
925 if ((rsc == NULL) || (n_data == NULL)) {
928 collect_resource_data(rsc,
true, n_data);
929 add_notif_keys(rsc, n_data);
930 create_notify_actions(rsc, n_data);
942 if (n_data == NULL) {
945 g_list_free_full(n_data->
stop, free);
946 g_list_free_full(n_data->
start, free);
947 g_list_free_full(n_data->
demote, free);
948 g_list_free_full(n_data->
promote, free);
949 g_list_free_full(n_data->
promoted, free);
951 g_list_free_full(n_data->
active, free);
952 g_list_free_full(n_data->
inactive, free);
977 crm_info(
"Ordering notifications for implied %s after fencing", stop->
uuid);
979 collect_resource_data(rsc,
false, n_data);
#define CRM_CHECK(expr, failure_action)
#define pe__set_action_flags(action, flags_to_set)
void pcmk_free_nvpairs(GSList *nvpairs)
Free a list of name/value pairs.
GHashTable * allowed_nodes
pe_resource_t * container
notify_data_t * pcmk__clone_notif_pseudo_ops(pe_resource_t *rsc, const char *task, pe_action_t *action, pe_action_t *complete)
enum rsc_role_e next_role
void pcmk__free_notification_data(notify_data_t *n_data)
pe_resource_t * remote_rsc
void pcmk__order_notifs_after_fencing(pe_action_t *stop, pe_resource_t *rsc, pe_action_t *stonith_op)
enum action_tasks text2task(const char *task)
#define CRM_LOG_ASSERT(expr)
#define XML_RSC_ATTR_TARGET
#define pe_proc_err(fmt...)
gboolean remote_requires_reset
const char * role2text(enum rsc_role_e role)
char * pcmk__notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
pe_resource_t * uber_parent(pe_resource_t *rsc)
bool pe__is_guest_node(const pe_node_t *node)
#define add_notify_env_free(n_data, key, value)
void pcmk__create_notifications(pe_resource_t *rsc, notify_data_t *n_data)
#define pe__clear_action_flags(action, flags_to_clear)
#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)
struct notify_entry_s notify_entry_t
void add_hash_param(GHashTable *hash, const char *name, const char *value)
#define crm_err(fmt, args...)
#define add_notify_env(n_data, key, value)
#define XML_LRM_ATTR_INTERVAL_MS
enum pe_action_flags flags
pe_working_set_t * cluster
#define pe_rsc_trace(rsc, fmt, args...)
gint sort_node_uname(gconstpointer a, gconstpointer b)
#define crm_info(fmt, args...)
pe_action_t * find_first_action(GList *input, const char *uuid, const char *task, pe_node_t *on_node)
GHashTable * allowed_nodes
pe_action_t * custom_action(pe_resource_t *rsc, char *key, const char *task, pe_node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Create or update an action object.