This source file includes following definitions.
- action_flags_for_ordering
- action_uuid_for_ordering
- action_for_ordering
- update_action_for_ordering_flags
- pcmk__update_action_for_orderings
- pcmk__log_action
- pcmk__new_rsc_pseudo_action
- pcmk__new_cancel_action
- pcmk__new_shutdown_action
- add_op_digest_to_xml
- pcmk__create_history_xml
- pcmk__action_locks_rsc_to_node
- sort_action_id
- pcmk__deduplicate_action_inputs
- pcmk__output_actions
- schedule_cancel
- action_in_config
- task_for_digest
- only_sanitized_changed
- force_restart
- reschedule_recurring
- schedule_reload
- pcmk__check_action_config
- rsc_history_as_list
- process_rsc_history
- process_node_history
- pcmk__handle_rsc_config_changes
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <stdio.h>
  13 #include <sys/param.h>
  14 #include <glib.h>
  15 
  16 #include <crm/lrmd_internal.h>
  17 #include <pacemaker-internal.h>
  18 #include "libpacemaker_private.h"
  19 
  20 extern gboolean DeleteRsc(pe_resource_t *rsc, pe_node_t *node,
  21                           gboolean optional, pe_working_set_t *data_set);
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 
  31 
  32 
  33 static enum pe_action_flags
  34 action_flags_for_ordering(pe_action_t *action, pe_node_t *node)
     
  35 {
  36     bool runnable = false;
  37     enum pe_action_flags flags;
  38 
  39     
  40     if (action->rsc == NULL) {
  41         return action->flags;
  42     }
  43 
  44     
  45 
  46 
  47 
  48     flags = action->rsc->cmds->action_flags(action, NULL);
  49     if ((node == NULL) || !pe_rsc_is_clone(action->rsc)) {
  50         return flags;
  51     }
  52 
  53     
  54 
  55 
  56     runnable = pcmk_is_set(flags, pe_action_runnable);
  57 
  58     
  59     flags = action->rsc->cmds->action_flags(action, node);
  60 
  61     
  62 
  63 
  64 
  65 
  66 
  67 
  68 
  69     if (runnable && !pcmk_is_set(flags, pe_action_runnable)) {
  70         pe__set_raw_action_flags(flags, action->rsc->id,
  71                                  pe_action_runnable);
  72     }
  73     return flags;
  74 }
  75 
  76 
  77 
  78 
  79 
  80 
  81 
  82 
  83 
  84 
  85 
  86 
  87 
  88 
  89 
  90 
  91 
  92 
  93 
  94 static char *
  95 action_uuid_for_ordering(const char *first_uuid, pe_resource_t *first_rsc)
     
  96 {
  97     guint interval_ms = 0;
  98     char *uuid = NULL;
  99     char *rid = NULL;
 100     char *first_task_str = NULL;
 101     enum action_tasks first_task = no_action;
 102     enum action_tasks remapped_task = no_action;
 103 
 104     
 105     if ((strstr(first_uuid, "notify") != NULL)
 106         || (first_rsc->variant < pe_group)) {
 107         goto done;
 108     }
 109 
 110     
 111     CRM_ASSERT(parse_op_key(first_uuid, &rid, &first_task_str, &interval_ms));
 112     if (interval_ms > 0) {
 113         goto done;
 114     }
 115 
 116     first_task = text2task(first_task_str);
 117     switch (first_task) {
 118         case stop_rsc:
 119         case start_rsc:
 120         case action_notify:
 121         case action_promote:
 122         case action_demote:
 123             remapped_task = first_task + 1;
 124             break;
 125         case stopped_rsc:
 126         case started_rsc:
 127         case action_notified:
 128         case action_promoted:
 129         case action_demoted:
 130             remapped_task = first_task;
 131             break;
 132         case monitor_rsc:
 133         case shutdown_crm:
 134         case stonith_node:
 135             break;
 136         default:
 137             crm_err("Unknown action '%s' in ordering", first_task_str);
 138             break;
 139     }
 140 
 141     if (remapped_task != no_action) {
 142         
 143 
 144 
 145 
 146 
 147         if (pcmk_is_set(first_rsc->flags, pe_rsc_notify)
 148             && ((first_rsc->parent == NULL)
 149                 || (pe_rsc_is_clone(first_rsc)
 150                     && (first_rsc->parent->variant == pe_container)))) {
 151             uuid = pcmk__notify_key(rid, "confirmed-post",
 152                                     task2text(remapped_task));
 153         } else {
 154             uuid = pcmk__op_key(rid, task2text(remapped_task), 0);
 155         }
 156         pe_rsc_trace(first_rsc,
 157                      "Remapped action UUID %s to %s for ordering purposes",
 158                      first_uuid, uuid);
 159     }
 160 
 161 done:
 162     if (uuid == NULL) {
 163         uuid = strdup(first_uuid);
 164         CRM_ASSERT(uuid != NULL);
 165     }
 166     free(first_task_str);
 167     free(rid);
 168     return uuid;
 169 }
 170 
 171 
 172 
 173 
 174 
 175 
 176 
 177 
 178 
 179 
 180 
 181 
 182 
 183 
 184 
 185 
 186 
 187 static pe_action_t *
 188 action_for_ordering(pe_action_t *action)
     
 189 {
 190     pe_action_t *result = action;
 191     pe_resource_t *rsc = action->rsc;
 192 
 193     if ((rsc != NULL) && (rsc->variant >= pe_group) && (action->uuid != NULL)) {
 194         char *uuid = action_uuid_for_ordering(action->uuid, rsc);
 195 
 196         result = find_first_action(rsc->actions, uuid, NULL, NULL);
 197         if (result == NULL) {
 198             crm_warn("Not remapping %s to %s because %s does not have "
 199                      "remapped action", action->uuid, uuid, rsc->id);
 200             result = action;
 201         }
 202         free(uuid);
 203     }
 204     return result;
 205 }
 206 
 207 
 208 
 209 
 210 
 211 
 212 
 213 
 214 
 215 
 216 
 217 
 218 
 219 
 220 static enum pe_graph_flags
 221 update_action_for_ordering_flags(pe_action_t *first, pe_action_t *then,
     
 222                                  enum pe_action_flags first_flags,
 223                                  enum pe_action_flags then_flags,
 224                                  pe_action_wrapper_t *order,
 225                                  pe_working_set_t *data_set)
 226 {
 227     enum pe_graph_flags changed = pe_graph_none;
 228 
 229     
 230 
 231 
 232 
 233 
 234     pe_node_t *node = then->node;
 235 
 236     if (pcmk_is_set(order->type, pe_order_implies_then_on_node)) {
 237         
 238 
 239 
 240 
 241 
 242         pe__clear_order_flags(order->type, pe_order_implies_then_on_node);
 243         pe__set_order_flags(order->type, pe_order_implies_then);
 244         node = first->node;
 245         pe_rsc_trace(then->rsc,
 246                      "%s then %s: mapped pe_order_implies_then_on_node to "
 247                      "pe_order_implies_then on %s",
 248                      first->uuid, then->uuid, node->details->uname);
 249     }
 250 
 251     if (pcmk_is_set(order->type, pe_order_implies_then)) {
 252         if (then->rsc != NULL) {
 253             changed |= then->rsc->cmds->update_actions(first, then, node,
 254                                                        first_flags & pe_action_optional,
 255                                                        pe_action_optional,
 256                                                        pe_order_implies_then,
 257                                                        data_set);
 258         } else if (!pcmk_is_set(first_flags, pe_action_optional)
 259                    && pcmk_is_set(then->flags, pe_action_optional)) {
 260             pe__clear_action_flags(then, pe_action_optional);
 261             pe__set_graph_flags(changed, first, pe_graph_updated_then);
 262         }
 263         pe_rsc_trace(then->rsc, "%s then %s: %s after pe_order_implies_then",
 264                      first->uuid, then->uuid,
 265                      (changed? "changed" : "unchanged"));
 266     }
 267 
 268     if (pcmk_is_set(order->type, pe_order_restart) && (then->rsc != NULL)) {
 269         enum pe_action_flags restart = pe_action_optional|pe_action_runnable;
 270 
 271         changed |= then->rsc->cmds->update_actions(first, then, node,
 272                                                    first_flags, restart,
 273                                                    pe_order_restart, data_set);
 274         pe_rsc_trace(then->rsc, "%s then %s: %s after pe_order_restart",
 275                      first->uuid, then->uuid,
 276                      (changed? "changed" : "unchanged"));
 277     }
 278 
 279     if (pcmk_is_set(order->type, pe_order_implies_first)) {
 280         if (first->rsc != NULL) {
 281             changed |= first->rsc->cmds->update_actions(first, then, node,
 282                                                         first_flags,
 283                                                         pe_action_optional,
 284                                                         pe_order_implies_first,
 285                                                         data_set);
 286         } else if (!pcmk_is_set(first_flags, pe_action_optional)
 287                    && pcmk_is_set(first->flags, pe_action_runnable)) {
 288             pe__clear_action_flags(first, pe_action_runnable);
 289             pe__set_graph_flags(changed, first, pe_graph_updated_first);
 290         }
 291         pe_rsc_trace(then->rsc, "%s then %s: %s after pe_order_implies_first",
 292                      first->uuid, then->uuid,
 293                      (changed? "changed" : "unchanged"));
 294     }
 295 
 296     if (pcmk_is_set(order->type, pe_order_promoted_implies_first)) {
 297         if (then->rsc != NULL) {
 298             changed |= then->rsc->cmds->update_actions(first, then, node,
 299                                                        first_flags & pe_action_optional,
 300                                                        pe_action_optional,
 301                                                        pe_order_promoted_implies_first,
 302                                                        data_set);
 303         }
 304         pe_rsc_trace(then->rsc,
 305                      "%s then %s: %s after pe_order_promoted_implies_first",
 306                      first->uuid, then->uuid,
 307                      (changed? "changed" : "unchanged"));
 308     }
 309 
 310     if (pcmk_is_set(order->type, pe_order_one_or_more)) {
 311         if (then->rsc != NULL) {
 312             changed |= then->rsc->cmds->update_actions(first, then, node,
 313                                                        first_flags,
 314                                                        pe_action_runnable,
 315                                                        pe_order_one_or_more,
 316                                                        data_set);
 317 
 318         } else if (pcmk_is_set(first_flags, pe_action_runnable)) {
 319             
 320             then->runnable_before++;
 321 
 322             
 323 
 324 
 325             if ((then->runnable_before >= then->required_runnable_before)
 326                 && !pcmk_is_set(then->flags, pe_action_runnable)) {
 327 
 328                 pe__set_action_flags(then, pe_action_runnable);
 329                 pe__set_graph_flags(changed, first, pe_graph_updated_then);
 330             }
 331         }
 332         pe_rsc_trace(then->rsc, "%s then %s: %s after pe_order_one_or_more",
 333                      first->uuid, then->uuid,
 334                      (changed? "changed" : "unchanged"));
 335     }
 336 
 337     if (pcmk_is_set(order->type, pe_order_probe) && (then->rsc != NULL)) {
 338         if (!pcmk_is_set(first_flags, pe_action_runnable)
 339             && (first->rsc->running_on != NULL)) {
 340 
 341             pe_rsc_trace(then->rsc,
 342                          "%s then %s: ignoring because first is stopping",
 343                          first->uuid, then->uuid);
 344             order->type = pe_order_none;
 345         } else {
 346             changed |= then->rsc->cmds->update_actions(first, then, node,
 347                                                        first_flags,
 348                                                        pe_action_runnable,
 349                                                        pe_order_runnable_left,
 350                                                        data_set);
 351         }
 352         pe_rsc_trace(then->rsc, "%s then %s: %s after pe_order_probe",
 353                      first->uuid, then->uuid,
 354                      (changed? "changed" : "unchanged"));
 355     }
 356 
 357     if (pcmk_is_set(order->type, pe_order_runnable_left)) {
 358         if (then->rsc != NULL) {
 359             changed |= then->rsc->cmds->update_actions(first, then, node,
 360                                                        first_flags,
 361                                                        pe_action_runnable,
 362                                                        pe_order_runnable_left,
 363                                                        data_set);
 364 
 365         } else if (!pcmk_is_set(first_flags, pe_action_runnable)
 366                    && pcmk_is_set(then->flags, pe_action_runnable)) {
 367 
 368             pe__clear_action_flags(then, pe_action_runnable);
 369             pe__set_graph_flags(changed, first, pe_graph_updated_then);
 370         }
 371         pe_rsc_trace(then->rsc, "%s then %s: %s after pe_order_runnable_left",
 372                      first->uuid, then->uuid,
 373                      (changed? "changed" : "unchanged"));
 374     }
 375 
 376     if (pcmk_is_set(order->type, pe_order_implies_first_migratable)) {
 377         if (then->rsc != NULL) {
 378             changed |= then->rsc->cmds->update_actions(first, then, node,
 379                 first_flags, pe_action_optional,
 380                 pe_order_implies_first_migratable, data_set);
 381         }
 382         pe_rsc_trace(then->rsc, "%s then %s: %s after "
 383                      "pe_order_implies_first_migratable",
 384                      first->uuid, then->uuid,
 385                      (changed? "changed" : "unchanged"));
 386     }
 387 
 388     if (pcmk_is_set(order->type, pe_order_pseudo_left)) {
 389         if (then->rsc != NULL) {
 390             changed |= then->rsc->cmds->update_actions(first, then, node,
 391                                                        first_flags,
 392                                                        pe_action_optional,
 393                                                        pe_order_pseudo_left,
 394                                                        data_set);
 395         }
 396         pe_rsc_trace(then->rsc, "%s then %s: %s after pe_order_pseudo_left",
 397                      first->uuid, then->uuid,
 398                      (changed? "changed" : "unchanged"));
 399     }
 400 
 401     if (pcmk_is_set(order->type, pe_order_optional)) {
 402         if (then->rsc != NULL) {
 403             changed |= then->rsc->cmds->update_actions(first, then, node,
 404                                                        first_flags,
 405                                                        pe_action_runnable,
 406                                                        pe_order_optional,
 407                                                        data_set);
 408         }
 409         pe_rsc_trace(then->rsc, "%s then %s: %s after pe_order_optional",
 410                      first->uuid, then->uuid,
 411                      (changed? "changed" : "unchanged"));
 412     }
 413 
 414     if (pcmk_is_set(order->type, pe_order_asymmetrical)) {
 415         if (then->rsc != NULL) {
 416             changed |= then->rsc->cmds->update_actions(first, then, node,
 417                                                        first_flags,
 418                                                        pe_action_runnable,
 419                                                        pe_order_asymmetrical,
 420                                                        data_set);
 421         }
 422         pe_rsc_trace(then->rsc, "%s then %s: %s after pe_order_asymmetrical",
 423                      first->uuid, then->uuid,
 424                      (changed? "changed" : "unchanged"));
 425     }
 426 
 427     if (pcmk_is_set(first->flags, pe_action_runnable)
 428         && pcmk_is_set(order->type, pe_order_implies_then_printed)
 429         && !pcmk_is_set(first_flags, pe_action_optional)) {
 430 
 431         pe_rsc_trace(then->rsc, "%s will be in graph because %s is required",
 432                      then->uuid, first->uuid);
 433         pe__set_action_flags(then, pe_action_print_always);
 434         
 435     }
 436 
 437     if (pcmk_is_set(order->type, pe_order_implies_first_printed)
 438         && !pcmk_is_set(then_flags, pe_action_optional)) {
 439 
 440         pe_rsc_trace(then->rsc, "%s will be in graph because %s is required",
 441                      first->uuid, then->uuid);
 442         pe__set_action_flags(first, pe_action_print_always);
 443         
 444     }
 445 
 446     if (pcmk_any_flags_set(order->type, pe_order_implies_then
 447                                         |pe_order_implies_first
 448                                         |pe_order_restart)
 449         && (first->rsc != NULL)
 450         && !pcmk_is_set(first->rsc->flags, pe_rsc_managed)
 451         && pcmk_is_set(first->rsc->flags, pe_rsc_block)
 452         && !pcmk_is_set(first->flags, pe_action_runnable)
 453         && pcmk__str_eq(first->task, RSC_STOP, pcmk__str_casei)) {
 454 
 455         if (pcmk_is_set(then->flags, pe_action_runnable)) {
 456             pe__clear_action_flags(then, pe_action_runnable);
 457             pe__set_graph_flags(changed, first, pe_graph_updated_then);
 458         }
 459         pe_rsc_trace(then->rsc, "%s then %s: %s after checking whether first "
 460                      "is blocked, unmanaged, unrunnable stop",
 461                      first->uuid, then->uuid,
 462                      (changed? "changed" : "unchanged"));
 463     }
 464 
 465     return changed;
 466 }
 467 
 468 
 469 
 470 #define action_type_str(flags) \
 471     (pcmk_is_set((flags), pe_action_pseudo)? "pseudo-action" : "action")
 472 
 473 #define action_optional_str(flags) \
 474     (pcmk_is_set((flags), pe_action_optional)? "optional" : "required")
 475 
 476 #define action_runnable_str(flags) \
 477     (pcmk_is_set((flags), pe_action_runnable)? "runnable" : "unrunnable")
 478 
 479 #define action_node_str(a) \
 480     (((a)->node == NULL)? "no node" : (a)->node->details->uname)
 481 
 482 
 483 
 484 
 485 
 486 
 487 
 488 
 489 void
 490 pcmk__update_action_for_orderings(pe_action_t *then, pe_working_set_t *data_set)
     
 491 {
 492     GList *lpc = NULL;
 493     enum pe_graph_flags changed = pe_graph_none;
 494     int last_flags = then->flags;
 495 
 496     pe_rsc_trace(then->rsc, "Updating %s %s (%s %s) on %s",
 497                  action_type_str(then->flags), then->uuid,
 498                  action_optional_str(then->flags),
 499                  action_runnable_str(then->flags), action_node_str(then));
 500 
 501     if (pcmk_is_set(then->flags, pe_action_requires_any)) {
 502         
 503 
 504 
 505 
 506 
 507         then->runnable_before = 0;
 508 
 509         if (then->required_runnable_before == 0) {
 510             
 511 
 512 
 513             then->required_runnable_before = 1;
 514         }
 515 
 516         
 517 
 518 
 519         pe__clear_action_flags(then, pe_action_runnable);
 520     }
 521 
 522     for (lpc = then->actions_before; lpc != NULL; lpc = lpc->next) {
 523         pe_action_wrapper_t *other = (pe_action_wrapper_t *) lpc->data;
 524         pe_action_t *first = other->action;
 525 
 526         pe_node_t *then_node = then->node;
 527         pe_node_t *first_node = first->node;
 528 
 529         if ((first->rsc != NULL)
 530             && (first->rsc->variant == pe_group)
 531             && pcmk__str_eq(first->task, RSC_START, pcmk__str_casei)) {
 532 
 533             first_node = first->rsc->fns->location(first->rsc, NULL, FALSE);
 534             if (first_node != NULL) {
 535                 pe_rsc_trace(first->rsc, "Found node %s for 'first' %s",
 536                              first_node->details->uname, first->uuid);
 537             }
 538         }
 539 
 540         if ((then->rsc != NULL)
 541             && (then->rsc->variant == pe_group)
 542             && pcmk__str_eq(then->task, RSC_START, pcmk__str_casei)) {
 543 
 544             then_node = then->rsc->fns->location(then->rsc, NULL, FALSE);
 545             if (then_node != NULL) {
 546                 pe_rsc_trace(then->rsc, "Found node %s for 'then' %s",
 547                              then_node->details->uname, then->uuid);
 548             }
 549         }
 550 
 551         
 552         if (pcmk_is_set(other->type, pe_order_same_node)
 553             && (first_node != NULL) && (then_node != NULL)
 554             && (first_node->details != then_node->details)) {
 555 
 556             pe_rsc_trace(then->rsc,
 557                          "Disabled ordering %s on %s then %s on %s: not same node",
 558                          other->action->uuid, first_node->details->uname,
 559                          then->uuid, then_node->details->uname);
 560             other->type = pe_order_none;
 561             continue;
 562         }
 563 
 564         pe__clear_graph_flags(changed, then, pe_graph_updated_first);
 565 
 566         if ((first->rsc != NULL)
 567             && pcmk_is_set(other->type, pe_order_then_cancels_first)
 568             && !pcmk_is_set(then->flags, pe_action_optional)) {
 569 
 570             
 571 
 572 
 573             pe__set_action_flags(other->action, pe_action_optional);
 574             if (!strcmp(first->task, CRMD_ACTION_RELOAD_AGENT)) {
 575                 pe__clear_resource_flags(first->rsc, pe_rsc_reload);
 576             }
 577         }
 578 
 579         if ((first->rsc != NULL) && (then->rsc != NULL)
 580             && (first->rsc != then->rsc) && !is_parent(then->rsc, first->rsc)) {
 581             first = action_for_ordering(first);
 582         }
 583         if (first != other->action) {
 584             pe_rsc_trace(then->rsc, "Ordering %s after %s instead of %s",
 585                          then->uuid, first->uuid, other->action->uuid);
 586         }
 587 
 588         pe_rsc_trace(then->rsc,
 589                      "%s (%#.6x) then %s (%#.6x): type=%#.6x node=%s",
 590                      first->uuid, first->flags, then->uuid, then->flags,
 591                      other->type, action_node_str(first));
 592 
 593         if (first == other->action) {
 594             
 595 
 596 
 597 
 598             enum pe_action_flags first_flags, then_flags;
 599 
 600             first_flags = action_flags_for_ordering(first, then_node);
 601             then_flags = action_flags_for_ordering(then, first_node);
 602 
 603             changed |= update_action_for_ordering_flags(first, then,
 604                                                         first_flags, then_flags,
 605                                                         other, data_set);
 606 
 607             
 608 
 609 
 610         } else if (order_actions(first, then, other->type)) {
 611             
 612 
 613 
 614             pe__set_graph_flags(changed, then,
 615                                 pe_graph_updated_then|pe_graph_disable);
 616         }
 617 
 618         if (pcmk_is_set(changed, pe_graph_disable)) {
 619             pe_rsc_trace(then->rsc,
 620                          "Disabled ordering %s then %s in favor of %s then %s",
 621                          other->action->uuid, then->uuid, first->uuid,
 622                          then->uuid);
 623             pe__clear_graph_flags(changed, then, pe_graph_disable);
 624             other->type = pe_order_none;
 625         }
 626 
 627         if (pcmk_is_set(changed, pe_graph_updated_first)) {
 628             crm_trace("Re-processing %s and its 'after' actions "
 629                       "because it changed", first->uuid);
 630             for (GList *lpc2 = first->actions_after; lpc2 != NULL;
 631                  lpc2 = lpc2->next) {
 632                 pe_action_wrapper_t *other = (pe_action_wrapper_t *) lpc2->data;
 633 
 634                 pcmk__update_action_for_orderings(other->action, data_set);
 635             }
 636             pcmk__update_action_for_orderings(first, data_set);
 637         }
 638     }
 639 
 640     if (pcmk_is_set(then->flags, pe_action_requires_any)) {
 641         if (last_flags == then->flags) {
 642             pe__clear_graph_flags(changed, then, pe_graph_updated_then);
 643         } else {
 644             pe__set_graph_flags(changed, then, pe_graph_updated_then);
 645         }
 646     }
 647 
 648     if (pcmk_is_set(changed, pe_graph_updated_then)) {
 649         crm_trace("Re-processing %s and its 'after' actions because it changed",
 650                   then->uuid);
 651         if (pcmk_is_set(last_flags, pe_action_runnable)
 652             && !pcmk_is_set(then->flags, pe_action_runnable)) {
 653             pcmk__block_colocated_starts(then, data_set);
 654         }
 655         pcmk__update_action_for_orderings(then, data_set);
 656         for (lpc = then->actions_after; lpc != NULL; lpc = lpc->next) {
 657             pe_action_wrapper_t *other = (pe_action_wrapper_t *) lpc->data;
 658 
 659             pcmk__update_action_for_orderings(other->action, data_set);
 660         }
 661     }
 662 }
 663 
 664 
 665 
 666 
 667 
 668 
 669 
 670 
 671 
 672 void
 673 pcmk__log_action(const char *pre_text, pe_action_t *action, bool details)
     
 674 {
 675     const char *node_uname = NULL;
 676     const char *node_uuid = NULL;
 677     const char *desc = NULL;
 678 
 679     CRM_CHECK(action != NULL, return);
 680 
 681     if (!pcmk_is_set(action->flags, pe_action_pseudo)) {
 682         if (action->node != NULL) {
 683             node_uname = action->node->details->uname;
 684             node_uuid = action->node->details->id;
 685         } else {
 686             node_uname = "<none>";
 687         }
 688     }
 689 
 690     switch (text2task(action->task)) {
 691         case stonith_node:
 692         case shutdown_crm:
 693             if (pcmk_is_set(action->flags, pe_action_pseudo)) {
 694                 desc = "Pseudo ";
 695             } else if (pcmk_is_set(action->flags, pe_action_optional)) {
 696                 desc = "Optional ";
 697             } else if (!pcmk_is_set(action->flags, pe_action_runnable)) {
 698                 desc = "!!Non-Startable!! ";
 699             } else if (pcmk_is_set(action->flags, pe_action_processed)) {
 700                desc = "";
 701             } else {
 702                desc = "(Provisional) ";
 703             }
 704             crm_trace("%s%s%sAction %d: %s%s%s%s%s%s",
 705                       ((pre_text == NULL)? "" : pre_text),
 706                       ((pre_text == NULL)? "" : ": "),
 707                       desc, action->id, action->uuid,
 708                       (node_uname? "\ton " : ""), (node_uname? node_uname : ""),
 709                       (node_uuid? "\t\t(" : ""), (node_uuid? node_uuid : ""),
 710                       (node_uuid? ")" : ""));
 711             break;
 712         default:
 713             if (pcmk_is_set(action->flags, pe_action_optional)) {
 714                 desc = "Optional ";
 715             } else if (pcmk_is_set(action->flags, pe_action_pseudo)) {
 716                 desc = "Pseudo ";
 717             } else if (!pcmk_is_set(action->flags, pe_action_runnable)) {
 718                 desc = "!!Non-Startable!! ";
 719             } else if (pcmk_is_set(action->flags, pe_action_processed)) {
 720                desc = "";
 721             } else {
 722                desc = "(Provisional) ";
 723             }
 724             crm_trace("%s%s%sAction %d: %s %s%s%s%s%s%s",
 725                       ((pre_text == NULL)? "" : pre_text),
 726                       ((pre_text == NULL)? "" : ": "),
 727                       desc, action->id, action->uuid,
 728                       (action->rsc? action->rsc->id : "<none>"),
 729                       (node_uname? "\ton " : ""), (node_uname? node_uname : ""),
 730                       (node_uuid? "\t\t(" : ""), (node_uuid? node_uuid : ""),
 731                       (node_uuid? ")" : ""));
 732             break;
 733     }
 734 
 735     if (details) {
 736         GList *iter = NULL;
 737 
 738         crm_trace("\t\t====== Preceding Actions");
 739         for (iter = action->actions_before; iter != NULL; iter = iter->next) {
 740             pe_action_wrapper_t *other = (pe_action_wrapper_t *) iter->data;
 741 
 742             pcmk__log_action("\t\t", other->action, false);
 743         }
 744         crm_trace("\t\t====== Subsequent Actions");
 745         for (iter = action->actions_after; iter != NULL; iter = iter->next) {
 746             pe_action_wrapper_t *other = (pe_action_wrapper_t *) iter->data;
 747 
 748             pcmk__log_action("\t\t", other->action, false);
 749         }
 750         crm_trace("\t\t====== End");
 751 
 752     } else {
 753         crm_trace("\t\t(before=%d, after=%d)",
 754                   g_list_length(action->actions_before),
 755                   g_list_length(action->actions_after));
 756     }
 757 }
 758 
 759 
 760 
 761 
 762 
 763 
 764 
 765 
 766 
 767 
 768 
 769 
 770 pe_action_t *
 771 pcmk__new_rsc_pseudo_action(pe_resource_t *rsc, const char *task,
     
 772                             bool optional, bool runnable)
 773 {
 774     pe_action_t *action = NULL;
 775 
 776     CRM_ASSERT((rsc != NULL) && (task != NULL));
 777 
 778     action = custom_action(rsc, pcmk__op_key(rsc->id, task, 0), task, NULL,
 779                            optional, TRUE, rsc->cluster);
 780     pe__set_action_flags(action, pe_action_pseudo);
 781     if (runnable) {
 782         pe__set_action_flags(action, pe_action_runnable);
 783     }
 784     return action;
 785 }
 786 
 787 
 788 
 789 
 790 
 791 
 792 
 793 
 794 
 795 
 796 
 797 
 798 
 799 pe_action_t *
 800 pcmk__new_cancel_action(pe_resource_t *rsc, const char *task, guint interval_ms,
     
 801                         pe_node_t *node)
 802 {
 803     pe_action_t *cancel_op = NULL;
 804     char *key = NULL;
 805     char *interval_ms_s = NULL;
 806 
 807     CRM_ASSERT((rsc != NULL) && (task != NULL) && (node != NULL));
 808 
 809     
 810     key = pcmk__op_key(rsc->id, task, interval_ms);
 811 
 812     cancel_op = custom_action(rsc, key, RSC_CANCEL, node, FALSE, TRUE,
 813                               rsc->cluster);
 814 
 815     pcmk__str_update(&cancel_op->task, RSC_CANCEL);
 816     pcmk__str_update(&cancel_op->cancel_task, task);
 817 
 818     interval_ms_s = crm_strdup_printf("%u", interval_ms);
 819     add_hash_param(cancel_op->meta, XML_LRM_ATTR_TASK, task);
 820     add_hash_param(cancel_op->meta, XML_LRM_ATTR_INTERVAL_MS, interval_ms_s);
 821     free(interval_ms_s);
 822 
 823     return cancel_op;
 824 }
 825 
 826 
 827 
 828 
 829 
 830 
 831 
 832 
 833 
 834 
 835 pe_action_t *
 836 pcmk__new_shutdown_action(pe_node_t *node, pe_working_set_t *data_set)
     
 837 {
 838     char *shutdown_id = NULL;
 839     pe_action_t *shutdown_op = NULL;
 840 
 841     CRM_ASSERT((node != NULL) && (data_set != NULL));
 842 
 843     shutdown_id = crm_strdup_printf("%s-%s", CRM_OP_SHUTDOWN,
 844                                     node->details->uname);
 845 
 846     shutdown_op = custom_action(NULL, shutdown_id, CRM_OP_SHUTDOWN, node, FALSE,
 847                                 TRUE, data_set);
 848 
 849     pcmk__order_stops_before_shutdown(node, shutdown_op, data_set);
 850     add_hash_param(shutdown_op->meta, XML_ATTR_TE_NOWAIT, XML_BOOLEAN_TRUE);
 851     return shutdown_op;
 852 }
 853 
 854 
 855 
 856 
 857 
 858 
 859 
 860 
 861 
 862 
 863 
 864 
 865 static void
 866 add_op_digest_to_xml(lrmd_event_data_t *op, xmlNode *update)
     
 867 {
 868     char *digest = NULL;
 869     xmlNode *args_xml = NULL;
 870 
 871     if (op->params == NULL) {
 872         return;
 873     }
 874     args_xml = create_xml_node(NULL, XML_TAG_PARAMS);
 875     g_hash_table_foreach(op->params, hash2field, args_xml);
 876     pcmk__filter_op_for_digest(args_xml);
 877     digest = calculate_operation_digest(args_xml, NULL);
 878     crm_xml_add(update, XML_LRM_ATTR_OP_DIGEST, digest);
 879     free_xml(args_xml);
 880     free(digest);
 881 }
 882 
 883 #define FAKE_TE_ID     "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
 884 
 885 
 886 
 887 
 888 
 889 
 890 
 891 
 892 
 893 
 894 
 895 
 896 
 897 
 898 xmlNode *
 899 pcmk__create_history_xml(xmlNode *parent, lrmd_event_data_t *op,
     
 900                          const char *caller_version, int target_rc,
 901                          const char *node, const char *origin)
 902 {
 903     char *key = NULL;
 904     char *magic = NULL;
 905     char *op_id = NULL;
 906     char *op_id_additional = NULL;
 907     char *local_user_data = NULL;
 908     const char *exit_reason = NULL;
 909 
 910     xmlNode *xml_op = NULL;
 911     const char *task = NULL;
 912 
 913     CRM_CHECK(op != NULL, return NULL);
 914     crm_trace("Creating history XML for %s-interval %s action for %s on %s "
 915               "(DC version: %s, origin: %s)",
 916               pcmk__readable_interval(op->interval_ms), op->op_type, op->rsc_id,
 917               ((node == NULL)? "no node" : node), caller_version, origin);
 918 
 919     task = op->op_type;
 920 
 921     
 922 
 923 
 924 
 925 
 926 
 927 
 928 
 929 
 930     if (pcmk__str_any_of(task, CRMD_ACTION_RELOAD, CRMD_ACTION_RELOAD_AGENT,
 931                          NULL)) {
 932         if (op->op_status == PCMK_EXEC_DONE) {
 933             task = CRMD_ACTION_START;
 934         } else {
 935             task = CRMD_ACTION_STATUS;
 936         }
 937     }
 938 
 939     key = pcmk__op_key(op->rsc_id, task, op->interval_ms);
 940     if (pcmk__str_eq(task, CRMD_ACTION_NOTIFY, pcmk__str_none)) {
 941         const char *n_type = crm_meta_value(op->params, "notify_type");
 942         const char *n_task = crm_meta_value(op->params, "notify_operation");
 943 
 944         CRM_LOG_ASSERT(n_type != NULL);
 945         CRM_LOG_ASSERT(n_task != NULL);
 946         op_id = pcmk__notify_key(op->rsc_id, n_type, n_task);
 947 
 948         if (op->op_status != PCMK_EXEC_PENDING) {
 949             
 950 
 951 
 952 
 953 
 954             lrmd__set_result(op, PCMK_OCF_OK, PCMK_EXEC_DONE, NULL);
 955         }
 956 
 957     } else if (did_rsc_op_fail(op, target_rc)) {
 958         op_id = pcmk__op_key(op->rsc_id, "last_failure", 0);
 959         if (op->interval_ms == 0) {
 960             
 961             op_id_additional = pcmk__op_key(op->rsc_id, "last", 0);
 962         }
 963         exit_reason = op->exit_reason;
 964 
 965     } else if (op->interval_ms > 0) {
 966         op_id = strdup(key);
 967 
 968     } else {
 969         op_id = pcmk__op_key(op->rsc_id, "last", 0);
 970     }
 971 
 972   again:
 973     xml_op = pcmk__xe_match(parent, XML_LRM_TAG_RSC_OP, XML_ATTR_ID, op_id);
 974     if (xml_op == NULL) {
 975         xml_op = create_xml_node(parent, XML_LRM_TAG_RSC_OP);
 976     }
 977 
 978     if (op->user_data == NULL) {
 979         crm_debug("Generating fake transition key for: " PCMK__OP_FMT
 980                   " %d from %s", op->rsc_id, op->op_type, op->interval_ms,
 981                   op->call_id, origin);
 982         local_user_data = pcmk__transition_key(-1, op->call_id, target_rc,
 983                                                FAKE_TE_ID);
 984         op->user_data = local_user_data;
 985     }
 986 
 987     if (magic == NULL) {
 988         magic = crm_strdup_printf("%d:%d;%s", op->op_status, op->rc,
 989                                   (const char *) op->user_data);
 990     }
 991 
 992     crm_xml_add(xml_op, XML_ATTR_ID, op_id);
 993     crm_xml_add(xml_op, XML_LRM_ATTR_TASK_KEY, key);
 994     crm_xml_add(xml_op, XML_LRM_ATTR_TASK, task);
 995     crm_xml_add(xml_op, XML_ATTR_ORIGIN, origin);
 996     crm_xml_add(xml_op, XML_ATTR_CRM_VERSION, caller_version);
 997     crm_xml_add(xml_op, XML_ATTR_TRANSITION_KEY, op->user_data);
 998     crm_xml_add(xml_op, XML_ATTR_TRANSITION_MAGIC, magic);
 999     crm_xml_add(xml_op, XML_LRM_ATTR_EXIT_REASON, exit_reason == NULL ? "" : exit_reason);
1000     crm_xml_add(xml_op, XML_LRM_ATTR_TARGET, node); 
1001 
1002     crm_xml_add_int(xml_op, XML_LRM_ATTR_CALLID, op->call_id);
1003     crm_xml_add_int(xml_op, XML_LRM_ATTR_RC, op->rc);
1004     crm_xml_add_int(xml_op, XML_LRM_ATTR_OPSTATUS, op->op_status);
1005     crm_xml_add_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, op->interval_ms);
1006 
1007     if (compare_version("2.1", caller_version) <= 0) {
1008         if (op->t_run || op->t_rcchange || op->exec_time || op->queue_time) {
1009             crm_trace("Timing data (" PCMK__OP_FMT
1010                       "): last=%u change=%u exec=%u queue=%u",
1011                       op->rsc_id, op->op_type, op->interval_ms,
1012                       op->t_run, op->t_rcchange, op->exec_time, op->queue_time);
1013 
1014             if ((op->interval_ms != 0) && (op->t_rcchange != 0)) {
1015                 
1016                 crm_xml_add_ll(xml_op, XML_RSC_OP_LAST_CHANGE,
1017                                (long long) op->t_rcchange);
1018             } else {
1019                 crm_xml_add_ll(xml_op, XML_RSC_OP_LAST_CHANGE,
1020                                (long long) op->t_run);
1021             }
1022 
1023             crm_xml_add_int(xml_op, XML_RSC_OP_T_EXEC, op->exec_time);
1024             crm_xml_add_int(xml_op, XML_RSC_OP_T_QUEUE, op->queue_time);
1025         }
1026     }
1027 
1028     if (pcmk__str_any_of(op->op_type, CRMD_ACTION_MIGRATE, CRMD_ACTION_MIGRATED, NULL)) {
1029         
1030 
1031 
1032         const char *name = XML_LRM_ATTR_MIGRATE_SOURCE;
1033 
1034         crm_xml_add(xml_op, name, crm_meta_value(op->params, name));
1035 
1036         name = XML_LRM_ATTR_MIGRATE_TARGET;
1037         crm_xml_add(xml_op, name, crm_meta_value(op->params, name));
1038     }
1039 
1040     add_op_digest_to_xml(op, xml_op);
1041 
1042     if (op_id_additional) {
1043         free(op_id);
1044         op_id = op_id_additional;
1045         op_id_additional = NULL;
1046         goto again;
1047     }
1048 
1049     if (local_user_data) {
1050         free(local_user_data);
1051         op->user_data = NULL;
1052     }
1053     free(magic);
1054     free(op_id);
1055     free(key);
1056     return xml_op;
1057 }
1058 
1059 
1060 
1061 
1062 
1063 
1064 
1065 
1066 
1067 
1068 
1069 
1070 
1071 
1072 
1073 bool
1074 pcmk__action_locks_rsc_to_node(const pe_action_t *action)
     
