18typedef struct notify_entry_s {
37compare_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->
priv->
id, entry_b->node->
priv->
id);
100 dup->rsc = entry->rsc;
101 dup->node = entry->node;
119get_node_names(
const GList *list, GString **all_node_names,
120 GString **host_node_names)
122 if (all_node_names != NULL) {
123 *all_node_names = NULL;
125 if (host_node_names != NULL) {
126 *host_node_names = NULL;
129 for (
const GList *iter = list; iter != NULL; iter = iter->next) {
132 if (node->priv->name == NULL) {
141 if (all_node_names != NULL) {
142 pcmk__add_word(all_node_names, 1024, node->priv->name);
146 if (host_node_names != NULL) {
147 if (pcmk__is_guest_or_bundle_node(node)) {
152 node = pcmk__current_node(launcher);
153 if (node->priv->name == NULL) {
158 pcmk__add_word(host_node_names, 1024, node->priv->name);
162 if ((all_node_names != NULL) && (*all_node_names == NULL)) {
163 *all_node_names = g_string_new(
" ");
165 if ((host_node_names != NULL) && (*host_node_names == NULL)) {
166 *host_node_names = g_string_new(
" ");
185notify_entries_to_strings(GList *list, GString **rsc_names,
186 GString **node_names)
188 const char *last_rsc_id = NULL;
191 if (rsc_names != NULL) {
194 if (node_names != NULL) {
199 list = g_list_sort(list, compare_notify_entries);
201 for (GList *gIter = list; gIter != NULL; gIter = gIter->next) {
206 && (entry->rsc->
id != NULL));
207 if ((entry == NULL) || (entry->rsc == NULL)
208 || (entry->rsc->
id == NULL)) {
214 if ((node_names != NULL) && (entry->node == NULL)) {
222 last_rsc_id = entry->rsc->
id;
224 if (rsc_names != NULL) {
225 pcmk__add_word(rsc_names, 1024, entry->rsc->
id);
227 if ((node_names != NULL) && (entry->node->
priv->
name != NULL)) {
228 pcmk__add_word(node_names, 1024, entry->node->
priv->
name);
233 if ((rsc_names != NULL) && (*rsc_names == NULL)) {
234 *rsc_names = g_string_new(
" ");
236 if ((node_names != NULL) && (*node_names == NULL)) {
237 *node_names = g_string_new(
" ");
252copy_meta_to_notify(gpointer key, gpointer value, gpointer user_data)
259 if (g_hash_table_lookup(notify->
meta, (
const char *) key) != NULL) {
270 for (
const GSList *item = n_data->
keys; item; item = item->next) {
290 const char *notif_action,
const char *notif_type)
324 const char *value = NULL;
325 const char *task = NULL;
326 const char *skip_reason = NULL;
328 CRM_CHECK((rsc != NULL) && (node != NULL),
return NULL);
332 skip_reason =
"no action";
333 }
else if (notify_done == NULL) {
334 skip_reason =
"no parent notification";
336 skip_reason =
"node offline";
338 skip_reason =
"original action not runnable";
340 if (skip_reason != NULL) {
342 rsc->
id, pcmk__node_name(node), skip_reason);
346 value = g_hash_table_lookup(op->
meta,
"notify_type");
347 task = g_hash_table_lookup(op->
meta,
"notify_operation");
350 rsc->
id, pcmk__node_name(node), value, task);
359 g_hash_table_foreach(op->
meta, copy_meta_to_notify, notify_action);
360 add_notify_data_to_action_meta(n_data, notify_action);
365 return notify_action;
385 notify = new_notify_action(rsc, node, n_data->
post, n_data->
post_done,
387 if (notify != NULL) {
395 for (GList *iter = rsc->
priv->
actions; iter != NULL; iter = iter->next) {
397 const char *interval_ms_s = NULL;
475 if (complete != NULL) {
478 n_data->
post = new_notify_pseudo_action(rsc, complete,
490 n_data->
post_done = new_notify_pseudo_action(rsc, complete,
501 "notify_operation", n_data->
action);
517 if ((
action != NULL) && (complete != NULL)) {
555 const GList *iter = NULL;
559 if (n_data == NULL) {
569 for (iter = rsc->
priv->
children; iter != NULL; iter = iter->next) {
572 collect_resource_data(child, activity, n_data);
582 entry = new_notify_entry(rsc, node);
597 dup_notify_entry(entry));
603 dup_notify_entry(entry));
608 "Resource %s role on %s (%s) is not supported for "
609 "notifications (bug?)",
610 rsc->
id, pcmk__node_name(node),
621 for (iter = rsc->
priv->
actions; iter != NULL; iter = iter->next) {
625 && (op->
node != NULL)) {
634 entry = new_notify_entry(rsc, op->
node);
638 n_data->
start = g_list_prepend(n_data->
start, entry);
641 n_data->
stop = g_list_prepend(n_data->
stop, entry);
658#define add_notify_env(n_data, key, value) do { \
659 n_data->keys = pcmk_prepend_nvpair(n_data->keys, key, value); \
663#define add_notify_env_gs(n_data, key, value) do { \
664 n_data->keys = pcmk_prepend_nvpair(n_data->keys, key, \
665 (const char *) value->str); \
669#define add_notify_env_free_gs(n_data, key, value) do { \
670 n_data->keys = pcmk_prepend_nvpair(n_data->keys, key, \
671 (const char *) value->str); \
672 g_string_free(value, TRUE); value = NULL; \
685 bool required =
false;
686 GString *rsc_list = NULL;
687 GString *node_list = NULL;
688 GString *metal_list = NULL;
689 const char *source = NULL;
692 n_data->
stop = notify_entries_to_strings(n_data->
stop,
693 &rsc_list, &node_list);
694 if ((strcmp(
" ", (
const char *) rsc_list->str) != 0)
701 if ((n_data->
start != NULL)
705 n_data->
start = notify_entries_to_strings(n_data->
start,
706 &rsc_list, &node_list);
710 if ((n_data->
demote != NULL)
714 n_data->
demote = notify_entries_to_strings(n_data->
demote,
715 &rsc_list, &node_list);
724 &rsc_list, &node_list);
728 n_data->
active = notify_entries_to_strings(n_data->
active,
729 &rsc_list, &node_list);
734 &rsc_list, &node_list);
743 &rsc_list, &node_list);
763 get_node_names(nodes, &node_list, NULL);
767 source = g_hash_table_lookup(rsc->
priv->
meta,
777 if (required && (n_data->
pre != NULL)) {
782 if (required && (n_data->
post != NULL)) {
802 if (remote_rsc != NULL) {
828 g_list_foreach(rsc->
priv->
children, (GFunc) create_notify_actions,
834 for (iter = rsc->
priv->
actions; iter != NULL; iter = iter->next) {
838 && (op->
node != NULL)) {
844 add_notify_data_to_action_meta(n_data, op);
855 if (n_data->
start == NULL) {
871 if (n_data->
demote == NULL) {
894 iter != NULL; iter = iter->next) {
903 && (current_node->details->unclean
909 new_notify_action(rsc, current_node, n_data->
pre,
914 new_post_notify_action(rsc, current_node, n_data);
928 if ((remote_start != NULL)
940 "Next role '%s' but %s is not allocated",
964 if ((rsc == NULL) || (n_data == NULL)) {
967 collect_resource_data(rsc,
true, n_data);
968 add_notif_keys(rsc, n_data);
969 create_notify_actions(rsc, n_data);
981 if (n_data == NULL) {
984 g_list_free_full(n_data->
stop, free);
985 g_list_free_full(n_data->
start, free);
986 g_list_free_full(n_data->
demote, free);
987 g_list_free_full(n_data->
promote, free);
988 g_list_free_full(n_data->
promoted, free);
990 g_list_free_full(n_data->
active, free);
991 g_list_free_full(n_data->
inactive, free);
1016 crm_info(
"Ordering notifications for implied %s after fencing", stop->
uuid);
1020 if (n_data != NULL) {
1021 collect_resource_data(rsc,
false, n_data);
@ pcmk__ar_first_implies_then
@ pcmk__ar_ordered
Actions are ordered (optionally, if no other flags are set)
#define PCMK_ACTION_CANCEL
#define PCMK_ACTION_PROMOTE
#define PCMK_ACTION_START
#define PCMK_ACTION_NOTIFIED
#define PCMK_ACTION_DEMOTE
#define PCMK_ACTION_NOTIFY
char * pcmk__notify_key(const char *rsc_id, const char *notify_type, const char *op_type)
#define pcmk__set_action_flags(action, flags_to_set)
#define pcmk__clear_action_flags(action, flags_to_clear)
enum pcmk__action_type pcmk__parse_action(const char *action_name)
#define pcmk__assert_alloc(nmemb, size)
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
pcmk_resource_t * uber_parent(pcmk_resource_t *rsc)
#define crm_info(fmt, args...)
#define CRM_LOG_ASSERT(expr)
#define CRM_CHECK(expr, failure_action)
@ pcmk__node_remote_reset
void pcmk_free_nvpairs(GSList *nvpairs)
Free a list of name/value pairs.
#define pcmk__insert_meta(obj, name, value)
#define PCMK_META_INTERVAL
#define PCMK_META_CONTAINER_ATTRIBUTE_TARGET
#define add_notify_env(n_data, key, value)
#define add_notify_env_free_gs(n_data, key, value)
#define add_notify_env_gs(n_data, key, value)
void pe__free_action_notification_data(notify_data_t *n_data)
notify_data_t * pe__action_notif_pseudo_ops(pcmk_resource_t *rsc, const char *task, pcmk_action_t *action, pcmk_action_t *complete)
void pe__order_notifs_after_fencing(const pcmk_action_t *stop, pcmk_resource_t *rsc, pcmk_action_t *stonith_op)
struct notify_entry_s notify_entry_t
void pe__create_action_notifications(pcmk_resource_t *rsc, notify_data_t *n_data)
gboolean order_actions(pcmk_action_t *first, pcmk_action_t *then, uint32_t flags)
gint pe__cmp_node_name(gconstpointer a, gconstpointer b)
pcmk_action_t * find_first_action(const GList *input, const char *uuid, const char *task, const pcmk_node_t *on_node)
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.
#define pcmk__assert(expr)
const char * pcmk_role_text(enum rsc_role_e role)
Get readable description of a resource role.
@ pcmk_role_started
Started.
@ pcmk_role_unpromoted
Unpromoted.
@ pcmk_role_promoted
Promoted.
@ pcmk_role_stopped
Stopped.
#define pcmk__sched_err(scheduler, fmt...)
#define pcmk__rsc_trace(rsc, fmt, args...)
#define PCMK_SCORE_INFINITY
Integer score to use to represent "infinity".
void pcmk__insert_dup(GHashTable *table, const char *name, const char *value)
GHashTable * allowed_nodes
pcmk_action_t * post_done
pcmk_node_t * assigned_node
pcmk_scheduler_t * scheduler
enum rsc_role_e orig_role
pcmk_resource_t * launcher
enum rsc_role_e next_role
GHashTable * allowed_nodes
pcmk__resource_private_t * priv
pcmk__node_private_t * priv
struct pcmk__node_details * details
Wrappers for and extensions to libxml2.