This source file includes following definitions.
- sorted_allowed_nodes
- assign_best_node
- apply_this_with
- remote_connection_assigned
- pcmk__primitive_assign
- schedule_restart_actions
- set_default_next_role
- create_pending_start
- schedule_role_transition_actions
- pcmk__primitive_create_actions
- rsc_avoids_remote_nodes
- allowed_nodes_as_list
- pcmk__primitive_internal_constraints
- pcmk__primitive_apply_coloc_score
- pcmk__with_primitive_colocations
- pcmk__primitive_with_colocations
- pcmk__primitive_action_flags
- is_expected_node
- stop_resource
- start_resource
- promote_resource
- demote_resource
- assert_role_error
- pcmk__schedule_cleanup
- pcmk__primitive_add_graph_meta
- pcmk__primitive_add_utilization
- shutdown_time
- ban_if_not_locked
- pcmk__primitive_shutdown_lock
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <stdbool.h>
  13 
  14 #include <crm/msg_xml.h>
  15 #include <pacemaker-internal.h>
  16 
  17 #include "libpacemaker_private.h"
  18 
  19 static void stop_resource(pe_resource_t *rsc, pe_node_t *node, bool optional);
  20 static void start_resource(pe_resource_t *rsc, pe_node_t *node, bool optional);
  21 static void demote_resource(pe_resource_t *rsc, pe_node_t *node, bool optional);
  22 static void promote_resource(pe_resource_t *rsc, pe_node_t *node,
  23                              bool optional);
  24 static void assert_role_error(pe_resource_t *rsc, pe_node_t *node,
  25                               bool optional);
  26 
  27 static enum rsc_role_e rsc_state_matrix[RSC_ROLE_MAX][RSC_ROLE_MAX] = {
  28     
  29 
  30 
  31 
  32 
  33 
  34 
  35 
  36 
  37            { RSC_ROLE_UNKNOWN,     
  38                           RSC_ROLE_STOPPED,     
  39                           RSC_ROLE_STOPPED,     
  40                           RSC_ROLE_STOPPED,     
  41                           RSC_ROLE_STOPPED,     
  42                         },
  43            { RSC_ROLE_STOPPED,     
  44                           RSC_ROLE_STOPPED,     
  45                           RSC_ROLE_STARTED,     
  46                           RSC_ROLE_UNPROMOTED,  
  47                           RSC_ROLE_UNPROMOTED,  
  48                         },
  49            { RSC_ROLE_STOPPED,     
  50                           RSC_ROLE_STOPPED,     
  51                           RSC_ROLE_STARTED,     
  52                           RSC_ROLE_UNPROMOTED,  
  53                           RSC_ROLE_PROMOTED,    
  54                         },
  55         { RSC_ROLE_STOPPED,     
  56                           RSC_ROLE_STOPPED,     
  57                           RSC_ROLE_STOPPED,     
  58                           RSC_ROLE_UNPROMOTED,  
  59                           RSC_ROLE_PROMOTED,    
  60                         },
  61          { RSC_ROLE_STOPPED,     
  62                           RSC_ROLE_UNPROMOTED,  
  63                           RSC_ROLE_UNPROMOTED,  
  64                           RSC_ROLE_UNPROMOTED,  
  65                           RSC_ROLE_PROMOTED,    
  66                         },
  67 };
  68 
  69 
  70 
  71 
  72 
  73 
  74 
  75 
  76 
  77 typedef void (*rsc_transition_fn)(pe_resource_t *rsc, pe_node_t *node,
  78                                   bool optional);
  79 
  80 static rsc_transition_fn rsc_action_matrix[RSC_ROLE_MAX][RSC_ROLE_MAX] = {
  81     
  82 
  83 
  84 
  85 
  86 
  87            {   assert_role_error,              
  88                             stop_resource,                  
  89                             assert_role_error,              
  90                             assert_role_error,              
  91                             assert_role_error,              
  92                         },
  93            {   assert_role_error,              
  94                             NULL,                           
  95                             start_resource,                 
  96                             start_resource,                 
  97                             assert_role_error,              
  98                         },
  99            {   assert_role_error,              
 100                             stop_resource,                  
 101                             NULL,                           
 102                             NULL,                           
 103                             promote_resource,               
 104                         },
 105         {   assert_role_error,              
 106                             stop_resource,                  
 107                             stop_resource,                  
 108                             NULL,                           
 109                             promote_resource,               
 110                         },
 111          {   assert_role_error,              
 112                             demote_resource,                
 113                             demote_resource,                
 114                             demote_resource,                
 115                             NULL,                           
 116                         },
 117 };
 118 
 119 
 120 
 121 
 122 
 123 
 124 
 125 
 126 
 127 static GList *
 128 sorted_allowed_nodes(const pe_resource_t *rsc)
     
 129 {
 130     if (rsc->allowed_nodes != NULL) {
 131         GList *nodes = g_hash_table_get_values(rsc->allowed_nodes);
 132 
 133         if (nodes != NULL) {
 134             return pcmk__sort_nodes(nodes, pe__current_node(rsc));
 135         }
 136     }
 137     return NULL;
 138 }
 139 
 140 
 141 
 142 
 143 
 144 
 145 
 146 
 147 
 148 
 149 static bool
 150 assign_best_node(pe_resource_t *rsc, const pe_node_t *prefer)
     
 151 {
 152     GList *nodes = NULL;
 153     pe_node_t *chosen = NULL;
 154     pe_node_t *best = NULL;
 155     bool result = false;
 156     const pe_node_t *most_free_node = pcmk__ban_insufficient_capacity(rsc);
 157 
 158     if (prefer == NULL) {
 159         prefer = most_free_node;
 160     }
 161 
 162     if (!pcmk_is_set(rsc->flags, pe_rsc_provisional)) {
 163         
 164         return rsc->allocated_to != NULL;
 165     }
 166 
 167     
 168     nodes = sorted_allowed_nodes(rsc);
 169     if (nodes != NULL) {
 170         best = (pe_node_t *) nodes->data; 
 171     }
 172 
 173     if ((prefer != NULL) && (nodes != NULL)) {
 174         
 175         chosen = g_hash_table_lookup(rsc->allowed_nodes, prefer->details->id);
 176 
 177         if (chosen == NULL) {
 178             pe_rsc_trace(rsc, "Preferred node %s for %s was unknown",
 179                          pe__node_name(prefer), rsc->id);
 180 
 181         
 182 
 183 
 184 
 185 
 186 
 187         } else if (chosen->weight < best->weight) {
 188             pe_rsc_trace(rsc, "Preferred node %s for %s was unsuitable",
 189                          pe__node_name(chosen), rsc->id);
 190             chosen = NULL;
 191 
 192         } else if (!pcmk__node_available(chosen, true, false)) {
 193             pe_rsc_trace(rsc, "Preferred node %s for %s was unavailable",
 194                          pe__node_name(chosen), rsc->id);
 195             chosen = NULL;
 196 
 197         } else {
 198             pe_rsc_trace(rsc,
 199                          "Chose preferred node %s for %s (ignoring %d candidates)",
 200                          pe__node_name(chosen), rsc->id, g_list_length(nodes));
 201         }
 202     }
 203 
 204     if ((chosen == NULL) && (best != NULL)) {
 205         
 206 
 207 
 208 
 209         chosen = best;
 210 
 211         if (!pe_rsc_is_unique_clone(rsc->parent)
 212             && (chosen->weight > 0) 
 213             && pcmk__node_available(chosen, false, false)) {
 214             
 215 
 216 
 217 
 218 
 219 
 220 
 221 
 222 
 223             pe_node_t *running = pe__current_node(rsc);
 224 
 225             if (running == NULL) {
 226                 
 227 
 228             } else if (!pcmk__node_available(running, true, false)) {
 229                 pe_rsc_trace(rsc, "Current node for %s (%s) can't run resources",
 230                              rsc->id, pe__node_name(running));
 231 
 232             } else {
 233                 int nodes_with_best_score = 1;
 234 
 235                 for (GList *iter = nodes->next; iter; iter = iter->next) {
 236                     pe_node_t *allowed = (pe_node_t *) iter->data;
 237 
 238                     if (allowed->weight != chosen->weight) {
 239                         
 240                         break;
 241                     }
 242                     if (pe__same_node(allowed, running)) {
 243                         
 244                         chosen = allowed;
 245                     }
 246                     nodes_with_best_score++;
 247                 }
 248 
 249                 if (nodes_with_best_score > 1) {
 250                     do_crm_log(((chosen->weight >= INFINITY)? LOG_WARNING : LOG_INFO),
 251                                "Chose %s for %s from %d nodes with score %s",
 252                                pe__node_name(chosen), rsc->id,
 253                                nodes_with_best_score,
 254                                pcmk_readable_score(chosen->weight));
 255                 }
 256             }
 257         }
 258 
 259         pe_rsc_trace(rsc, "Chose %s for %s from %d candidates",
 260                      pe__node_name(chosen), rsc->id, g_list_length(nodes));
 261     }
 262 
 263     result = pcmk__finalize_assignment(rsc, chosen, false);
 264     g_list_free(nodes);
 265     return result;
 266 }
 267 
 268 
 269 
 270 
 271 
 272 
 273 
 274 
 275 static void
 276 apply_this_with(gpointer data, gpointer user_data)
     
 277 {
 278     pcmk__colocation_t *colocation = (pcmk__colocation_t *) data;
 279     pe_resource_t *rsc = (pe_resource_t *) user_data;
 280 
 281     GHashTable *archive = NULL;
 282     pe_resource_t *other = colocation->primary;
 283 
 284     
 285     if ((colocation->dependent_role >= RSC_ROLE_PROMOTED)
 286         || ((colocation->score < 0) && (colocation->score > -INFINITY))) {
 287         archive = pcmk__copy_node_table(rsc->allowed_nodes);
 288     }
 289 
 290     if (pcmk_is_set(other->flags, pe_rsc_provisional)) {
 291         pe_rsc_trace(rsc,
 292                      "%s: Assigning colocation %s primary %s first"
 293                      "(score=%d role=%s)",
 294                      rsc->id, colocation->id, other->id,
 295                      colocation->score, role2text(colocation->dependent_role));
 296         other->cmds->assign(other, NULL);
 297     }
 298 
 299     
 300     rsc->cmds->apply_coloc_score(rsc, other, colocation, true);
 301     if ((archive != NULL)
 302         && !pcmk__any_node_available(rsc->allowed_nodes)) {
 303         pe_rsc_info(rsc,
 304                     "%s: Reverting scores from colocation with %s "
 305                     "because no nodes allowed",
 306                     rsc->id, other->id);
 307         g_hash_table_destroy(rsc->allowed_nodes);
 308         rsc->allowed_nodes = archive;
 309         archive = NULL;
 310     }
 311     if (archive != NULL) {
 312         g_hash_table_destroy(archive);
 313     }
 314 }
 315 
 316 
 317 
 318 
 319 
 320 
 321 
 322 static void
 323 remote_connection_assigned(const pe_resource_t *connection)
     
 324 {
 325     pe_node_t *remote_node = pe_find_node(connection->cluster->nodes,
 326                                           connection->id);
 327 
 328     CRM_CHECK(remote_node != NULL, return);
 329 
 330     if ((connection->allocated_to != NULL)
 331         && (connection->next_role != RSC_ROLE_STOPPED)) {
 332 
 333         crm_trace("Pacemaker Remote node %s will be online",
 334                   remote_node->details->id);
 335         remote_node->details->online = TRUE;
 336         if (remote_node->details->unseen) {
 337             
 338             remote_node->details->unclean = FALSE;
 339         }
 340 
 341     } else {
 342         crm_trace("Pacemaker Remote node %s will be shut down "
 343                   "(%sassigned connection's next role is %s)",
 344                   remote_node->details->id,
 345                   ((connection->allocated_to == NULL)? "un" : ""),
 346                   role2text(connection->next_role));
 347         remote_node->details->shutdown = TRUE;
 348     }
 349 }
 350 
 351 
 352 
 353 
 354 
 355 
 356 
 357 
 358 
 359 
 360 pe_node_t *
 361 pcmk__primitive_assign(pe_resource_t *rsc, const pe_node_t *prefer)
     
 362 {
 363     GList *this_with_colocations = NULL;
 364     GList *with_this_colocations = NULL;
 365     GList *iter = NULL;
 366     pcmk__colocation_t *colocation = NULL;
 367 
 368     CRM_ASSERT(rsc != NULL);
 369 
 370     
 371     if ((rsc->parent != NULL)
 372         && !pcmk_is_set(rsc->parent->flags, pe_rsc_allocating)) {
 373         pe_rsc_debug(rsc, "%s: Assigning parent %s first",
 374                      rsc->id, rsc->parent->id);
 375         rsc->parent->cmds->assign(rsc->parent, prefer);
 376     }
 377 
 378     if (!pcmk_is_set(rsc->flags, pe_rsc_provisional)) {
 379         return rsc->allocated_to; 
 380     }
 381 
 382     
 383     if (pcmk_is_set(rsc->flags, pe_rsc_allocating)) {
 384         pe_rsc_debug(rsc, "Breaking assignment loop involving %s", rsc->id);
 385         return NULL;
 386     }
 387     pe__set_resource_flags(rsc, pe_rsc_allocating);
 388 
 389     pe__show_node_weights(true, rsc, "Pre-assignment", rsc->allowed_nodes,
 390                           rsc->cluster);
 391 
 392     this_with_colocations = pcmk__this_with_colocations(rsc);
 393     with_this_colocations = pcmk__with_this_colocations(rsc);
 394 
 395     
 396     for (iter = this_with_colocations; iter != NULL; iter = iter->next) {
 397         colocation = iter->data;
 398         if ((colocation->score <= -CRM_SCORE_INFINITY)
 399             || (colocation->score >= CRM_SCORE_INFINITY)) {
 400             apply_this_with(iter->data, rsc);
 401         }
 402     }
 403     for (iter = with_this_colocations; iter != NULL; iter = iter->next) {
 404         colocation = iter->data;
 405         if ((colocation->score <= -CRM_SCORE_INFINITY)
 406             || (colocation->score >= CRM_SCORE_INFINITY)) {
 407             pcmk__add_dependent_scores(iter->data, rsc);
 408         }
 409     }
 410 
 411     pe__show_node_weights(true, rsc, "Mandatory-colocations",
 412                           rsc->allowed_nodes, rsc->cluster);
 413 
 414     
 415     for (iter = this_with_colocations; iter != NULL; iter = iter->next) {
 416         colocation = iter->data;
 417 
 418         if ((colocation->score > -CRM_SCORE_INFINITY)
 419             && (colocation->score < CRM_SCORE_INFINITY)) {
 420             apply_this_with(iter->data, rsc);
 421         }
 422     }
 423     for (iter = with_this_colocations; iter != NULL; iter = iter->next) {
 424         colocation = iter->data;
 425 
 426         if ((colocation->score > -CRM_SCORE_INFINITY)
 427             && (colocation->score < CRM_SCORE_INFINITY)) {
 428             pcmk__add_dependent_scores(iter->data, rsc);
 429         }
 430     }
 431 
 432     g_list_free(this_with_colocations);
 433     g_list_free(with_this_colocations);
 434 
 435     if (rsc->next_role == RSC_ROLE_STOPPED) {
 436         pe_rsc_trace(rsc,
 437                      "Banning %s from all nodes because it will be stopped",
 438                      rsc->id);
 439         resource_location(rsc, NULL, -INFINITY, XML_RSC_ATTR_TARGET_ROLE,
 440                           rsc->cluster);
 441 
 442     } else if ((rsc->next_role > rsc->role)
 443                && !pcmk_is_set(rsc->cluster->flags, pe_flag_have_quorum)
 444                && (rsc->cluster->no_quorum_policy == no_quorum_freeze)) {
 445         crm_notice("Resource %s cannot be elevated from %s to %s due to "
 446                    "no-quorum-policy=freeze",
 447                    rsc->id, role2text(rsc->role), role2text(rsc->next_role));
 448         pe__set_next_role(rsc, rsc->role, "no-quorum-policy=freeze");
 449     }
 450 
 451     pe__show_node_weights(!pcmk_is_set(rsc->cluster->flags, pe_flag_show_scores),
 452                           rsc, __func__, rsc->allowed_nodes, rsc->cluster);
 453 
 454     
 455     if (pcmk_is_set(rsc->cluster->flags, pe_flag_stonith_enabled)
 456         && !pcmk_is_set(rsc->cluster->flags, pe_flag_have_stonith_resource)) {
 457         pe__clear_resource_flags(rsc, pe_rsc_managed);
 458     }
 459 
 460     if (!pcmk_is_set(rsc->flags, pe_rsc_managed)) {
 461         
 462         const char *reason = NULL;
 463         pe_node_t *assign_to = NULL;
 464 
 465         pe__set_next_role(rsc, rsc->role, "unmanaged");
 466         assign_to = pe__current_node(rsc);
 467         if (assign_to == NULL) {
 468             reason = "inactive";
 469         } else if (rsc->role == RSC_ROLE_PROMOTED) {
 470             reason = "promoted";
 471         } else if (pcmk_is_set(rsc->flags, pe_rsc_failed)) {
 472             reason = "failed";
 473         } else {
 474             reason = "active";
 475         }
 476         pe_rsc_info(rsc, "Unmanaged resource %s assigned to %s: %s", rsc->id,
 477                     (assign_to? assign_to->details->uname : "no node"), reason);
 478         pcmk__finalize_assignment(rsc, assign_to, true);
 479 
 480     } else if (pcmk_is_set(rsc->cluster->flags, pe_flag_stop_everything)) {
 481         pe_rsc_debug(rsc, "Forcing %s to stop: stop-all-resources", rsc->id);
 482         pcmk__finalize_assignment(rsc, NULL, true);
 483 
 484     } else if (pcmk_is_set(rsc->flags, pe_rsc_provisional)
 485                && assign_best_node(rsc, prefer)) {
 486         
 487 
 488     } else if (rsc->allocated_to == NULL) {
 489         if (!pcmk_is_set(rsc->flags, pe_rsc_orphan)) {
 490             pe_rsc_info(rsc, "Resource %s cannot run anywhere", rsc->id);
 491         } else if (rsc->running_on != NULL) {
 492             pe_rsc_info(rsc, "Stopping orphan resource %s", rsc->id);
 493         }
 494 
 495     } else {
 496         pe_rsc_debug(rsc, "%s: pre-assigned to %s", rsc->id,
 497                      pe__node_name(rsc->allocated_to));
 498     }
 499 
 500     pe__clear_resource_flags(rsc, pe_rsc_allocating);
 501 
 502     if (rsc->is_remote_node) {
 503         remote_connection_assigned(rsc);
 504     }
 505 
 506     return rsc->allocated_to;
 507 }
 508 
 509 
 510 
 511 
 512 
 513 
 514 
 515 
 516 
 517 
 518 
 519 
 520 static void
 521 schedule_restart_actions(pe_resource_t *rsc, pe_node_t *current,
     
 522                          bool need_stop, bool need_promote)
 523 {
 524     enum rsc_role_e role = rsc->role;
 525     enum rsc_role_e next_role;
 526     rsc_transition_fn fn = NULL;
 527 
 528     pe__set_resource_flags(rsc, pe_rsc_restarting);
 529 
 530     
 531     while (role != RSC_ROLE_STOPPED) {
 532         next_role = rsc_state_matrix[role][RSC_ROLE_STOPPED];
 533         pe_rsc_trace(rsc, "Creating %s action to take %s down from %s to %s",
 534                      (need_stop? "required" : "optional"), rsc->id,
 535                      role2text(role), role2text(next_role));
 536         fn = rsc_action_matrix[role][next_role];
 537         if (fn == NULL) {
 538             break;
 539         }
 540         fn(rsc, current, !need_stop);
 541         role = next_role;
 542     }
 543 
 544     
 545     while ((rsc->role <= rsc->next_role) && (role != rsc->role)
 546            && !pcmk_is_set(rsc->flags, pe_rsc_block)) {
 547         bool required = need_stop;
 548 
 549         next_role = rsc_state_matrix[role][rsc->role];
 550         if ((next_role == RSC_ROLE_PROMOTED) && need_promote) {
 551             required = true;
 552         }
 553         pe_rsc_trace(rsc, "Creating %s action to take %s up from %s to %s",
 554                      (required? "required" : "optional"), rsc->id,
 555                      role2text(role), role2text(next_role));
 556         fn = rsc_action_matrix[role][next_role];
 557         if (fn == NULL) {
 558             break;
 559         }
 560         fn(rsc, rsc->allocated_to, !required);
 561         role = next_role;
 562     }
 563 
 564     pe__clear_resource_flags(rsc, pe_rsc_restarting);
 565 }
 566 
 567 
 568 
 569 
 570 
 571 
 572 
 573 
 574 
 575 static const char *
 576 set_default_next_role(pe_resource_t *rsc)
     
 577 {
 578     if (rsc->next_role != RSC_ROLE_UNKNOWN) {
 579         return "explicit";
 580     }
 581 
 582     if (rsc->allocated_to == NULL) {
 583         pe__set_next_role(rsc, RSC_ROLE_STOPPED, "assignment");
 584     } else {
 585         pe__set_next_role(rsc, RSC_ROLE_STARTED, "assignment");
 586     }
 587     return "implicit";
 588 }
 589 
 590 
 591 
 592 
 593 
 594 
 595 
 596 static void
 597 create_pending_start(pe_resource_t *rsc)
     
 598 {
 599     pe_action_t *start = NULL;
 600 
 601     pe_rsc_trace(rsc,
 602                  "Creating action for %s to represent already pending start",
 603                  rsc->id);
 604     start = start_action(rsc, rsc->allocated_to, TRUE);
 605     pe__set_action_flags(start, pe_action_print_always);
 606 }
 607 
 608 
 609 
 610 
 611 
 612 
 613 
 614 static void
 615 schedule_role_transition_actions(pe_resource_t *rsc)
     
 616 {
 617     enum rsc_role_e role = rsc->role;
 618 
 619     while (role != rsc->next_role) {
 620         enum rsc_role_e next_role = rsc_state_matrix[role][rsc->next_role];
 621         rsc_transition_fn fn = NULL;
 622 
 623         pe_rsc_trace(rsc,
 624                      "Creating action to take %s from %s to %s (ending at %s)",
 625                      rsc->id, role2text(role), role2text(next_role),
 626                      role2text(rsc->next_role));
 627         fn = rsc_action_matrix[role][next_role];
 628         if (fn == NULL) {
 629             break;
 630         }
 631         fn(rsc, rsc->allocated_to, false);
 632         role = next_role;
 633     }
 634 }
 635 
 636 
 637 
 638 
 639 
 640 
 641 
 642 void
 643 pcmk__primitive_create_actions(pe_resource_t *rsc)
     
 644 {
 645     bool need_stop = false;
 646     bool need_promote = false;
 647     bool is_moving = false;
 648     bool allow_migrate = false;
 649     bool multiply_active = false;
 650 
 651     pe_node_t *current = NULL;
 652     unsigned int num_all_active = 0;
 653     unsigned int num_clean_active = 0;
 654     const char *next_role_source = NULL;
 655 
 656     CRM_ASSERT(rsc != NULL);
 657 
 658     next_role_source = set_default_next_role(rsc);
 659     pe_rsc_trace(rsc,
 660                  "Creating all actions for %s transition from %s to %s "
 661                  "(%s) on %s",
 662                  rsc->id, role2text(rsc->role), role2text(rsc->next_role),
 663                  next_role_source, pe__node_name(rsc->allocated_to));
 664 
 665     current = rsc->fns->active_node(rsc, &num_all_active, &num_clean_active);
 666 
 667     g_list_foreach(rsc->dangling_migrations, pcmk__abort_dangling_migration,
 668                    rsc);
 669 
 670     if ((current != NULL) && (rsc->allocated_to != NULL)
 671         && (current->details != rsc->allocated_to->details)
 672         && (rsc->next_role >= RSC_ROLE_STARTED)) {
 673 
 674         pe_rsc_trace(rsc, "Moving %s from %s to %s",
 675                      rsc->id, pe__node_name(current),
 676                      pe__node_name(rsc->allocated_to));
 677         is_moving = true;
 678         allow_migrate = pcmk__rsc_can_migrate(rsc, current);
 679 
 680         
 681         need_stop = true;
 682     }
 683 
 684     
 685     if ((rsc->partial_migration_source != NULL)
 686         && (rsc->partial_migration_target != NULL)
 687         && allow_migrate && (num_all_active == 2)
 688         && pe__same_node(current, rsc->partial_migration_source)
 689         && pe__same_node(rsc->allocated_to, rsc->partial_migration_target)) {
 690         
 691 
 692 
 693         pe_rsc_trace(rsc, "Partial migration of %s from %s to %s will continue",
 694                      rsc->id, pe__node_name(rsc->partial_migration_source),
 695                      pe__node_name(rsc->partial_migration_target));
 696 
 697     } else if ((rsc->partial_migration_source != NULL)
 698                || (rsc->partial_migration_target != NULL)) {
 699         
 700 
 701         if (num_all_active > 2) {
 702             
 703             crm_notice("Forcing recovery of %s because it is migrating "
 704                        "from %s to %s and possibly active elsewhere",
 705                        rsc->id, pe__node_name(rsc->partial_migration_source),
 706                        pe__node_name(rsc->partial_migration_target));
 707         } else {
 708             
 709             crm_notice("Forcing recovery of %s because it can no longer "
 710                        "migrate from %s to %s",
 711                        rsc->id, pe__node_name(rsc->partial_migration_source),
 712                        pe__node_name(rsc->partial_migration_target));
 713         }
 714         need_stop = true;
 715         rsc->partial_migration_source = rsc->partial_migration_target = NULL;
 716         allow_migrate = false;
 717 
 718     } else if (pcmk_is_set(rsc->flags, pe_rsc_needs_fencing)) {
 719         multiply_active = (num_all_active > 1);
 720     } else {
 721         
 722 
 723 
 724 
 725 
 726 
 727 
 728         multiply_active = (num_clean_active > 1);
 729     }
 730 
 731     if (multiply_active) {
 732         const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
 733 
 734         
 735         pe_proc_err("%s resource %s might be active on %u nodes (%s)",
 736                     pcmk__s(class, "Untyped"), rsc->id, num_all_active,
 737                     recovery2text(rsc->recovery_type));
 738         crm_notice("See https://wiki.clusterlabs.org/wiki/FAQ"
 739                    "#Resource_is_Too_Active for more information");
 740 
 741         switch (rsc->recovery_type) {
 742             case recovery_stop_start:
 743                 need_stop = true;
 744                 break;
 745             case recovery_stop_unexpected:
 746                 need_stop = true; 
 747                 pe__set_resource_flags(rsc, pe_rsc_stop_unexpected);
 748                 break;
 749             default:
 750                 break;
 751         }
 752 
 753     } else {
 754         pe__clear_resource_flags(rsc, pe_rsc_stop_unexpected);
 755     }
 756 
 757     if (pcmk_is_set(rsc->flags, pe_rsc_start_pending)) {
 758         create_pending_start(rsc);
 759     }
 760 
 761     if (is_moving) {
 762         
 763 
 764     } else if (pcmk_is_set(rsc->flags, pe_rsc_failed)) {
 765         if (pcmk_is_set(rsc->flags, pe_rsc_stop)) {
 766             need_stop = true;
 767             pe_rsc_trace(rsc, "Recovering %s", rsc->id);
 768         } else {
 769             pe_rsc_trace(rsc, "Recovering %s by demotion", rsc->id);
 770             if (rsc->next_role == RSC_ROLE_PROMOTED) {
 771                 need_promote = true;
 772             }
 773         }
 774 
 775     } else if (pcmk_is_set(rsc->flags, pe_rsc_block)) {
 776         pe_rsc_trace(rsc, "Blocking further actions on %s", rsc->id);
 777         need_stop = true;
 778 
 779     } else if ((rsc->role > RSC_ROLE_STARTED) && (current != NULL)
 780                && (rsc->allocated_to != NULL)) {
 781         pe_action_t *start = NULL;
 782 
 783         pe_rsc_trace(rsc, "Creating start action for promoted resource %s",
 784                      rsc->id);
 785         start = start_action(rsc, rsc->allocated_to, TRUE);
 786         if (!pcmk_is_set(start->flags, pe_action_optional)) {
 787             
 788             pe_rsc_trace(rsc, "%s restart is required for recovery", rsc->id);
 789             need_stop = true;
 790         }
 791     }
 792 
 793     
 794     schedule_restart_actions(rsc, current, need_stop, need_promote);
 795 
 796     
 797     schedule_role_transition_actions(rsc);
 798 
 799     pcmk__create_recurring_actions(rsc);
 800 
 801     if (allow_migrate) {
 802         pcmk__create_migration_actions(rsc, current);
 803     }
 804 }
 805 
 806 
 807 
 808 
 809 
 810 
 811 
 812 static void
 813 rsc_avoids_remote_nodes(const pe_resource_t *rsc)
     
 814 {
 815     GHashTableIter iter;
 816     pe_node_t *node = NULL;
 817 
 818     g_hash_table_iter_init(&iter, rsc->allowed_nodes);
 819     while (g_hash_table_iter_next(&iter, NULL, (void **) &node)) {
 820         if (node->details->remote_rsc != NULL) {
 821             node->weight = -INFINITY;
 822         }
 823     }
 824 }
 825 
 826 
 827 
 828 
 829 
 830 
 831 
 832 
 833 
 834 
 835 
 836 
 837 
 838 
 839 static GList *
 840 allowed_nodes_as_list(const pe_resource_t *rsc)
     
 841 {
 842     GList *allowed_nodes = NULL;
 843 
 844     if (rsc->allowed_nodes) {
 845         allowed_nodes = g_hash_table_get_values(rsc->allowed_nodes);
 846     }
 847 
 848     if (!pcmk__is_daemon) {
 849         allowed_nodes = g_list_sort(allowed_nodes, pe__cmp_node_name);
 850     }
 851 
 852     return allowed_nodes;
 853 }
 854 
 855 
 856 
 857 
 858 
 859 
 860 
 861 void
 862 pcmk__primitive_internal_constraints(pe_resource_t *rsc)
     
 863 {
 864     GList *allowed_nodes = NULL;
 865     bool check_unfencing = false;
 866     bool check_utilization = false;
 867 
 868     CRM_ASSERT(rsc != NULL);
 869 
 870     if (!pcmk_is_set(rsc->flags, pe_rsc_managed)) {
 871         pe_rsc_trace(rsc,
 872                      "Skipping implicit constraints for unmanaged resource %s",
 873                      rsc->id);
 874         return;
 875     }
 876 
 877     
 878     check_unfencing = !pcmk_is_set(rsc->flags, pe_rsc_fence_device)
 879                       && pcmk_is_set(rsc->cluster->flags, pe_flag_enable_unfencing)
 880                       && pcmk_is_set(rsc->flags, pe_rsc_needs_unfencing);
 881 
 882     
 883     check_utilization = (g_hash_table_size(rsc->utilization) > 0)
 884                          && !pcmk__str_eq(rsc->cluster->placement_strategy,
 885                                           "default", pcmk__str_casei);
 886 
 887     
 888     pcmk__new_ordering(rsc, pcmk__op_key(rsc->id, RSC_STOP, 0), NULL,
 889                        rsc, pcmk__op_key(rsc->id, RSC_START, 0), NULL,
 890                        pe_order_optional|pe_order_implies_then|pe_order_restart,
 891                        rsc->cluster);
 892 
 893     
 894     if (pcmk_is_set(pe__const_top_resource(rsc, false)->flags,
 895                     pe_rsc_promotable)
 896         || (rsc->role > RSC_ROLE_UNPROMOTED)) {
 897 
 898         pcmk__new_ordering(rsc, pcmk__op_key(rsc->id, RSC_DEMOTE, 0), NULL,
 899                            rsc, pcmk__op_key(rsc->id, RSC_STOP, 0), NULL,
 900                            pe_order_promoted_implies_first, rsc->cluster);
 901 
 902         pcmk__new_ordering(rsc, pcmk__op_key(rsc->id, RSC_START, 0), NULL,
 903                            rsc, pcmk__op_key(rsc->id, RSC_PROMOTE, 0), NULL,
 904                            pe_order_runnable_left, rsc->cluster);
 905     }
 906 
 907     
 908     pcmk__new_ordering(rsc, pcmk__op_key(rsc->id, CRM_OP_LRM_DELETE, 0),
 909                        NULL, rsc, pcmk__op_key(rsc->id, RSC_STATUS, 0),
 910                        NULL, pe_order_same_node|pe_order_then_cancels_first,
 911                        rsc->cluster);
 912 
 913     
 914     if (check_unfencing || check_utilization || (rsc->container != NULL)) {
 915         allowed_nodes = allowed_nodes_as_list(rsc);
 916     }
 917 
 918     if (check_unfencing) {
 919         g_list_foreach(allowed_nodes, pcmk__order_restart_vs_unfence, rsc);
 920     }
 921 
 922     if (check_utilization) {
 923         pcmk__create_utilization_constraints(rsc, allowed_nodes);
 924     }
 925 
 926     if (rsc->container != NULL) {
 927         pe_resource_t *remote_rsc = NULL;
 928 
 929         if (rsc->is_remote_node) {
 930             
 931 
 932             
 933 
 934 
 935             if (!pcmk_is_set(rsc->flags, pe_rsc_allow_remote_remotes)) {
 936                 rsc_avoids_remote_nodes(rsc->container);
 937             }
 938 
 939             
 940 
 941 
 942 
 943 
 944 
 945             pcmk__order_resource_actions(rsc->container, RSC_STATUS, rsc,
 946                                          RSC_STOP, pe_order_optional);
 947 
 948         
 949 
 950 
 951 
 952 
 953 
 954 
 955         } else if (rsc->container->is_remote_node) {
 956             remote_rsc = rsc->container;
 957         } else  {
 958             remote_rsc = pe__resource_contains_guest_node(rsc->cluster,
 959                                                           rsc->container);
 960         }
 961 
 962         if (remote_rsc != NULL) {
 963             
 964 
 965 
 966             for (GList *item = allowed_nodes; item; item = item->next) {
 967                 pe_node_t *node = item->data;
 968 
 969                 if (node->details->remote_rsc != remote_rsc) {
 970                     node->weight = -INFINITY;
 971                 }
 972             }
 973 
 974         } else {
 975             
 976 
 977 
 978 
 979             int score;
 980 
 981             crm_trace("Order and colocate %s relative to its container %s",
 982                       rsc->id, rsc->container->id);
 983 
 984             pcmk__new_ordering(rsc->container,
 985                                pcmk__op_key(rsc->container->id, RSC_START, 0),
 986                                NULL, rsc, pcmk__op_key(rsc->id, RSC_START, 0),
 987                                NULL,
 988                                pe_order_implies_then|pe_order_runnable_left,
 989                                rsc->cluster);
 990 
 991             pcmk__new_ordering(rsc, pcmk__op_key(rsc->id, RSC_STOP, 0), NULL,
 992                                rsc->container,
 993                                pcmk__op_key(rsc->container->id, RSC_STOP, 0),
 994                                NULL, pe_order_implies_first, rsc->cluster);
 995 
 996             if (pcmk_is_set(rsc->flags, pe_rsc_allow_remote_remotes)) {
 997                 score = 10000;    
 998             } else {
 999                 score = INFINITY; 
1000             }
1001             pcmk__new_colocation("resource-with-container", NULL, score, rsc,
1002                                  rsc->container, NULL, NULL, true,
1003                                  rsc->cluster);
1004         }
1005     }
1006 
1007     if (rsc->is_remote_node || pcmk_is_set(rsc->flags, pe_rsc_fence_device)) {
1008         
1009 
1010 
1011         rsc_avoids_remote_nodes(rsc);
1012     }
1013     g_list_free(allowed_nodes);
1014 }
1015 
1016 
1017 
1018 
1019 
1020 
1021 
1022 
1023 
1024 
1025 
1026 
1027 
1028 
1029 void
1030 pcmk__primitive_apply_coloc_score(pe_resource_t *dependent,
     
1031                                   const pe_resource_t *primary,
1032                                   const pcmk__colocation_t *colocation,
1033                                   bool for_dependent)
1034 {
1035     enum pcmk__coloc_affects filter_results;
1036 
1037     CRM_CHECK((colocation != NULL) && (dependent != NULL) && (primary != NULL),
1038               return);
1039 
1040     if (for_dependent) {
1041         
1042         primary->cmds->apply_coloc_score(dependent, primary, colocation, false);
1043         return;
1044     }
1045 
1046     filter_results = pcmk__colocation_affects(dependent, primary, colocation,
1047                                               false);
1048     pe_rsc_trace(dependent, "%s %s with %s (%s, score=%d, filter=%d)",
1049                  ((colocation->score > 0)? "Colocating" : "Anti-colocating"),
1050                  dependent->id, primary->id, colocation->id, colocation->score,
1051                  filter_results);
1052 
1053     switch (filter_results) {
1054         case pcmk__coloc_affects_role:
1055             pcmk__apply_coloc_to_priority(dependent, primary, colocation);
1056             break;
1057         case pcmk__coloc_affects_location:
1058             pcmk__apply_coloc_to_weights(dependent, primary, colocation);
1059             break;
1060         default: 
1061             return;
1062     }
1063 }
1064 
1065 
1066 
1067 
1068 void
1069 pcmk__with_primitive_colocations(const pe_resource_t *rsc,
     
1070                                  const pe_resource_t *orig_rsc, GList **list)
1071 {
1072     
1073     CRM_CHECK((rsc != NULL) && (rsc->variant == pe_native)
1074               && (rsc == orig_rsc) && (list != NULL),
1075               return);
1076 
1077     
1078     pcmk__add_with_this_list(list, rsc->rsc_cons_lhs);
1079     if (rsc->parent != NULL) {
1080         rsc->parent->cmds->with_this_colocations(rsc->parent, rsc, list);
1081     }
1082 }
1083 
1084 
1085 
1086 
1087 void
1088 pcmk__primitive_with_colocations(const pe_resource_t *rsc,
     
1089                                  const pe_resource_t *orig_rsc, GList **list)
1090 {
1091     
1092     CRM_CHECK((rsc != NULL) && (rsc->variant == pe_native)
1093               && (rsc == orig_rsc) && (list != NULL),
1094               return);
1095 
1096     
1097     pcmk__add_this_with_list(list, rsc->rsc_cons);
1098     if (rsc->parent != NULL) {
1099         rsc->parent->cmds->this_with_colocations(rsc->parent, rsc, list);
1100     }
1101 }
1102 
1103 
1104 
1105 
1106 
1107 
1108 
1109 
1110 
1111 
1112 enum pe_action_flags
1113 pcmk__primitive_action_flags(pe_action_t *action, const pe_node_t *node)
     