1075 {
1076     
1077     if ((action == NULL) || (action->rsc == NULL)
1078         || (action->rsc->lock_node == NULL) || (action->node == NULL)
1079         || (action->node->details != action->rsc->lock_node->details)) {
1080         return false;
1081     }
1082 
1083     
1084 
1085 
1086     if (action->node->details->shutdown && (action->task != NULL)
1087         && (strcmp(action->task, RSC_STOP) != 0)) {
1088         return false;
1089     }
1090 
1091     return true;
1092 }
1093 
1094 
1095 static gint
1096 sort_action_id(gconstpointer a, gconstpointer b)
     
1097 {
1098     const pe_action_wrapper_t *action_wrapper2 = (const pe_action_wrapper_t *)a;
1099     const pe_action_wrapper_t *action_wrapper1 = (const pe_action_wrapper_t *)b;
1100 
1101     if (a == NULL) {
1102         return 1;
1103     }
1104     if (b == NULL) {
1105         return -1;
1106     }
1107     if (action_wrapper1->action->id < action_wrapper2->action->id) {
1108         return 1;
1109     }
1110     if (action_wrapper1->action->id > action_wrapper2->action->id) {
1111         return -1;
1112     }
1113     return 0;
1114 }
1115 
1116 
1117 
1118 
1119 
1120 
1121 
1122 void
1123 pcmk__deduplicate_action_inputs(pe_action_t *action)
     
