16 typedef struct notify_entry_s {
    35 compare_notify_entries(gconstpointer a, gconstpointer b)
    42     if ((entry_a == NULL) && (entry_b == NULL)) {
    45     if (entry_a == NULL) {
    48     if (entry_b == NULL) {
    53     if ((entry_a->rsc == NULL) && (entry_b->rsc == NULL)) {
    56     if (entry_a->rsc == NULL) {
    59     if (entry_b->rsc == NULL) {
    64     tmp = strcmp(entry_a->rsc->id, entry_b->rsc->id);
    70     if ((entry_a->node == NULL) && (entry_b->node == NULL)) {
    73     if (entry_a->node == NULL) {
    76     if (entry_b->node == NULL) {
    81     return strcmp(entry_a->node->details->id, entry_b->node->details->id);
    99     dup->rsc = entry->rsc;
   100     dup->node = entry->node;
   118 get_node_names(
const GList *list, GString **all_node_names,
   119                GString **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 (
const GList *iter = list; iter != NULL; iter = iter->next) {
   136         if (all_node_names != NULL) {
   137             pcmk__add_word(all_node_names, 1024, node->
details->
uname);
   141         if (host_node_names != NULL) {
   149             pcmk__add_word(host_node_names, 1024, node->
details->
uname);
   153     if ((all_node_names != NULL) && (*all_node_names == NULL)) {
   154         *all_node_names = g_string_new(
" ");
   156     if ((host_node_names != NULL) && (*host_node_names == NULL)) {
   157         *host_node_names = g_string_new(
" ");
   176 notify_entries_to_strings(GList *list, GString **rsc_names,
   177                           GString **node_names)
   179     const char *last_rsc_id = NULL;
   182     if (rsc_names != NULL) {
   185     if (node_names != NULL) {
   190     list = g_list_sort(list, compare_notify_entries);
   192     for (GList *gIter = list; gIter != NULL; gIter = gIter->next) {
   197                        && (entry->rsc->id != NULL));
   198         if ((entry == NULL) || (entry->rsc == NULL)
   199             || (entry->rsc->id == NULL)) {
   205         if ((node_names != NULL) && (entry->node == NULL)) {
   213         last_rsc_id = entry->rsc->id;
   215         if (rsc_names != NULL) {
   216             pcmk__add_word(rsc_names, 1024, entry->rsc->id);
   218         if ((node_names != NULL) && (entry->node->details->uname != NULL)) {
   219             pcmk__add_word(node_names, 1024, entry->node->details->uname);
   224     if ((rsc_names != NULL) && (*rsc_names == NULL)) {
   225         *rsc_names = g_string_new(
" ");
   227     if ((node_names != NULL) && (*node_names == NULL)) {
   228         *node_names = g_string_new(
" ");
   243 copy_meta_to_notify(gpointer key, gpointer value, gpointer user_data)
   250     if (g_hash_table_lookup(notify->
meta, (
const char *) key) != NULL) {
   254     g_hash_table_insert(notify->
meta, strdup((
const char *) key),
   255                         strdup((
const char *) value));
   261     for (
const GSList *item = n_data->
keys; item; item = item->next) {
   281                          const char *notif_action, 
const char *notif_type)
   314     const char *value = NULL;
   315     const char *task = NULL;
   316     const char *skip_reason = NULL;
   318     CRM_CHECK((rsc != NULL) && (node != NULL), 
return NULL);
   322         skip_reason = 
"no action";
   323     } 
else if (notify_done == NULL) {
   324         skip_reason = 
"no parent notification";
   326         skip_reason = 
"node offline";
   328         skip_reason = 
"original action not runnable";
   330     if (skip_reason != NULL) {
   331         pe_rsc_trace(rsc, 
"Skipping notify action for %s on %s: %s",
   332                      rsc->
id, pe__node_name(node), skip_reason);
   336     value = g_hash_table_lookup(op->
meta, 
"notify_type");     
   337     task = g_hash_table_lookup(op->
meta, 
"notify_operation"); 
   339     pe_rsc_trace(rsc, 
"Creating notify action for %s on %s (%s-%s)",
   340                  rsc->
id, pe__node_name(node), value, task);
   349     g_hash_table_foreach(op->
meta, copy_meta_to_notify, notify_action);
   350     add_notify_data_to_action_meta(n_data, notify_action);
   355     return notify_action;
   375     notify = new_notify_action(rsc, node, n_data->
post, n_data->
post_done,
   377     if (notify != NULL) {
   385     for (GList *iter = rsc->
actions; iter != NULL; iter = iter->next) {
   387         const char *interval_ms_s = NULL;
   389         interval_ms_s = g_hash_table_lookup(mon->
meta,
   459                        "notify_operation", n_data->
action);
   466     if (complete != NULL) { 
   469         n_data->
post = new_notify_pseudo_action(rsc, complete, 
RSC_NOTIFY,
   481         n_data->
post_done = new_notify_pseudo_action(rsc, complete,
   492                        "notify_operation", n_data->
action);
   500     if ((
action != NULL) && (complete != NULL)) {
   536 collect_resource_data(
const pe_resource_t *rsc, 
bool activity,
   539     const GList *iter = NULL;
   543     if (n_data == NULL) {
   553         for (iter = rsc->
children; iter != NULL; iter = iter->next) {
   556             collect_resource_data(child, activity, n_data);
   566     entry = new_notify_entry(rsc, node);
   581                                             dup_notify_entry(entry));
   587                                             dup_notify_entry(entry));
   591             crm_err(
"Resource %s role on %s (%s) is not supported for "   592                     "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);
   639 #define add_notify_env(n_data, key, value) do {                         \   640          n_data->keys = pcmk_prepend_nvpair(n_data->keys, key, value);  \   644 #define add_notify_env_gs(n_data, key, value) do {                      \   645          n_data->keys = pcmk_prepend_nvpair(n_data->keys, key,          \   646                                             (const char *) value->str); \   650 #define add_notify_env_free_gs(n_data, key, value) do {                 \   651          n_data->keys = pcmk_prepend_nvpair(n_data->keys, key,          \   652                                             (const char *) value->str); \   653          g_string_free(value, TRUE); value = NULL;                      \   666     bool required = 
false; 
   667     GString *rsc_list = NULL;
   668     GString *node_list = NULL;
   669     GString *metal_list = NULL;
   670     const char *source = NULL;
   673     n_data->
stop = notify_entries_to_strings(n_data->
stop,
   674                                              &rsc_list, &node_list);
   675     if ((strcmp(
" ", (
const char *) rsc_list->str) != 0)
   682     if ((n_data->
start != NULL)
   686     n_data->
start = notify_entries_to_strings(n_data->
start,
   687                                               &rsc_list, &node_list);
   691     if ((n_data->
demote != NULL)
   695     n_data->
demote = notify_entries_to_strings(n_data->
demote,
   696                                                &rsc_list, &node_list);
   705                                                 &rsc_list, &node_list);
   709     n_data->
active = notify_entries_to_strings(n_data->
active,
   710                                                &rsc_list, &node_list);
   715                                                    &rsc_list, &node_list);
   724                                                  &rsc_list, &node_list);
   744     get_node_names(nodes, &node_list, NULL);
   750         get_node_names(rsc->
cluster->
nodes, &node_list, &metal_list);
   757     if (required && (n_data->
pre != NULL)) {
   762     if (required && (n_data->
post != NULL)) {
   782         if (remote_rsc != NULL) {
   807         g_list_foreach(rsc->
children, (GFunc) create_notify_actions, n_data);
   812     for (iter = rsc->
actions; iter != NULL; iter = iter->next) {
   821                     add_notify_data_to_action_meta(n_data, op);
   832             if (n_data->
start == NULL) {
   848             if (n_data->
demote == NULL) {
   869         for (iter = rsc->
running_on; iter != NULL; iter = iter->next) {
   881             new_notify_action(rsc, current_node, n_data->
pre,
   886                 new_post_notify_action(rsc, current_node, n_data);
   897             pe_action_t *remote_start = find_remote_start(start);
   899             if ((remote_start != NULL)
   910             pe_proc_err(
"Next role '%s' but %s is not allocated",
   914         if ((task != 
start_rsc) || (start == NULL)
   934     if ((rsc == NULL) || (n_data == NULL)) {
   937     collect_resource_data(rsc, 
true, n_data);
   938     add_notif_keys(rsc, n_data);
   939     create_notify_actions(rsc, n_data);
   951     if (n_data == NULL) {
   954     g_list_free_full(n_data->
stop, free);
   955     g_list_free_full(n_data->
start, free);
   956     g_list_free_full(n_data->
demote, free);
   957     g_list_free_full(n_data->
promote, free);
   958     g_list_free_full(n_data->
promoted, free);
   960     g_list_free_full(n_data->
active, free);
   961     g_list_free_full(n_data->
inactive, free);
   986     crm_info(
"Ordering notifications for implied %s after fencing", stop->
uuid);
   989     if (n_data != NULL) {
   990         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
gint pe__cmp_node_name(gconstpointer a, gconstpointer b)
#define add_notify_env_free_gs(n_data, key, value)
enum rsc_role_e next_role
pe_action_t * find_first_action(const GList *input, const char *uuid, const char *task, const pe_node_t *on_node)
pe_resource_t * remote_rsc
enum action_tasks text2task(const char *task)
#define CRM_LOG_ASSERT(expr)
#define add_notify_env_gs(n_data, key, value)
#define XML_RSC_ATTR_TARGET
#define pe_proc_err(fmt...)
gboolean remote_requires_reset
void pe__create_action_notifications(pe_resource_t *rsc, notify_data_t *n_data)
const char * role2text(enum rsc_role_e role)
char * pcmk__notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
void pe__free_action_notification_data(notify_data_t *n_data)
pe_resource_t * uber_parent(pe_resource_t *rsc)
bool pe__is_guest_node(const pe_node_t *node)
#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)
notify_data_t * pe__action_notif_pseudo_ops(pe_resource_t *rsc, const char *task, pe_action_t *action, pe_action_t *complete)
void add_hash_param(GHashTable *hash, const char *name, const char *value)
void pe__order_notifs_after_fencing(const pe_action_t *stop, pe_resource_t *rsc, pe_action_t *stonith_op)
#define crm_err(fmt, args...)
#define XML_LRM_ATTR_INTERVAL_MS
enum pe_action_flags flags
pe_working_set_t * cluster
struct notify_entry_s notify_entry_t
#define pe_rsc_trace(rsc, fmt, args...)
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 add_notify_env(n_data, key, value)
GHashTable * allowed_nodes