1114 {
1115     CRM_ASSERT(action != NULL);
1116     return action->flags;
1117 }
1118 
1119 
1120 
1121 
1122 
1123 
1124 
1125 
1126 
1127 
1128 
1129 
1130 
1131 
1132 static bool
1133 is_expected_node(const pe_resource_t *rsc, const pe_node_t *node)
     
1134 {
1135     return pcmk_all_flags_set(rsc->flags,
1136                               pe_rsc_stop_unexpected|pe_rsc_restarting)
1137            && (rsc->next_role > RSC_ROLE_STOPPED)
1138            && pe__same_node(rsc->allocated_to, node);
1139 }
1140 
1141 
1142 
1143 
1144 
1145 
1146 
1147 
1148 
1149 static void
1150 stop_resource(pe_resource_t *rsc, pe_node_t *node, bool optional)
     
1151 {
1152     for (GList *iter = rsc->running_on; iter != NULL; iter = iter->next) {
1153         pe_node_t *current = (pe_node_t *) iter->data;
1154         pe_action_t *stop = NULL;
1155 
1156         if (is_expected_node(rsc, current)) {
1157             
1158 
1159 
1160 
1161             pe_rsc_trace(rsc,
1162                          "Skipping stop of multiply active resource %s "
1163                          "on expected node %s",
1164                          rsc->id, pe__node_name(current));
1165             continue;
1166         }
1167 
1168         if (rsc->partial_migration_target != NULL) {
1169             
1170             if (pe__same_node(current, rsc->partial_migration_target)
1171                 && pe__same_node(current, rsc->allocated_to)) {
1172                 pe_rsc_trace(rsc,
1173                              "Skipping stop of %s on %s "
1174                              "because partial migration there will continue",
1175                              rsc->id, pe__node_name(current));
1176                 continue;
1177             } else {
1178                 pe_rsc_trace(rsc,
1179                              "Forcing stop of %s on %s "
1180                              "because migration target changed",
1181                              rsc->id, pe__node_name(current));
1182                 optional = false;
1183             }
1184         }
1185 
1186         pe_rsc_trace(rsc, "Scheduling stop of %s on %s",
1187                      rsc->id, pe__node_name(current));
1188         stop = stop_action(rsc, current, optional);
1189 
1190         if (rsc->allocated_to == NULL) {
1191             pe_action_set_reason(stop, "node availability", true);
1192         } else if (pcmk_all_flags_set(rsc->flags, pe_rsc_restarting
1193                                                   |pe_rsc_stop_unexpected)) {
1194             
1195 
1196 
1197 
1198             pe_action_set_reason(stop, "being multiply active", true);
1199         }
1200 
1201         if (!pcmk_is_set(rsc->flags, pe_rsc_managed)) {
1202             pe__clear_action_flags(stop, pe_action_runnable);
1203         }
1204 
1205         if (pcmk_is_set(rsc->cluster->flags, pe_flag_remove_after_stop)) {
1206             pcmk__schedule_cleanup(rsc, current, optional);
1207         }
1208 
1209         if (pcmk_is_set(rsc->flags, pe_rsc_needs_unfencing)) {
1210             pe_action_t *unfence = pe_fence_op(current, "on", true, NULL, false,
1211                                                rsc->cluster);
1212 
1213             order_actions(stop, unfence, pe_order_implies_first);
1214             if (!pcmk__node_unfenced(current)) {
1215                 pe_proc_err("Stopping %s until %s can be unfenced",
1216                             rsc->id, pe__node_name(current));
1217             }
1218         }
1219     }
1220 }
1221 
1222 
1223 
1224 
1225 
1226 
1227 
1228 
1229 
1230 static void
1231 start_resource(pe_resource_t *rsc, pe_node_t *node, bool optional)
     