1124 {
1125     GList *item = NULL;
1126     GList *next = NULL;
1127     pe_action_wrapper_t *last_input = NULL;
1128 
1129     action->actions_before = g_list_sort(action->actions_before,
1130                                          sort_action_id);
1131     for (item = action->actions_before; item != NULL; item = next) {
1132         pe_action_wrapper_t *input = (pe_action_wrapper_t *) item->data;
1133 
1134         next = item->next;
1135         if ((last_input != NULL)
1136             && (input->action->id == last_input->action->id)) {
1137             crm_trace("Input %s (%d) duplicate skipped for action %s (%d)",
1138                       input->action->uuid, input->action->id,
1139                       action->uuid, action->id);
1140 
1141             
1142 
1143 
1144 
1145             last_input->type |= input->type;
1146             if (input->state == pe_link_dumped) {
1147                 last_input->state = pe_link_dumped;
1148             }
1149 
1150             free(item->data);
1151             action->actions_before = g_list_delete_link(action->actions_before,
1152                                                         item);
1153         } else {
1154             last_input = input;
1155             input->state = pe_link_not_dumped;
1156         }
1157     }
1158 }
1159 
1160 
1161 
1162 
1163 
1164 
1165 
1166 void
1167 pcmk__output_actions(pe_working_set_t *data_set)
     
