This source file includes following definitions.
- compare_notify_entries
- dup_notify_entry
- get_node_names
- notify_entries_to_strings
- copy_meta_to_notify
- add_notify_data_to_action_meta
- new_notify_pseudo_action
- new_notify_action
- new_post_notify_action
- pe__clone_notif_pseudo_ops
- new_notify_entry
- collect_resource_data
- add_notif_keys
- find_remote_start
- create_notify_actions
- pe__create_notifications
- pe__free_notification_data
- pe__order_notifs_after_fencing
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11 #include <crm/msg_xml.h>
12 #include <pacemaker-internal.h>
13
14 typedef struct notify_entry_s {
15 pe_resource_t *rsc;
16 pe_node_t *node;
17 } notify_entry_t;
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 static gint
33 compare_notify_entries(gconstpointer a, gconstpointer b)
34 {
35 int tmp;
36 const notify_entry_t *entry_a = a;
37 const notify_entry_t *entry_b = b;
38
39
40 if ((entry_a == NULL) && (entry_b == NULL)) {
41 return 0;
42 }
43 if (entry_a == NULL) {
44 return 1;
45 }
46 if (entry_b == NULL) {
47 return -1;
48 }
49
50
51 if ((entry_a->rsc == NULL) && (entry_b->rsc == NULL)) {
52 return 0;
53 }
54 if (entry_a->rsc == NULL) {
55 return 1;
56 }
57 if (entry_b->rsc == NULL) {
58 return -1;
59 }
60
61
62 tmp = strcmp(entry_a->rsc->id, entry_b->rsc->id);
63 if (tmp != 0) {
64 return tmp;
65 }
66
67
68 if ((entry_a->node == NULL) && (entry_b->node == NULL)) {
69 return 0;
70 }
71 if (entry_a->node == NULL) {
72 return 1;
73 }
74 if (entry_b->node == NULL) {
75 return -1;
76 }
77
78
79 return strcmp(entry_a->node->details->id, entry_b->node->details->id);
80 }
81
82
83
84
85
86
87
88
89
90
91 static notify_entry_t *
92 dup_notify_entry(notify_entry_t *entry)
93 {
94 notify_entry_t *dup = calloc(1, sizeof(notify_entry_t));
95
96 CRM_ASSERT(dup != NULL);
97 dup->rsc = entry->rsc;
98 dup->node = entry->node;
99 return dup;
100 }
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 static void
116 get_node_names(GList *list, GString **all_node_names, GString **host_node_names)
117 {
118 if (all_node_names != NULL) {
119 *all_node_names = NULL;
120 }
121 if (host_node_names != NULL) {
122 *host_node_names = NULL;
123 }
124
125 for (GList *iter = list; iter != NULL; iter = iter->next) {
126 pe_node_t *node = (pe_node_t *) iter->data;
127
128 if (node->details->uname == NULL) {
129 continue;
130 }
131
132
133 if (all_node_names != NULL) {
134 pcmk__add_word(all_node_names, 1024, node->details->uname);
135 }
136
137
138 if (host_node_names != NULL) {
139 if (pe__is_guest_node(node)
140 && (node->details->remote_rsc->container->running_on != NULL)) {
141 node = pe__current_node(node->details->remote_rsc->container);
142 if (node->details->uname == NULL) {
143 continue;
144 }
145 }
146 pcmk__add_word(host_node_names, 1024, node->details->uname);
147 }
148 }
149
150 if ((all_node_names != NULL) && (*all_node_names == NULL)) {
151 *all_node_names = g_string_new(" ");
152 }
153 if ((host_node_names != NULL) && (*host_node_names == NULL)) {
154 *host_node_names = g_string_new(" ");
155 }
156 }
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172 static GList *
173 notify_entries_to_strings(GList *list, GString **rsc_names,
174 GString **node_names)
175 {
176 const char *last_rsc_id = NULL;
177
178
179 if (rsc_names != NULL) {
180 *rsc_names = NULL;
181 }
182 if (node_names != NULL) {
183 *node_names = NULL;
184 }
185
186
187 list = g_list_sort(list, compare_notify_entries);
188
189 for (GList *gIter = list; gIter != NULL; gIter = gIter->next) {
190 notify_entry_t *entry = (notify_entry_t *) gIter->data;
191
192
193 CRM_LOG_ASSERT((entry != NULL) && (entry->rsc != NULL)
194 && (entry->rsc->id != NULL));
195 if ((entry == NULL) || (entry->rsc == NULL)
196 || (entry->rsc->id == NULL)) {
197 continue;
198 }
199
200
201 CRM_LOG_ASSERT((node_names == NULL) || (entry->node != NULL));
202 if ((node_names != NULL) && (entry->node == NULL)) {
203 continue;
204 }
205
206
207 if (pcmk__str_eq(entry->rsc->id, last_rsc_id, pcmk__str_none)) {
208 continue;
209 }
210 last_rsc_id = entry->rsc->id;
211
212 if (rsc_names != NULL) {
213 pcmk__add_word(rsc_names, 1024, entry->rsc->id);
214 }
215 if ((node_names != NULL) && (entry->node->details->uname != NULL)) {
216 pcmk__add_word(node_names, 1024, entry->node->details->uname);
217 }
218 }
219
220
221 if ((rsc_names != NULL) && (*rsc_names == NULL)) {
222 *rsc_names = g_string_new(" ");
223 }
224 if ((node_names != NULL) && (*node_names == NULL)) {
225 *node_names = g_string_new(" ");
226 }
227
228 return list;
229 }
230
231
232
233
234
235
236
237
238
239 static void
240 copy_meta_to_notify(gpointer key, gpointer value, gpointer user_data)
241 {
242 pe_action_t *notify = (pe_action_t *) user_data;
243
244
245
246
247 if (g_hash_table_lookup(notify->meta, (const char *) key) != NULL) {
248 return;
249 }
250
251 g_hash_table_insert(notify->meta, strdup((const char *) key),
252 strdup((const char *) value));
253 }
254
255 static void
256 add_notify_data_to_action_meta(notify_data_t *n_data, pe_action_t *action)
257 {
258 for (GSList *item = n_data->keys; item; item = item->next) {
259 pcmk_nvpair_t *nvpair = item->data;
260
261 add_hash_param(action->meta, nvpair->name, nvpair->value);
262 }
263 }
264
265
266
267
268
269
270
271
272
273
274
275
276 static pe_action_t *
277 new_notify_pseudo_action(pe_resource_t *rsc, const pe_action_t *action,
278 const char *notif_action, const char *notif_type)
279 {
280 pe_action_t *notify = NULL;
281
282 notify = custom_action(rsc,
283 pcmk__notify_key(rsc->id, notif_type, action->task),
284 notif_action, NULL,
285 pcmk_is_set(action->flags, pe_action_optional),
286 TRUE, rsc->cluster);
287 pe__set_action_flags(notify, pe_action_pseudo);
288 add_hash_param(notify->meta, "notify_key_type", notif_type);
289 add_hash_param(notify->meta, "notify_key_operation", action->task);
290 return notify;
291 }
292
293
294
295
296
297
298
299
300
301
302
303
304
305 static pe_action_t *
306 new_notify_action(pe_resource_t *rsc, pe_node_t *node, pe_action_t *op,
307 pe_action_t *notify_done, notify_data_t *n_data)
308 {
309 char *key = NULL;
310 pe_action_t *notify_action = NULL;
311 const char *value = NULL;
312 const char *task = NULL;
313 const char *skip_reason = NULL;
314
315 CRM_CHECK((rsc != NULL) && (node != NULL), return NULL);
316
317
318 if (op == NULL) {
319 skip_reason = "no action";
320 } else if (notify_done == NULL) {
321 skip_reason = "no parent notification";
322 } else if (!node->details->online) {
323 skip_reason = "node offline";
324 } else if (!pcmk_is_set(op->flags, pe_action_runnable)) {
325 skip_reason = "original action not runnable";
326 }
327 if (skip_reason != NULL) {
328 pe_rsc_trace(rsc, "Skipping notify action for %s on %s: %s",
329 rsc->id, pe__node_name(node), skip_reason);
330 return NULL;
331 }
332
333 value = g_hash_table_lookup(op->meta, "notify_type");
334 task = g_hash_table_lookup(op->meta, "notify_operation");
335
336 pe_rsc_trace(rsc, "Creating notify action for %s on %s (%s-%s)",
337 rsc->id, pe__node_name(node), value, task);
338
339
340 key = pcmk__notify_key(rsc->id, value, task);
341 notify_action = custom_action(rsc, key, op->task, node,
342 pcmk_is_set(op->flags, pe_action_optional),
343 TRUE, rsc->cluster);
344
345
346 g_hash_table_foreach(op->meta, copy_meta_to_notify, notify_action);
347 add_notify_data_to_action_meta(n_data, notify_action);
348
349
350 order_actions(op, notify_action, pe_order_optional);
351 order_actions(notify_action, notify_done, pe_order_optional);
352 return notify_action;
353 }
354
355
356
357
358
359
360
361
362
363 static void
364 new_post_notify_action(pe_resource_t *rsc, pe_node_t *node,
365 notify_data_t *n_data)
366 {
367 pe_action_t *notify = NULL;
368
369 CRM_ASSERT(n_data != NULL);
370
371
372 notify = new_notify_action(rsc, node, n_data->post, n_data->post_done,
373 n_data);
374 if (notify != NULL) {
375 notify->priority = INFINITY;
376 }
377
378
379 if (n_data->post_done == NULL) {
380 return;
381 }
382 for (GList *iter = rsc->actions; iter != NULL; iter = iter->next) {
383 pe_action_t *mon = (pe_action_t *) iter->data;
384 const char *interval_ms_s = NULL;
385
386 interval_ms_s = g_hash_table_lookup(mon->meta,
387 XML_LRM_ATTR_INTERVAL_MS);
388 if (pcmk__str_eq(interval_ms_s, "0", pcmk__str_null_matches)
389 || pcmk__str_eq(mon->task, RSC_CANCEL, pcmk__str_none)) {
390 continue;
391 }
392 order_actions(n_data->post_done, mon, pe_order_optional);
393 }
394 }
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427 notify_data_t *
428 pe__clone_notif_pseudo_ops(pe_resource_t *rsc, const char *task,
429 pe_action_t *action, pe_action_t *complete)
430 {
431 notify_data_t *n_data = NULL;
432
433 if (!pcmk_is_set(rsc->flags, pe_rsc_notify)) {
434 return NULL;
435 }
436
437 n_data = calloc(1, sizeof(notify_data_t));
438 CRM_ASSERT(n_data != NULL);
439
440 n_data->action = task;
441
442 if (action != NULL) {
443
444
445 n_data->pre = new_notify_pseudo_action(rsc, action, RSC_NOTIFY, "pre");
446 pe__set_action_flags(n_data->pre, pe_action_runnable);
447 add_hash_param(n_data->pre->meta, "notify_type", "pre");
448 add_hash_param(n_data->pre->meta, "notify_operation", n_data->action);
449
450
451 n_data->pre_done = new_notify_pseudo_action(rsc, action, RSC_NOTIFIED,
452 "confirmed-pre");
453 pe__set_action_flags(n_data->pre_done, pe_action_runnable);
454 add_hash_param(n_data->pre_done->meta, "notify_type", "pre");
455 add_hash_param(n_data->pre_done->meta,
456 "notify_operation", n_data->action);
457
458
459 order_actions(n_data->pre, n_data->pre_done, pe_order_optional);
460 order_actions(n_data->pre_done, action, pe_order_optional);
461 }
462
463 if (complete != NULL) {
464
465
466 n_data->post = new_notify_pseudo_action(rsc, complete, RSC_NOTIFY,
467 "post");
468 n_data->post->priority = INFINITY;
469 if (pcmk_is_set(complete->flags, pe_action_runnable)) {
470 pe__set_action_flags(n_data->post, pe_action_runnable);
471 } else {
472 pe__clear_action_flags(n_data->post, pe_action_runnable);
473 }
474 add_hash_param(n_data->post->meta, "notify_type", "post");
475 add_hash_param(n_data->post->meta, "notify_operation", n_data->action);
476
477
478 n_data->post_done = new_notify_pseudo_action(rsc, complete,
479 RSC_NOTIFIED,
480 "confirmed-post");
481 n_data->post_done->priority = INFINITY;
482 if (pcmk_is_set(complete->flags, pe_action_runnable)) {
483 pe__set_action_flags(n_data->post_done, pe_action_runnable);
484 } else {
485 pe__clear_action_flags(n_data->post_done, pe_action_runnable);
486 }
487 add_hash_param(n_data->post_done->meta, "notify_type", "post");
488 add_hash_param(n_data->post_done->meta,
489 "notify_operation", n_data->action);
490
491
492 order_actions(complete, n_data->post, pe_order_implies_then);
493 order_actions(n_data->post, n_data->post_done, pe_order_implies_then);
494 }
495
496
497 if ((action != NULL) && (complete != NULL)) {
498 order_actions(n_data->pre_done, n_data->post, pe_order_optional);
499 }
500 return n_data;
501 }
502
503
504
505
506
507
508
509
510
511
512
513 static notify_entry_t *
514 new_notify_entry(pe_resource_t *rsc, pe_node_t *node)
515 {
516 notify_entry_t *entry = calloc(1, sizeof(notify_entry_t));
517
518 CRM_ASSERT(entry != NULL);
519 entry->rsc = rsc;
520 entry->node = node;
521 return entry;
522 }
523
524
525
526
527
528
529
530
531
532 static void
533 collect_resource_data(pe_resource_t *rsc, bool activity, notify_data_t *n_data)
534 {
535 GList *iter = NULL;
536 notify_entry_t *entry = NULL;
537 pe_node_t *node = NULL;
538
539 if (n_data == NULL) {
540 return;
541 }
542
543 if (n_data->allowed_nodes == NULL) {
544 n_data->allowed_nodes = rsc->allowed_nodes;
545 }
546
547
548 if (rsc->children != NULL) {
549 for (iter = rsc->children; iter != NULL; iter = iter->next) {
550 pe_resource_t *child = (pe_resource_t *) iter->data;
551
552 collect_resource_data(child, activity, n_data);
553 }
554 return;
555 }
556
557
558
559 if (rsc->running_on != NULL) {
560 node = rsc->running_on->data;
561 }
562 entry = new_notify_entry(rsc, node);
563
564
565 switch (rsc->role) {
566 case RSC_ROLE_STOPPED:
567 n_data->inactive = g_list_prepend(n_data->inactive, entry);
568 break;
569
570 case RSC_ROLE_STARTED:
571 n_data->active = g_list_prepend(n_data->active, entry);
572 break;
573
574 case RSC_ROLE_UNPROMOTED:
575 n_data->unpromoted = g_list_prepend(n_data->unpromoted, entry);
576 n_data->active = g_list_prepend(n_data->active,
577 dup_notify_entry(entry));
578 break;
579
580 case RSC_ROLE_PROMOTED:
581 n_data->promoted = g_list_prepend(n_data->promoted, entry);
582 n_data->active = g_list_prepend(n_data->active,
583 dup_notify_entry(entry));
584 break;
585
586 default:
587 crm_err("Resource %s role on %s (%s) is not supported for "
588 "notifications (bug?)",
589 rsc->id, pe__node_name(node), role2text(rsc->role));
590 free(entry);
591 break;
592 }
593
594 if (!activity) {
595 return;
596 }
597
598
599 for (iter = rsc->actions; iter != NULL; iter = iter->next) {
600 pe_action_t *op = (pe_action_t *) iter->data;
601
602 if (!pcmk_is_set(op->flags, pe_action_optional) && (op->node != NULL)) {
603 enum action_tasks task = text2task(op->task);
604
605 if ((task == stop_rsc) && op->node->details->unclean) {
606
607 } else if (!pcmk_is_set(op->flags, pe_action_runnable)) {
608 continue;
609 }
610
611 entry = new_notify_entry(rsc, op->node);
612
613 switch (task) {
614 case start_rsc:
615 n_data->start = g_list_prepend(n_data->start, entry);
616 break;
617 case stop_rsc:
618 n_data->stop = g_list_prepend(n_data->stop, entry);
619 break;
620 case action_promote:
621 n_data->promote = g_list_prepend(n_data->promote, entry);
622 break;
623 case action_demote:
624 n_data->demote = g_list_prepend(n_data->demote, entry);
625 break;
626 default:
627 free(entry);
628 break;
629 }
630 }
631 }
632 }
633
634
635 #define add_notify_env(n_data, key, value) do { \
636 n_data->keys = pcmk_prepend_nvpair(n_data->keys, key, value); \
637 } while (0)
638
639
640 #define add_notify_env_gs(n_data, key, value) do { \
641 n_data->keys = pcmk_prepend_nvpair(n_data->keys, key, \
642 (const char *) value->str); \
643 } while (0)
644
645
646 #define add_notify_env_free_gs(n_data, key, value) do { \
647 n_data->keys = pcmk_prepend_nvpair(n_data->keys, key, \
648 (const char *) value->str); \
649 g_string_free(value, TRUE); value = NULL; \
650 } while (0)
651
652
653
654
655
656
657
658
659 static void
660 add_notif_keys(pe_resource_t *rsc, notify_data_t *n_data)
661 {
662 bool required = false;
663 GString *rsc_list = NULL;
664 GString *node_list = NULL;
665 GString *metal_list = NULL;
666 const char *source = NULL;
667 GList *nodes = NULL;
668
669 n_data->stop = notify_entries_to_strings(n_data->stop,
670 &rsc_list, &node_list);
671 if ((strcmp(" ", (const char *) rsc_list->str) != 0)
672 && pcmk__str_eq(n_data->action, RSC_STOP, pcmk__str_none)) {
673 required = true;
674 }
675 add_notify_env_free_gs(n_data, "notify_stop_resource", rsc_list);
676 add_notify_env_free_gs(n_data, "notify_stop_uname", node_list);
677
678 if ((n_data->start != NULL)
679 && pcmk__str_eq(n_data->action, RSC_START, pcmk__str_none)) {
680 required = true;
681 }
682 n_data->start = notify_entries_to_strings(n_data->start,
683 &rsc_list, &node_list);
684 add_notify_env_free_gs(n_data, "notify_start_resource", rsc_list);
685 add_notify_env_free_gs(n_data, "notify_start_uname", node_list);
686
687 if ((n_data->demote != NULL)
688 && pcmk__str_eq(n_data->action, RSC_DEMOTE, pcmk__str_none)) {
689 required = true;
690 }
691 n_data->demote = notify_entries_to_strings(n_data->demote,
692 &rsc_list, &node_list);
693 add_notify_env_free_gs(n_data, "notify_demote_resource", rsc_list);
694 add_notify_env_free_gs(n_data, "notify_demote_uname", node_list);
695
696 if ((n_data->promote != NULL)
697 && pcmk__str_eq(n_data->action, RSC_PROMOTE, pcmk__str_none)) {
698 required = true;
699 }
700 n_data->promote = notify_entries_to_strings(n_data->promote,
701 &rsc_list, &node_list);
702 add_notify_env_free_gs(n_data, "notify_promote_resource", rsc_list);
703 add_notify_env_free_gs(n_data, "notify_promote_uname", node_list);
704
705 n_data->active = notify_entries_to_strings(n_data->active,
706 &rsc_list, &node_list);
707 add_notify_env_free_gs(n_data, "notify_active_resource", rsc_list);
708 add_notify_env_free_gs(n_data, "notify_active_uname", node_list);
709
710 n_data->unpromoted = notify_entries_to_strings(n_data->unpromoted,
711 &rsc_list, &node_list);
712 add_notify_env_gs(n_data, "notify_unpromoted_resource", rsc_list);
713 add_notify_env_gs(n_data, "notify_unpromoted_uname", node_list);
714
715
716 add_notify_env_free_gs(n_data, "notify_slave_resource", rsc_list);
717 add_notify_env_free_gs(n_data, "notify_slave_uname", node_list);
718
719 n_data->promoted = notify_entries_to_strings(n_data->promoted,
720 &rsc_list, &node_list);
721 add_notify_env_gs(n_data, "notify_promoted_resource", rsc_list);
722 add_notify_env_gs(n_data, "notify_promoted_uname", node_list);
723
724
725 add_notify_env_free_gs(n_data, "notify_master_resource", rsc_list);
726 add_notify_env_free_gs(n_data, "notify_master_uname", node_list);
727
728 n_data->inactive = notify_entries_to_strings(n_data->inactive,
729 &rsc_list, NULL);
730 add_notify_env_free_gs(n_data, "notify_inactive_resource", rsc_list);
731
732 nodes = g_hash_table_get_values(n_data->allowed_nodes);
733 if (!pcmk__is_daemon) {
734
735
736
737
738 nodes = g_list_sort(nodes, pe__cmp_node_name);
739 }
740 get_node_names(nodes, &node_list, NULL);
741 add_notify_env_free_gs(n_data, "notify_available_uname", node_list);
742 g_list_free(nodes);
743
744 source = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_TARGET);
745 if (pcmk__str_eq("host", source, pcmk__str_none)) {
746 get_node_names(rsc->cluster->nodes, &node_list, &metal_list);
747 add_notify_env_free_gs(n_data, "notify_all_hosts", metal_list);
748 } else {
749 get_node_names(rsc->cluster->nodes, &node_list, NULL);
750 }
751 add_notify_env_free_gs(n_data, "notify_all_uname", node_list);
752
753 if (required && (n_data->pre != NULL)) {
754 pe__clear_action_flags(n_data->pre, pe_action_optional);
755 pe__clear_action_flags(n_data->pre_done, pe_action_optional);
756 }
757
758 if (required && (n_data->post != NULL)) {
759 pe__clear_action_flags(n_data->post, pe_action_optional);
760 pe__clear_action_flags(n_data->post_done, pe_action_optional);
761 }
762 }
763
764
765
766
767
768
769
770
771
772 static pe_action_t *
773 find_remote_start(pe_action_t *action)
774 {
775 if ((action != NULL) && (action->node != NULL)) {
776 pe_resource_t *remote_rsc = action->node->details->remote_rsc;
777
778 if (remote_rsc != NULL) {
779 return find_first_action(remote_rsc->actions, NULL, RSC_START,
780 NULL);
781 }
782 }
783 return NULL;
784 }
785
786
787
788
789
790
791
792
793 static void
794 create_notify_actions(pe_resource_t *rsc, notify_data_t *n_data)
795 {
796 GList *iter = NULL;
797 pe_action_t *stop = NULL;
798 pe_action_t *start = NULL;
799 enum action_tasks task = text2task(n_data->action);
800
801
802 if (rsc->children != NULL) {
803 g_list_foreach(rsc->children, (GFunc) create_notify_actions, n_data);
804 return;
805 }
806
807
808 for (iter = rsc->actions; iter != NULL; iter = iter->next) {
809 pe_action_t *op = (pe_action_t *) iter->data;
810
811 if (!pcmk_is_set(op->flags, pe_action_optional) && (op->node != NULL)) {
812 switch (text2task(op->task)) {
813 case start_rsc:
814 case stop_rsc:
815 case action_promote:
816 case action_demote:
817 add_notify_data_to_action_meta(n_data, op);
818 break;
819 default:
820 break;
821 }
822 }
823 }
824
825
826 switch (task) {
827 case start_rsc:
828 if (n_data->start == NULL) {
829 pe_rsc_trace(rsc, "No notify action needed for %s %s",
830 rsc->id, n_data->action);
831 return;
832 }
833 break;
834
835 case action_promote:
836 if (n_data->promote == NULL) {
837 pe_rsc_trace(rsc, "No notify action needed for %s %s",
838 rsc->id, n_data->action);
839 return;
840 }
841 break;
842
843 case action_demote:
844 if (n_data->demote == NULL) {
845 pe_rsc_trace(rsc, "No notify action needed for %s %s",
846 rsc->id, n_data->action);
847 return;
848 }
849 break;
850
851 default:
852
853 break;
854 }
855
856 pe_rsc_trace(rsc, "Creating notify actions for %s %s",
857 rsc->id, n_data->action);
858
859
860 if ((rsc->role != RSC_ROLE_STOPPED)
861 && ((task == stop_rsc) || (task == action_demote))) {
862
863 stop = find_first_action(rsc->actions, NULL, RSC_STOP, NULL);
864
865 for (iter = rsc->running_on; iter != NULL; iter = iter->next) {
866 pe_node_t *current_node = (pe_node_t *) iter->data;
867
868
869
870
871 if ((stop != NULL) && pcmk_is_set(stop->flags, pe_action_pseudo)
872 && (current_node->details->unclean
873 || current_node->details->remote_requires_reset)) {
874 continue;
875 }
876
877 new_notify_action(rsc, current_node, n_data->pre,
878 n_data->pre_done, n_data);
879
880 if ((task == action_demote) || (stop == NULL)
881 || pcmk_is_set(stop->flags, pe_action_optional)) {
882 new_post_notify_action(rsc, current_node, n_data);
883 }
884 }
885 }
886
887
888 if ((rsc->next_role != RSC_ROLE_STOPPED)
889 && ((task == start_rsc) || (task == action_promote))) {
890
891 start = find_first_action(rsc->actions, NULL, RSC_START, NULL);
892 if (start != NULL) {
893 pe_action_t *remote_start = find_remote_start(start);
894
895 if ((remote_start != NULL)
896 && !pcmk_is_set(remote_start->flags, pe_action_runnable)) {
897
898
899
900
901
902 return;
903 }
904 }
905 if (rsc->allocated_to == NULL) {
906 pe_proc_err("Next role '%s' but %s is not allocated",
907 role2text(rsc->next_role), rsc->id);
908 return;
909 }
910 if ((task != start_rsc) || (start == NULL)
911 || pcmk_is_set(start->flags, pe_action_optional)) {
912
913 new_notify_action(rsc, rsc->allocated_to, n_data->pre,
914 n_data->pre_done, n_data);
915 }
916 new_post_notify_action(rsc, rsc->allocated_to, n_data);
917 }
918 }
919
920
921
922
923
924
925
926
927 void
928 pe__create_notifications(pe_resource_t *rsc, notify_data_t *n_data)
929 {
930 if ((rsc == NULL) || (n_data == NULL)) {
931 return;
932 }
933 collect_resource_data(rsc, true, n_data);
934 add_notif_keys(rsc, n_data);
935 create_notify_actions(rsc, n_data);
936 }
937
938
939
940
941
942
943
944 void
945 pe__free_notification_data(notify_data_t *n_data)
946 {
947 if (n_data == NULL) {
948 return;
949 }
950 g_list_free_full(n_data->stop, free);
951 g_list_free_full(n_data->start, free);
952 g_list_free_full(n_data->demote, free);
953 g_list_free_full(n_data->promote, free);
954 g_list_free_full(n_data->promoted, free);
955 g_list_free_full(n_data->unpromoted, free);
956 g_list_free_full(n_data->active, free);
957 g_list_free_full(n_data->inactive, free);
958 pcmk_free_nvpairs(n_data->keys);
959 free(n_data);
960 }
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976 void
977 pe__order_notifs_after_fencing(pe_action_t *stop, pe_resource_t *rsc,
978 pe_action_t *stonith_op)
979 {
980 notify_data_t *n_data;
981
982 crm_info("Ordering notifications for implied %s after fencing", stop->uuid);
983 n_data = pe__clone_notif_pseudo_ops(rsc, RSC_STOP, NULL, stonith_op);
984
985 if (n_data != NULL) {
986 collect_resource_data(rsc, false, n_data);
987 add_notify_env(n_data, "notify_stop_resource", rsc->id);
988 add_notify_env(n_data, "notify_stop_uname", stop->node->details->uname);
989 create_notify_actions(uber_parent(rsc), n_data);
990 pe__free_notification_data(n_data);
991 }
992 }