1232 {
1233     pe_action_t *start = NULL;
1234 
1235     CRM_ASSERT(node != NULL);
1236 
1237     pe_rsc_trace(rsc, "Scheduling %s start of %s on %s (score %d)",
1238                  (optional? "optional" : "required"), rsc->id,
1239                  pe__node_name(node), node->weight);
1240     start = start_action(rsc, node, TRUE);
1241 
1242     pcmk__order_vs_unfence(rsc, node, start, pe_order_implies_then);
1243 
1244     if (pcmk_is_set(start->flags, pe_action_runnable) && !optional) {
1245         pe__clear_action_flags(start, pe_action_optional);
1246     }
1247 
1248     if (is_expected_node(rsc, node)) {
1249         
1250 
1251 
1252         pe_rsc_trace(rsc,
1253                      "Start of multiply active resouce %s "
1254                      "on expected node %s will be a pseudo-action",
1255                      rsc->id, pe__node_name(node));
1256         pe__set_action_flags(start, pe_action_pseudo);
1257     }
1258 }
1259 
1260 
1261 
1262 
1263 
1264 
1265 
1266 
1267 
1268 static void
1269 promote_resource(pe_resource_t *rsc, pe_node_t *node, bool optional)
     
1270 {
1271     GList *iter = NULL;
1272     GList *action_list = NULL;
1273     bool runnable = true;
1274 
1275     CRM_ASSERT(node != NULL);
1276 
1277     
1278     action_list = pe__resource_actions(rsc, node, RSC_START, true);
1279     for (iter = action_list; iter != NULL; iter = iter->next) {
1280         pe_action_t *start = (pe_action_t *) iter->data;
1281 
1282         if (!pcmk_is_set(start->flags, pe_action_runnable)) {
1283             runnable = false;
1284         }
1285     }
1286     g_list_free(action_list);
1287 
1288     if (runnable) {
1289         pe_action_t *promote = promote_action(rsc, node, optional);
1290 
1291         pe_rsc_trace(rsc, "Scheduling %s promotion of %s on %s",
1292                      (optional? "optional" : "required"), rsc->id,
1293                      pe__node_name(node));
1294 
1295         if (is_expected_node(rsc, node)) {
1296             
1297 
1298 
1299             pe_rsc_trace(rsc,
1300                          "Promotion of multiply active resouce %s "
1301                          "on expected node %s will be a pseudo-action",
1302                          rsc->id, pe__node_name(node));
1303             pe__set_action_flags(promote, pe_action_pseudo);
1304         }
1305     } else {
1306         pe_rsc_trace(rsc, "Not promoting %s on %s: start unrunnable",
1307                      rsc->id, pe__node_name(node));
1308         action_list = pe__resource_actions(rsc, node, RSC_PROMOTE, true);
1309         for (iter = action_list; iter != NULL; iter = iter->next) {
1310             pe_action_t *promote = (pe_action_t *) iter->data;
1311 
1312             pe__clear_action_flags(promote, pe_action_runnable);
1313         }
1314         g_list_free(action_list);
1315     }
1316 }
1317 
1318 
1319 
1320 
1321 
1322 
1323 
1324 
1325 
1326 static void
1327 demote_resource(pe_resource_t *rsc, pe_node_t *node, bool optional)
     