1168 {
1169     pcmk__output_t *out = data_set->priv;
1170 
1171     
1172     for (GList *iter = data_set->actions; iter != NULL; iter = iter->next) {
1173         char *node_name = NULL;
1174         char *task = NULL;
1175         pe_action_t *action = (pe_action_t *) iter->data;
1176 
1177         if (action->rsc != NULL) {
1178             continue; 
1179 
1180         } else if (pcmk_is_set(action->flags, pe_action_optional)) {
1181             continue; 
1182         }
1183 
1184         if (pcmk__str_eq(action->task, CRM_OP_SHUTDOWN, pcmk__str_casei)) {
1185             task = strdup("Shutdown");
1186 
1187         } else if (pcmk__str_eq(action->task, CRM_OP_FENCE, pcmk__str_casei)) {
1188             const char *op = g_hash_table_lookup(action->meta, "stonith_action");
1189 
1190             task = crm_strdup_printf("Fence (%s)", op);
1191 
1192         } else {
1193             continue; 
1194         }
1195 
1196         if (pe__is_guest_node(action->node)) {
1197             node_name = crm_strdup_printf("%s (resource: %s)",
1198                                           action->node->details->uname,
1199                                           action->node->details->remote_rsc->container->id);
1200         } else if (action->node != NULL) {
1201             node_name = crm_strdup_printf("%s", action->node->details->uname);
1202         }
1203 
1204         out->message(out, "node-action", task, node_name, action->reason);
1205 
1206         free(node_name);
1207         free(task);
1208     }
1209 
1210     
1211     for (GList *iter = data_set->resources; iter != NULL; iter = iter->next) {
1212         pe_resource_t *rsc = (pe_resource_t *) iter->data;
1213 
1214         rsc->cmds->output_actions(rsc);
1215     }
1216 }
1217 
1218 
1219 
1220 
1221 
1222 
1223 
1224 
1225 
1226 
1227 
1228 
1229 static void
1230 schedule_cancel(pe_resource_t *rsc, const char *call_id, const char *task,
     
1231                 guint interval_ms, pe_node_t *node, const char *reason)
1232 {
1233     pe_action_t *cancel = NULL;
1234 
1235     CRM_CHECK((rsc != NULL) && (task != NULL)
1236               && (node != NULL) && (reason != NULL),
1237               return);
1238 
1239     crm_info("Recurring %s-interval %s for %s will be stopped on %s: %s",
1240              pcmk__readable_interval(interval_ms), task, rsc->id,
1241              crm_str(node->details->uname), reason);
1242     cancel = pcmk__new_cancel_action(rsc, task, interval_ms, node);
1243     add_hash_param(cancel->meta, XML_LRM_ATTR_CALLID, call_id);
1244 
1245     
1246     pcmk__new_ordering(rsc, stop_key(rsc), NULL, rsc, NULL, cancel,
1247                        pe_order_optional, rsc->cluster);
1248 }
1249 
1250 
1251 
1252 
1253 
1254 
1255 
1256 
1257 
1258 
1259 
1260 static bool
1261 action_in_config(pe_resource_t *rsc, const char *task, guint interval_ms)
     
1262 {
1263     char *key = pcmk__op_key(rsc->id, task, interval_ms);
1264     bool config = (find_rsc_op_entry(rsc, key) != NULL);
1265 
1266     free(key);
1267     return config;
1268 }
1269 
1270 
1271 
1272 
1273 
1274 
1275 
1276 
1277 
1278 
1279 static const char *
1280 task_for_digest(const char *task, guint interval_ms)
     
1281 {
1282     
1283 
1284 
1285     if ((interval_ms == 0)
1286         && pcmk__str_any_of(task, RSC_STATUS, RSC_MIGRATED, RSC_PROMOTE, NULL)) {
1287         task = RSC_START;
1288     }
1289     return task;
1290 }
1291 
1292 
1293 
1294 
1295 
1296 
1297 
1298 
1299 
1300 
1301 
1302 
1303 
1304 
1305 
1306 
1307 
1308 
1309 static bool
1310 only_sanitized_changed(xmlNode *xml_op, const op_digest_cache_t *digest_data,
     
1311                        pe_working_set_t *data_set)
1312 {
1313     const char *digest_secure = NULL;
1314 
1315     if (!pcmk_is_set(data_set->flags, pe_flag_sanitized)) {
1316         
1317         return false;
1318     }
1319 
1320     digest_secure = crm_element_value(xml_op, XML_LRM_ATTR_SECURE_DIGEST);
1321 
1322     return (digest_data->rc != RSC_DIGEST_MATCH) && (digest_secure != NULL)
1323            && (digest_data->digest_secure_calc != NULL)
1324            && (strcmp(digest_data->digest_secure_calc, digest_secure) == 0);
1325 }
1326 
1327 
1328 
1329 
1330 
1331 
1332 
1333 
1334 
1335 
1336 static void
1337 force_restart(pe_resource_t *rsc, const char *task, guint interval_ms,
     
1338               pe_node_t *node)
1339 {
1340     char *key = pcmk__op_key(rsc->id, task, interval_ms);
1341     pe_action_t *required = custom_action(rsc, key, task, NULL, FALSE, TRUE,
1342                                           rsc->cluster);
1343 
1344     pe_action_set_reason(required, "resource definition change", true);
1345     trigger_unfencing(rsc, node, "Device parameters changed", NULL,
1346                       rsc->cluster);
1347 }
1348 
1349 
1350 
1351 
1352 
1353 
1354 
1355 
1356 
1357 
1358 static void
1359 reschedule_recurring(pe_resource_t *rsc, const char *task, guint interval_ms,
     
1360                      pe_node_t *node)
1361 {
1362     pe_action_t *op = NULL;
1363 
1364     trigger_unfencing(rsc, node, "Device parameters changed (reschedule)",
1365                       NULL, rsc->cluster);
1366     op = custom_action(rsc, pcmk__op_key(rsc->id, task, interval_ms),
1367                        task, node, TRUE, TRUE, rsc->cluster);
1368     pe__set_action_flags(op, pe_action_reschedule);
1369 }
1370 
1371 
1372 
1373 
1374 
1375 
1376 
1377 
1378 static void
1379 schedule_reload(pe_resource_t *rsc, pe_node_t *node)
     