1328 {
1329     
1330 
1331 
1332 
1333 
1334     for (GList *iter = rsc->running_on; iter != NULL; iter = iter->next) {
1335         pe_node_t *current = (pe_node_t *) iter->data;
1336 
1337         if (is_expected_node(rsc, current)) {
1338             pe_rsc_trace(rsc,
1339                          "Skipping demote of multiply active resource %s "
1340                          "on expected node %s",
1341                          rsc->id, pe__node_name(current));
1342         } else {
1343             pe_rsc_trace(rsc, "Scheduling %s demotion of %s on %s",
1344                          (optional? "optional" : "required"), rsc->id,
1345                          pe__node_name(current));
1346             demote_action(rsc, current, optional);
1347         }
1348     }
1349 }
1350 
1351 static void
1352 assert_role_error(pe_resource_t *rsc, pe_node_t *node, bool optional)
     
1353 {
1354     CRM_ASSERT(false);
1355 }
1356 
1357 
1358 
1359 
1360 
1361 
1362 
1363 
1364 
1365 void
1366 pcmk__schedule_cleanup(pe_resource_t *rsc, const pe_node_t *node, bool optional)
     
1367 {
1368     
1369 
1370 
1371 
1372 
1373     uint32_t flag = optional? pe_order_implies_then : pe_order_optional;
1374 
1375     CRM_CHECK((rsc != NULL) && (node != NULL), return);
1376 
1377     if (pcmk_is_set(rsc->flags, pe_rsc_failed)) {
1378         pe_rsc_trace(rsc, "Skipping clean-up of %s on %s: resource failed",
1379                      rsc->id, pe__node_name(node));
1380         return;
1381     }
1382 
1383     if (node->details->unclean || !node->details->online) {
1384         pe_rsc_trace(rsc, "Skipping clean-up of %s on %s: node unavailable",
1385                      rsc->id, pe__node_name(node));
1386         return;
1387     }
1388 
1389     crm_notice("Scheduling clean-up of %s on %s", rsc->id, pe__node_name(node));
1390     delete_action(rsc, node, optional);
1391 
1392     
1393     pcmk__order_resource_actions(rsc, RSC_STOP, rsc, RSC_DELETE, flag);
1394     pcmk__order_resource_actions(rsc, RSC_DELETE, rsc, RSC_START, flag);
1395 }
1396 
1397 
1398 
1399 
1400 
1401 
1402 
1403 
1404 void
1405 pcmk__primitive_add_graph_meta(const pe_resource_t *rsc, xmlNode *xml)
     
1406 {
1407     char *name = NULL;
1408     char *value = NULL;
1409     const pe_resource_t *parent = NULL;
1410 
1411     CRM_ASSERT((rsc != NULL) && (xml != NULL));
1412 
1413     
1414 
1415 
1416 
1417     value = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_INCARNATION);
1418     if (value != NULL) {
1419         name = crm_meta_name(XML_RSC_ATTR_INCARNATION);
1420         crm_xml_add(xml, name, value);
1421         free(name);
1422     }
1423 
1424     
1425     value = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_REMOTE_NODE);
1426     if (value != NULL) {
1427         name = crm_meta_name(XML_RSC_ATTR_REMOTE_NODE);
1428         crm_xml_add(xml, name, value);
1429         free(name);
1430     }
1431 
1432     
1433 
1434 
1435 
1436     for (parent = rsc; parent != NULL; parent = parent->parent) {
1437         if (parent->container != NULL) {
1438             crm_xml_add(xml, CRM_META "_" XML_RSC_ATTR_CONTAINER,
1439                         parent->container->id);
1440         }
1441     }
1442 
1443     
1444 
1445 
1446 
1447     value = g_hash_table_lookup(rsc->meta, "external-ip");
1448     if (value != NULL) {
1449         crm_xml_add(xml, "pcmk_external_ip", value);
1450     }
1451 }
1452 
1453 
1454 void
1455 pcmk__primitive_add_utilization(const pe_resource_t *rsc,
     
1456                                 const pe_resource_t *orig_rsc, GList *all_rscs,
1457                                 GHashTable *utilization)
1458 {
1459     if (!pcmk_is_set(rsc->flags, pe_rsc_provisional)) {
1460         return;
1461     }
1462 
1463     pe_rsc_trace(orig_rsc, "%s: Adding primitive %s as colocated utilization",
1464                  orig_rsc->id, rsc->id);
1465     pcmk__release_node_capacity(utilization, rsc);
1466 }
1467 
1468 
1469 
1470 
1471 
1472 
1473 
1474 
1475 
1476 static time_t
1477 shutdown_time(pe_node_t *node)
     