1380 {
1381     pe_action_t *reload = NULL;
1382 
1383     
1384     if (rsc->variant > pe_native) {
1385         g_list_foreach(rsc->children, (GFunc) schedule_reload, node);
1386         return;
1387     }
1388 
1389     
1390     if ((node == NULL)
1391         || !pcmk_is_set(rsc->flags, pe_rsc_managed)
1392         || pcmk_is_set(rsc->flags, pe_rsc_failed)) {
1393         pe_rsc_trace(rsc, "Skip reload of %s:%s%s %s",
1394                      rsc->id,
1395                      pcmk_is_set(rsc->flags, pe_rsc_managed)? "" : " unmanaged",
1396                      pcmk_is_set(rsc->flags, pe_rsc_failed)? " failed" : "",
1397                      (node == NULL)? "inactive" : node->details->uname);
1398         return;
1399     }
1400 
1401     
1402 
1403 
1404     if (pcmk_is_set(rsc->flags, pe_rsc_start_pending)) {
1405         pe_rsc_trace(rsc, "%s: preventing agent reload because start pending",
1406                      rsc->id);
1407         custom_action(rsc, stop_key(rsc), CRMD_ACTION_STOP, node, FALSE, TRUE,
1408                       rsc->cluster);
1409         return;
1410     }
1411 
1412     
1413     pe__set_resource_flags(rsc, pe_rsc_reload);
1414     reload = custom_action(rsc, reload_key(rsc), CRMD_ACTION_RELOAD_AGENT, node,
1415                            FALSE, TRUE, rsc->cluster);
1416     pe_action_set_reason(reload, "resource definition change", FALSE);
1417 
1418     
1419     pcmk__new_ordering(NULL, NULL, reload, rsc, stop_key(rsc), NULL,
1420                        pe_order_optional|pe_order_then_cancels_first,
1421                        rsc->cluster);
1422     pcmk__new_ordering(NULL, NULL, reload, rsc, demote_key(rsc), NULL,
1423                        pe_order_optional|pe_order_then_cancels_first,
1424                        rsc->cluster);
1425 }
1426 
1427 
1428 
1429 
1430 
1431 
1432 
1433 
1434 
1435 
1436 
1437 
1438 
1439 
1440 
1441 bool
1442 pcmk__check_action_config(pe_resource_t *rsc, pe_node_t *node, xmlNode *xml_op)
     
1443 {
1444     guint interval_ms = 0;
1445     const char *task = NULL;
1446     const op_digest_cache_t *digest_data = NULL;
1447 
1448     CRM_CHECK((rsc != NULL) && (node != NULL) && (xml_op != NULL),
1449               return false);
1450 
1451     task = crm_element_value(xml_op, XML_LRM_ATTR_TASK);
1452     CRM_CHECK(task != NULL, return false);
1453 
1454     crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms);
1455 
1456     
1457     if (interval_ms > 0) {
1458         if (action_in_config(rsc, task, interval_ms)) {
1459             pe_rsc_trace(rsc, "%s-interval %s for %s on %s is in configuration",
1460                          pcmk__readable_interval(interval_ms), task, rsc->id,
1461                          node->details->uname);
1462         } else if (pcmk_is_set(rsc->cluster->flags,
1463                                pe_flag_stop_action_orphans)) {
1464             schedule_cancel(rsc,
1465                             crm_element_value(xml_op, XML_LRM_ATTR_CALLID),
1466                             task, interval_ms, node, "orphan");
1467             return true;
1468         } else {
1469             pe_rsc_debug(rsc, "%s-interval %s for %s on %s is orphaned",
1470                          pcmk__readable_interval(interval_ms), task, rsc->id,
1471                          node->details->uname);
1472             return true;
1473         }
1474     }
1475 
1476     crm_trace("Checking %s-interval %s for %s on %s for configuration changes",
1477               pcmk__readable_interval(interval_ms), task, rsc->id,
1478               node->details->uname);
1479     task = task_for_digest(task, interval_ms);
1480     digest_data = rsc_action_digest_cmp(rsc, xml_op, node, rsc->cluster);
1481 
1482     if (only_sanitized_changed(xml_op, digest_data, rsc->cluster)) {
1483         if (!pcmk__is_daemon && (rsc->cluster->priv != NULL)) {
1484             pcmk__output_t *out = rsc->cluster->priv;
1485 
1486             out->info(out,
1487                       "Only 'private' parameters to %s-interval %s for %s "
1488                       "on %s changed: %s",
1489                       pcmk__readable_interval(interval_ms), task, rsc->id,
1490                       node->details->uname,
1491                       crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC));
1492         }
1493         return false;
1494     }
1495 
1496     switch (digest_data->rc) {
1497         case RSC_DIGEST_RESTART:
1498             crm_log_xml_debug(digest_data->params_restart, "params:restart");
1499             force_restart(rsc, task, interval_ms, node);
1500             return true;
1501 
1502         case RSC_DIGEST_ALL:
1503         case RSC_DIGEST_UNKNOWN:
1504             
1505 
1506             if (interval_ms > 0) {
1507                 
1508 
1509 
1510 
1511                 crm_log_xml_debug(digest_data->params_all, "params:reschedule");
1512                 reschedule_recurring(rsc, task, interval_ms, node);
1513 
1514             } else if (crm_element_value(xml_op,
1515                                          XML_LRM_ATTR_RESTART_DIGEST) != NULL) {
1516                 
1517                 trigger_unfencing(rsc, node,
1518                                   "Device parameters changed (reload)", NULL,
1519                                   rsc->cluster);
1520                 crm_log_xml_debug(digest_data->params_all, "params:reload");
1521                 schedule_reload(rsc, node);
1522 
1523             } else {
1524                 pe_rsc_trace(rsc,
1525                              "Restarting %s because agent doesn't support reload",
1526                              rsc->id);
1527                 crm_log_xml_debug(digest_data->params_restart,
1528                                   "params:restart");
1529                 force_restart(rsc, task, interval_ms, node);
1530             }
1531             return true;
1532 
1533         default:
1534             break;
1535     }
1536     return false;
1537 }
1538 
1539 
1540 
1541 
1542 
1543 
1544 
1545 
1546 
1547 
1548 static GList *
1549 rsc_history_as_list(pe_resource_t *rsc, xmlNode *rsc_entry,
     
1550                     int *start_index, int *stop_index)
1551 {
1552     GList *ops = NULL;
1553 
1554     for (xmlNode *rsc_op = first_named_child(rsc_entry, XML_LRM_TAG_RSC_OP);
1555          rsc_op != NULL; rsc_op = crm_next_same_xml(rsc_op)) {
1556         ops = g_list_prepend(ops, rsc_op);
1557     }
1558     ops = g_list_sort(ops, sort_op_by_callid);
1559     calculate_active_ops(ops, start_index, stop_index);
1560     return ops;
1561 }
1562 
1563 
1564 
1565 
1566 
1567 
1568 
1569 
1570 
1571 
1572 
1573 
1574 
1575 
1576 
1577 static void
1578 process_rsc_history(xmlNode *rsc_entry, pe_resource_t *rsc, pe_node_t *node)
     