1478 {
1479     const char *shutdown = pe_node_attribute_raw(node, XML_CIB_ATTR_SHUTDOWN);
1480     time_t result = 0;
1481 
1482     if (shutdown != NULL) {
1483         long long result_ll;
1484 
1485         if (pcmk__scan_ll(shutdown, &result_ll, 0LL) == pcmk_rc_ok) {
1486             result = (time_t) result_ll;
1487         }
1488     }
1489     return (result == 0)? get_effective_time(node->details->data_set) : result;
1490 }
1491 
1492 
1493 
1494 
1495 
1496 
1497 
1498 
1499 static void
1500 ban_if_not_locked(gpointer data, gpointer user_data)
     
1501 {
1502     const pe_node_t *node = (const pe_node_t *) data;
1503     pe_resource_t *rsc = (pe_resource_t *) user_data;
1504 
1505     if (strcmp(node->details->uname, rsc->lock_node->details->uname) != 0) {
1506         resource_location(rsc, node, -CRM_SCORE_INFINITY,
1507                           XML_CONFIG_ATTR_SHUTDOWN_LOCK, rsc->cluster);
1508     }
1509 }
1510 
1511 
1512 void
1513 pcmk__primitive_shutdown_lock(pe_resource_t *rsc)
     
1514 {
1515     const char *class = crm_element_value(rsc->xml, XML_AGENT_ATTR_CLASS);
1516 
1517     
1518     if (pcmk__str_eq(class, PCMK_RESOURCE_CLASS_STONITH, pcmk__str_null_matches)
1519         || pe__resource_is_remote_conn(rsc, rsc->cluster)) {
1520         return;
1521     }
1522 
1523     if (rsc->lock_node != NULL) {
1524         
1525 
1526         if (rsc->running_on != NULL) {
1527             
1528 
1529 
1530 
1531             pe_rsc_info(rsc,
1532                         "Cancelling shutdown lock because %s is already active",
1533                         rsc->id);
1534             pe__clear_resource_history(rsc, rsc->lock_node, rsc->cluster);
1535             rsc->lock_node = NULL;
1536             rsc->lock_time = 0;
1537         }
1538 
1539     
1540     } else if (pcmk__list_of_1(rsc->running_on)) {
1541         pe_node_t *node = rsc->running_on->data;
1542 
1543         if (node->details->shutdown) {
1544             if (node->details->unclean) {
1545                 pe_rsc_debug(rsc, "Not locking %s to unclean %s for shutdown",
1546                              rsc->id, pe__node_name(node));
1547             } else {
1548                 rsc->lock_node = node;
1549                 rsc->lock_time = shutdown_time(node);
1550             }
1551         }
1552     }
1553 
1554     if (rsc->lock_node == NULL) {
1555         
1556         return;
1557     }
1558 
1559     if (rsc->cluster->shutdown_lock > 0) {
1560         time_t lock_expiration = rsc->lock_time + rsc->cluster->shutdown_lock;
1561 
1562         pe_rsc_info(rsc, "Locking %s to %s due to shutdown (expires @%lld)",
1563                     rsc->id, pe__node_name(rsc->lock_node),
1564                     (long long) lock_expiration);
1565         pe__update_recheck_time(++lock_expiration, rsc->cluster);
1566     } else {
1567         pe_rsc_info(rsc, "Locking %s to %s due to shutdown",
1568                     rsc->id, pe__node_name(rsc->lock_node));
1569     }
1570 
1571     
1572     g_list_foreach(rsc->cluster->nodes, ban_if_not_locked, rsc);
1573 }