1579 {
1580     int offset = -1;
1581     int stop_index = 0;
1582     int start_index = 0;
1583     GList *sorted_op_list = NULL;
1584 
1585     if (pcmk_is_set(rsc->flags, pe_rsc_orphan)) {
1586         if (pe_rsc_is_anon_clone(uber_parent(rsc))) {
1587             pe_rsc_trace(rsc,
1588                          "Skipping configuration check "
1589                          "for orphaned clone instance %s",
1590                          rsc->id);
1591         } else {
1592             pe_rsc_trace(rsc,
1593                          "Skipping configuration check and scheduling clean-up "
1594                          "for orphaned resource %s", rsc->id);
1595             DeleteRsc(rsc, node, FALSE, rsc->cluster);
1596         }
1597         return;
1598     }
1599 
1600     if (pe_find_node_id(rsc->running_on, node->details->id) == NULL) {
1601         if (pcmk__rsc_agent_changed(rsc, node, rsc_entry, false)) {
1602             DeleteRsc(rsc, node, FALSE, rsc->cluster);
1603         }
1604         pe_rsc_trace(rsc,
1605                      "Skipping configuration check for %s "
1606                      "because no longer active on %s",
1607                      rsc->id, node->details->uname);
1608         return;
1609     }
1610 
1611     pe_rsc_trace(rsc, "Checking for configuration changes for %s on %s",
1612                  rsc->id, node->details->uname);
1613 
1614     if (pcmk__rsc_agent_changed(rsc, node, rsc_entry, true)) {
1615         DeleteRsc(rsc, node, FALSE, rsc->cluster);
1616     }
1617 
1618     sorted_op_list = rsc_history_as_list(rsc, rsc_entry, &start_index,
1619                                          &stop_index);
1620     if (start_index < stop_index) {
1621         return; 
1622     }
1623 
1624     for (GList *iter = sorted_op_list; iter != NULL; iter = iter->next) {
1625         xmlNode *rsc_op = (xmlNode *) iter->data;
1626         const char *task = NULL;
1627         guint interval_ms = 0;
1628 
1629         if (++offset < start_index) {
1630             
1631             continue;
1632         }
1633 
1634         task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK);
1635         crm_element_value_ms(rsc_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms);
1636 
1637         if ((interval_ms > 0)
1638             && (pcmk_is_set(rsc->flags, pe_rsc_maintenance)
1639                 || node->details->maintenance)) {
1640             
1641             schedule_cancel(rsc,
1642                             crm_element_value(rsc_op, XML_LRM_ATTR_CALLID),
1643                             task, interval_ms, node, "maintenance mode");
1644 
1645         } else if ((interval_ms > 0)
1646                    || pcmk__strcase_any_of(task, RSC_STATUS, RSC_START,
1647                                            RSC_PROMOTE, RSC_MIGRATED, NULL)) {
1648             
1649 
1650 
1651 
1652             if (pe__bundle_needs_remote_name(rsc, rsc->cluster)) {
1653                 
1654 
1655 
1656 
1657 
1658 
1659 
1660                 pe__add_param_check(rsc_op, rsc, node, pe_check_active,
1661                                     rsc->cluster);
1662 
1663             } else if (pcmk__check_action_config(rsc, node, rsc_op)
1664                        && (pe_get_failcount(node, rsc, NULL, pe_fc_effective,
1665                                             NULL, rsc->cluster) != 0)) {
1666                 pe__clear_failcount(rsc, node, "action definition changed",
1667                                     rsc->cluster);
1668             }
1669         }
1670     }
1671     g_list_free(sorted_op_list);
1672 }
1673 
1674 
1675 
1676 
1677 
1678 
1679 
1680 
1681 
1682 
1683 
1684 
1685 
1686 
1687 
1688 static void
1689 process_node_history(pe_node_t *node, xmlNode *lrm_rscs, pe_working_set_t *data_set)
     
1690 {
1691     crm_trace("Processing history for node %s", node->details->uname);
1692     for (xmlNode *rsc_entry = first_named_child(lrm_rscs, XML_LRM_TAG_RESOURCE);
1693          rsc_entry != NULL; rsc_entry = crm_next_same_xml(rsc_entry)) {
1694 
1695         if (xml_has_children(rsc_entry)) {
1696             GList *result = pcmk__rscs_matching_id(ID(rsc_entry), data_set);
1697 
1698             for (GList *iter = result; iter != NULL; iter = iter->next) {
1699                 pe_resource_t *rsc = (pe_resource_t *) iter->data;
1700 
1701                 if (rsc->variant == pe_native) {
1702                     process_rsc_history(rsc_entry, rsc, node);
1703                 }
1704             }
1705             g_list_free(result);
1706         }
1707     }
1708 }
1709 
1710 
1711 #define XPATH_NODE_HISTORY "/" XML_TAG_CIB "/" XML_CIB_TAG_STATUS             \
1712                            "/" XML_CIB_TAG_STATE "[@" XML_ATTR_UNAME "='%s']" \
1713                            "/" XML_CIB_TAG_LRM "/" XML_LRM_TAG_RESOURCES
1714 
1715 
1716 
1717 
1718 
1719 
1720 
1721 
1722 
1723 
1724 
1725 
1726 
1727 void
1728 pcmk__handle_rsc_config_changes(pe_working_set_t *data_set)
     
1729 {
1730     crm_trace("Check resource and action configuration for changes");
1731 
1732     
1733 
1734 
1735 
1736     for (GList *iter = data_set->nodes; iter != NULL; iter = iter->next) {
1737         pe_node_t *node = (pe_node_t *) iter->data;
1738 
1739         
1740 
1741 
1742 
1743         if (node->details->maintenance || pcmk__node_available(node)) {
1744             char *xpath = NULL;
1745             xmlNode *history = NULL;
1746 
1747             xpath = crm_strdup_printf(XPATH_NODE_HISTORY, node->details->uname);
1748             history = get_xpath_object(xpath, data_set->input, LOG_NEVER);
1749             free(xpath);
1750 
1751             process_node_history(node, history, data_set);
1752         }
1753     }
1754 }