root/daemons/controld/controld_utils.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. controld_is_local_node
  2. controld_get_local_node_status
  3. fsa_input2string
  4. fsa_state2string
  5. fsa_cause2string
  6. fsa_action2string
  7. fsa_dump_inputs
  8. fsa_dump_actions
  9. update_dc
  10. crmd_peer_down
  11. feature_set_compatible
  12. get_node_id

   1 /*
   2  * Copyright 2004-2024 the Pacemaker project contributors
   3  *
   4  * The version control history for this file may have further details.
   5  *
   6  * This source code is licensed under the GNU General Public License version 2
   7  * or later (GPLv2+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <stdlib.h>
  13 #include <stdint.h>                 // uint64_t
  14 
  15 #include <crm/crm.h>
  16 #include <crm/cib.h>
  17 #include <crm/common/xml.h>
  18 
  19 #include <pacemaker-controld.h>
  20 
  21 /*!
  22  * \internal
  23  * \brief Check whether a given name is for the local node
  24  *
  25  * \param[in] name  Name to check
  26  *
  27  * \return true if \p name is the name of the local node, otherwise false
  28  */
  29 bool
  30 controld_is_local_node(const char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
  31 {
  32     CRM_CHECK(controld_globals.cluster != NULL, return false);
  33     return pcmk__str_eq(name, controld_globals.cluster->priv->node_name,
  34                         pcmk__str_casei);
  35 }
  36 
  37 /*!
  38  * \internal
  39  * \brief Get node status object for local node
  40  *
  41  * \return Node status object for local node
  42  */
  43 pcmk__node_status_t *
  44 controld_get_local_node_status(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  45 {
  46     CRM_CHECK(controld_globals.cluster != NULL, return NULL);
  47     return pcmk__get_node(controld_globals.cluster->priv->node_id,
  48                           controld_globals.cluster->priv->node_name, NULL,
  49                           pcmk__node_search_cluster_member);
  50 }
  51 
  52 const char *
  53 fsa_input2string(enum crmd_fsa_input input)
     /* [previous][next][first][last][top][bottom][index][help] */
  54 {
  55     const char *inputAsText = NULL;
  56 
  57     switch (input) {
  58         case I_NULL:
  59             inputAsText = "I_NULL";
  60             break;
  61         case I_CIB_OP:
  62             inputAsText = "I_CIB_OP (unused)";
  63             break;
  64         case I_CIB_UPDATE:
  65             inputAsText = "I_CIB_UPDATE";
  66             break;
  67         case I_DC_TIMEOUT:
  68             inputAsText = "I_DC_TIMEOUT";
  69             break;
  70         case I_ELECTION:
  71             inputAsText = "I_ELECTION";
  72             break;
  73         case I_PE_CALC:
  74             inputAsText = "I_PE_CALC";
  75             break;
  76         case I_RELEASE_DC:
  77             inputAsText = "I_RELEASE_DC";
  78             break;
  79         case I_ELECTION_DC:
  80             inputAsText = "I_ELECTION_DC";
  81             break;
  82         case I_ERROR:
  83             inputAsText = "I_ERROR";
  84             break;
  85         case I_FAIL:
  86             inputAsText = "I_FAIL";
  87             break;
  88         case I_INTEGRATED:
  89             inputAsText = "I_INTEGRATED";
  90             break;
  91         case I_FINALIZED:
  92             inputAsText = "I_FINALIZED";
  93             break;
  94         case I_NODE_JOIN:
  95             inputAsText = "I_NODE_JOIN";
  96             break;
  97         case I_JOIN_OFFER:
  98             inputAsText = "I_JOIN_OFFER";
  99             break;
 100         case I_JOIN_REQUEST:
 101             inputAsText = "I_JOIN_REQUEST";
 102             break;
 103         case I_JOIN_RESULT:
 104             inputAsText = "I_JOIN_RESULT";
 105             break;
 106         case I_NOT_DC:
 107             inputAsText = "I_NOT_DC";
 108             break;
 109         case I_RECOVERED:
 110             inputAsText = "I_RECOVERED";
 111             break;
 112         case I_RELEASE_FAIL:
 113             inputAsText = "I_RELEASE_FAIL";
 114             break;
 115         case I_RELEASE_SUCCESS:
 116             inputAsText = "I_RELEASE_SUCCESS";
 117             break;
 118         case I_RESTART:
 119             inputAsText = "I_RESTART";
 120             break;
 121         case I_PE_SUCCESS:
 122             inputAsText = "I_PE_SUCCESS";
 123             break;
 124         case I_ROUTER:
 125             inputAsText = "I_ROUTER";
 126             break;
 127         case I_SHUTDOWN:
 128             inputAsText = "I_SHUTDOWN";
 129             break;
 130         case I_STARTUP:
 131             inputAsText = "I_STARTUP";
 132             break;
 133         case I_TE_SUCCESS:
 134             inputAsText = "I_TE_SUCCESS";
 135             break;
 136         case I_STOP:
 137             inputAsText = "I_STOP";
 138             break;
 139         case I_DC_HEARTBEAT:
 140             inputAsText = "I_DC_HEARTBEAT";
 141             break;
 142         case I_WAIT_FOR_EVENT:
 143             inputAsText = "I_WAIT_FOR_EVENT";
 144             break;
 145         case I_LRM_EVENT:
 146             inputAsText = "I_LRM_EVENT";
 147             break;
 148         case I_PENDING:
 149             inputAsText = "I_PENDING";
 150             break;
 151         case I_HALT:
 152             inputAsText = "I_HALT";
 153             break;
 154         case I_TERMINATE:
 155             inputAsText = "I_TERMINATE";
 156             break;
 157         case I_ILLEGAL:
 158             inputAsText = "I_ILLEGAL";
 159             break;
 160     }
 161 
 162     if (inputAsText == NULL) {
 163         crm_err("Input %d is unknown", input);
 164         inputAsText = "<UNKNOWN_INPUT>";
 165     }
 166 
 167     return inputAsText;
 168 }
 169 
 170 const char *
 171 fsa_state2string(enum crmd_fsa_state state)
     /* [previous][next][first][last][top][bottom][index][help] */
 172 {
 173     const char *stateAsText = NULL;
 174 
 175     switch (state) {
 176         case S_IDLE:
 177             stateAsText = "S_IDLE";
 178             break;
 179         case S_ELECTION:
 180             stateAsText = "S_ELECTION";
 181             break;
 182         case S_INTEGRATION:
 183             stateAsText = "S_INTEGRATION";
 184             break;
 185         case S_FINALIZE_JOIN:
 186             stateAsText = "S_FINALIZE_JOIN";
 187             break;
 188         case S_NOT_DC:
 189             stateAsText = "S_NOT_DC";
 190             break;
 191         case S_POLICY_ENGINE:
 192             stateAsText = "S_POLICY_ENGINE";
 193             break;
 194         case S_RECOVERY:
 195             stateAsText = "S_RECOVERY";
 196             break;
 197         case S_RELEASE_DC:
 198             stateAsText = "S_RELEASE_DC";
 199             break;
 200         case S_PENDING:
 201             stateAsText = "S_PENDING";
 202             break;
 203         case S_STOPPING:
 204             stateAsText = "S_STOPPING";
 205             break;
 206         case S_TERMINATE:
 207             stateAsText = "S_TERMINATE";
 208             break;
 209         case S_TRANSITION_ENGINE:
 210             stateAsText = "S_TRANSITION_ENGINE";
 211             break;
 212         case S_STARTING:
 213             stateAsText = "S_STARTING";
 214             break;
 215         case S_HALT:
 216             stateAsText = "S_HALT";
 217             break;
 218         case S_ILLEGAL:
 219             stateAsText = "S_ILLEGAL";
 220             break;
 221     }
 222 
 223     if (stateAsText == NULL) {
 224         crm_err("State %d is unknown", state);
 225         stateAsText = "<UNKNOWN_STATE>";
 226     }
 227 
 228     return stateAsText;
 229 }
 230 
 231 const char *
 232 fsa_cause2string(enum crmd_fsa_cause cause)
     /* [previous][next][first][last][top][bottom][index][help] */
 233 {
 234     const char *causeAsText = NULL;
 235 
 236     switch (cause) {
 237         case C_UNKNOWN:
 238             causeAsText = "C_UNKNOWN";
 239             break;
 240         case C_STARTUP:
 241             causeAsText = "C_STARTUP";
 242             break;
 243         case C_IPC_MESSAGE:
 244             causeAsText = "C_IPC_MESSAGE";
 245             break;
 246         case C_HA_MESSAGE:
 247             causeAsText = "C_HA_MESSAGE";
 248             break;
 249         case C_TIMER_POPPED:
 250             causeAsText = "C_TIMER_POPPED";
 251             break;
 252         case C_SHUTDOWN:
 253             causeAsText = "C_SHUTDOWN";
 254             break;
 255         case C_LRM_OP_CALLBACK:
 256             causeAsText = "C_LRM_OP_CALLBACK";
 257             break;
 258         case C_CRMD_STATUS_CALLBACK:
 259             causeAsText = "C_CRMD_STATUS_CALLBACK";
 260             break;
 261         case C_FSA_INTERNAL:
 262             causeAsText = "C_FSA_INTERNAL";
 263             break;
 264     }
 265 
 266     if (causeAsText == NULL) {
 267         crm_err("Cause %d is unknown", cause);
 268         causeAsText = "<UNKNOWN_CAUSE>";
 269     }
 270 
 271     return causeAsText;
 272 }
 273 
 274 const char *
 275 fsa_action2string(long long action)
     /* [previous][next][first][last][top][bottom][index][help] */
 276 {
 277     const char *actionAsText = NULL;
 278 
 279     switch (action) {
 280 
 281         case A_NOTHING:
 282             actionAsText = "A_NOTHING";
 283             break;
 284         case A_ELECTION_START:
 285             actionAsText = "A_ELECTION_START";
 286             break;
 287         case A_DC_JOIN_FINAL:
 288             actionAsText = "A_DC_JOIN_FINAL";
 289             break;
 290         case A_READCONFIG:
 291             actionAsText = "A_READCONFIG";
 292             break;
 293         case O_RELEASE:
 294             actionAsText = "O_RELEASE";
 295             break;
 296         case A_STARTUP:
 297             actionAsText = "A_STARTUP";
 298             break;
 299         case A_STARTED:
 300             actionAsText = "A_STARTED";
 301             break;
 302         case A_HA_CONNECT:
 303             actionAsText = "A_HA_CONNECT";
 304             break;
 305         case A_HA_DISCONNECT:
 306             actionAsText = "A_HA_DISCONNECT";
 307             break;
 308         case A_LRM_CONNECT:
 309             actionAsText = "A_LRM_CONNECT";
 310             break;
 311         case A_LRM_EVENT:
 312             actionAsText = "A_LRM_EVENT";
 313             break;
 314         case A_LRM_INVOKE:
 315             actionAsText = "A_LRM_INVOKE";
 316             break;
 317         case A_LRM_DISCONNECT:
 318             actionAsText = "A_LRM_DISCONNECT";
 319             break;
 320         case O_LRM_RECONNECT:
 321             actionAsText = "O_LRM_RECONNECT";
 322             break;
 323         case A_CL_JOIN_QUERY:
 324             actionAsText = "A_CL_JOIN_QUERY";
 325             break;
 326         case A_DC_TIMER_STOP:
 327             actionAsText = "A_DC_TIMER_STOP";
 328             break;
 329         case A_DC_TIMER_START:
 330             actionAsText = "A_DC_TIMER_START";
 331             break;
 332         case A_INTEGRATE_TIMER_START:
 333             actionAsText = "A_INTEGRATE_TIMER_START";
 334             break;
 335         case A_INTEGRATE_TIMER_STOP:
 336             actionAsText = "A_INTEGRATE_TIMER_STOP";
 337             break;
 338         case A_FINALIZE_TIMER_START:
 339             actionAsText = "A_FINALIZE_TIMER_START";
 340             break;
 341         case A_FINALIZE_TIMER_STOP:
 342             actionAsText = "A_FINALIZE_TIMER_STOP";
 343             break;
 344         case A_ELECTION_COUNT:
 345             actionAsText = "A_ELECTION_COUNT";
 346             break;
 347         case A_ELECTION_VOTE:
 348             actionAsText = "A_ELECTION_VOTE";
 349             break;
 350         case A_ELECTION_CHECK:
 351             actionAsText = "A_ELECTION_CHECK";
 352             break;
 353         case A_CL_JOIN_ANNOUNCE:
 354             actionAsText = "A_CL_JOIN_ANNOUNCE";
 355             break;
 356         case A_CL_JOIN_REQUEST:
 357             actionAsText = "A_CL_JOIN_REQUEST";
 358             break;
 359         case A_CL_JOIN_RESULT:
 360             actionAsText = "A_CL_JOIN_RESULT";
 361             break;
 362         case A_DC_JOIN_OFFER_ALL:
 363             actionAsText = "A_DC_JOIN_OFFER_ALL";
 364             break;
 365         case A_DC_JOIN_OFFER_ONE:
 366             actionAsText = "A_DC_JOIN_OFFER_ONE";
 367             break;
 368         case A_DC_JOIN_PROCESS_REQ:
 369             actionAsText = "A_DC_JOIN_PROCESS_REQ";
 370             break;
 371         case A_DC_JOIN_PROCESS_ACK:
 372             actionAsText = "A_DC_JOIN_PROCESS_ACK";
 373             break;
 374         case A_DC_JOIN_FINALIZE:
 375             actionAsText = "A_DC_JOIN_FINALIZE";
 376             break;
 377         case A_MSG_PROCESS:
 378             actionAsText = "A_MSG_PROCESS";
 379             break;
 380         case A_MSG_ROUTE:
 381             actionAsText = "A_MSG_ROUTE";
 382             break;
 383         case A_RECOVER:
 384             actionAsText = "A_RECOVER";
 385             break;
 386         case A_DC_RELEASE:
 387             actionAsText = "A_DC_RELEASE";
 388             break;
 389         case A_DC_RELEASED:
 390             actionAsText = "A_DC_RELEASED";
 391             break;
 392         case A_DC_TAKEOVER:
 393             actionAsText = "A_DC_TAKEOVER";
 394             break;
 395         case A_SHUTDOWN:
 396             actionAsText = "A_SHUTDOWN";
 397             break;
 398         case A_SHUTDOWN_REQ:
 399             actionAsText = "A_SHUTDOWN_REQ";
 400             break;
 401         case A_STOP:
 402             actionAsText = "A_STOP  ";
 403             break;
 404         case A_EXIT_0:
 405             actionAsText = "A_EXIT_0";
 406             break;
 407         case A_EXIT_1:
 408             actionAsText = "A_EXIT_1";
 409             break;
 410         case O_CIB_RESTART:
 411             actionAsText = "O_CIB_RESTART";
 412             break;
 413         case A_CIB_START:
 414             actionAsText = "A_CIB_START";
 415             break;
 416         case A_CIB_STOP:
 417             actionAsText = "A_CIB_STOP";
 418             break;
 419         case A_TE_INVOKE:
 420             actionAsText = "A_TE_INVOKE";
 421             break;
 422         case O_TE_RESTART:
 423             actionAsText = "O_TE_RESTART";
 424             break;
 425         case A_TE_START:
 426             actionAsText = "A_TE_START";
 427             break;
 428         case A_TE_STOP:
 429             actionAsText = "A_TE_STOP";
 430             break;
 431         case A_TE_HALT:
 432             actionAsText = "A_TE_HALT";
 433             break;
 434         case A_TE_CANCEL:
 435             actionAsText = "A_TE_CANCEL";
 436             break;
 437         case A_PE_INVOKE:
 438             actionAsText = "A_PE_INVOKE";
 439             break;
 440         case O_PE_RESTART:
 441             actionAsText = "O_PE_RESTART";
 442             break;
 443         case A_PE_START:
 444             actionAsText = "A_PE_START";
 445             break;
 446         case A_PE_STOP:
 447             actionAsText = "A_PE_STOP";
 448             break;
 449         case A_NODE_BLOCK:
 450             actionAsText = "A_NODE_BLOCK";
 451             break;
 452         case A_UPDATE_NODESTATUS:
 453             actionAsText = "A_UPDATE_NODESTATUS";
 454             break;
 455         case A_LOG:
 456             actionAsText = "A_LOG   ";
 457             break;
 458         case A_ERROR:
 459             actionAsText = "A_ERROR ";
 460             break;
 461         case A_WARN:
 462             actionAsText = "A_WARN  ";
 463             break;
 464             /* Composite actions */
 465         case A_DC_TIMER_START | A_CL_JOIN_QUERY:
 466             actionAsText = "A_DC_TIMER_START|A_CL_JOIN_QUERY";
 467             break;
 468     }
 469 
 470     if (actionAsText == NULL) {
 471         crm_err("Action %.16llx is unknown", action);
 472         actionAsText = "<UNKNOWN_ACTION>";
 473     }
 474 
 475     return actionAsText;
 476 }
 477 
 478 void
 479 fsa_dump_inputs(int log_level, const char *text, long long input_register)
     /* [previous][next][first][last][top][bottom][index][help] */
 480 {
 481     if (input_register == A_NOTHING) {
 482         return;
 483     }
 484     if (text == NULL) {
 485         text = "Input register contents:";
 486     }
 487 
 488     if (pcmk_is_set(input_register, R_THE_DC)) {
 489         crm_trace("%s %.16llx (R_THE_DC)", text, R_THE_DC);
 490     }
 491     if (pcmk_is_set(input_register, R_STARTING)) {
 492         crm_trace("%s %.16llx (R_STARTING)", text, R_STARTING);
 493     }
 494     if (pcmk_is_set(input_register, R_SHUTDOWN)) {
 495         crm_trace("%s %.16llx (R_SHUTDOWN)", text, R_SHUTDOWN);
 496     }
 497     if (pcmk_is_set(input_register, R_STAYDOWN)) {
 498         crm_trace("%s %.16llx (R_STAYDOWN)", text, R_STAYDOWN);
 499     }
 500     if (pcmk_is_set(input_register, R_JOIN_OK)) {
 501         crm_trace("%s %.16llx (R_JOIN_OK)", text, R_JOIN_OK);
 502     }
 503     if (pcmk_is_set(input_register, R_READ_CONFIG)) {
 504         crm_trace("%s %.16llx (R_READ_CONFIG)", text, R_READ_CONFIG);
 505     }
 506     if (pcmk_is_set(input_register, R_INVOKE_PE)) {
 507         crm_trace("%s %.16llx (R_INVOKE_PE)", text, R_INVOKE_PE);
 508     }
 509     if (pcmk_is_set(input_register, R_CIB_CONNECTED)) {
 510         crm_trace("%s %.16llx (R_CIB_CONNECTED)", text, R_CIB_CONNECTED);
 511     }
 512     if (pcmk_is_set(input_register, R_PE_CONNECTED)) {
 513         crm_trace("%s %.16llx (R_PE_CONNECTED)", text, R_PE_CONNECTED);
 514     }
 515     if (pcmk_is_set(input_register, R_TE_CONNECTED)) {
 516         crm_trace("%s %.16llx (R_TE_CONNECTED)", text, R_TE_CONNECTED);
 517     }
 518     if (pcmk_is_set(input_register, R_LRM_CONNECTED)) {
 519         crm_trace("%s %.16llx (R_LRM_CONNECTED)", text, R_LRM_CONNECTED);
 520     }
 521     if (pcmk_is_set(input_register, R_CIB_REQUIRED)) {
 522         crm_trace("%s %.16llx (R_CIB_REQUIRED)", text, R_CIB_REQUIRED);
 523     }
 524     if (pcmk_is_set(input_register, R_PE_REQUIRED)) {
 525         crm_trace("%s %.16llx (R_PE_REQUIRED)", text, R_PE_REQUIRED);
 526     }
 527     if (pcmk_is_set(input_register, R_TE_REQUIRED)) {
 528         crm_trace("%s %.16llx (R_TE_REQUIRED)", text, R_TE_REQUIRED);
 529     }
 530     if (pcmk_is_set(input_register, R_REQ_PEND)) {
 531         crm_trace("%s %.16llx (R_REQ_PEND)", text, R_REQ_PEND);
 532     }
 533     if (pcmk_is_set(input_register, R_PE_PEND)) {
 534         crm_trace("%s %.16llx (R_PE_PEND)", text, R_PE_PEND);
 535     }
 536     if (pcmk_is_set(input_register, R_TE_PEND)) {
 537         crm_trace("%s %.16llx (R_TE_PEND)", text, R_TE_PEND);
 538     }
 539     if (pcmk_is_set(input_register, R_RESP_PEND)) {
 540         crm_trace("%s %.16llx (R_RESP_PEND)", text, R_RESP_PEND);
 541     }
 542     if (pcmk_is_set(input_register, R_CIB_DONE)) {
 543         crm_trace("%s %.16llx (R_CIB_DONE)", text, R_CIB_DONE);
 544     }
 545     if (pcmk_is_set(input_register, R_HAVE_CIB)) {
 546         crm_trace("%s %.16llx (R_HAVE_CIB)", text, R_HAVE_CIB);
 547     }
 548     if (pcmk_is_set(input_register, R_MEMBERSHIP)) {
 549         crm_trace("%s %.16llx (R_MEMBERSHIP)", text, R_MEMBERSHIP);
 550     }
 551     if (pcmk_is_set(input_register, R_PEER_DATA)) {
 552         crm_trace("%s %.16llx (R_PEER_DATA)", text, R_PEER_DATA);
 553     }
 554     if (pcmk_is_set(input_register, R_IN_RECOVERY)) {
 555         crm_trace("%s %.16llx (R_IN_RECOVERY)", text, R_IN_RECOVERY);
 556     }
 557 }
 558 
 559 void
 560 fsa_dump_actions(uint64_t action, const char *text)
     /* [previous][next][first][last][top][bottom][index][help] */
 561 {
 562     if (pcmk_is_set(action, A_READCONFIG)) {
 563         crm_trace("Action %.16llx (A_READCONFIG) %s", A_READCONFIG, text);
 564     }
 565     if (pcmk_is_set(action, A_STARTUP)) {
 566         crm_trace("Action %.16llx (A_STARTUP) %s", A_STARTUP, text);
 567     }
 568     if (pcmk_is_set(action, A_STARTED)) {
 569         crm_trace("Action %.16llx (A_STARTED) %s", A_STARTED, text);
 570     }
 571     if (pcmk_is_set(action, A_HA_CONNECT)) {
 572         crm_trace("Action %.16llx (A_CONNECT) %s", A_HA_CONNECT, text);
 573     }
 574     if (pcmk_is_set(action, A_HA_DISCONNECT)) {
 575         crm_trace("Action %.16llx (A_DISCONNECT) %s", A_HA_DISCONNECT, text);
 576     }
 577     if (pcmk_is_set(action, A_LRM_CONNECT)) {
 578         crm_trace("Action %.16llx (A_LRM_CONNECT) %s", A_LRM_CONNECT, text);
 579     }
 580     if (pcmk_is_set(action, A_LRM_EVENT)) {
 581         crm_trace("Action %.16llx (A_LRM_EVENT) %s", A_LRM_EVENT, text);
 582     }
 583     if (pcmk_is_set(action, A_LRM_INVOKE)) {
 584         crm_trace("Action %.16llx (A_LRM_INVOKE) %s", A_LRM_INVOKE, text);
 585     }
 586     if (pcmk_is_set(action, A_LRM_DISCONNECT)) {
 587         crm_trace("Action %.16llx (A_LRM_DISCONNECT) %s", A_LRM_DISCONNECT, text);
 588     }
 589     if (pcmk_is_set(action, A_DC_TIMER_STOP)) {
 590         crm_trace("Action %.16llx (A_DC_TIMER_STOP) %s", A_DC_TIMER_STOP, text);
 591     }
 592     if (pcmk_is_set(action, A_DC_TIMER_START)) {
 593         crm_trace("Action %.16llx (A_DC_TIMER_START) %s", A_DC_TIMER_START, text);
 594     }
 595     if (pcmk_is_set(action, A_INTEGRATE_TIMER_START)) {
 596         crm_trace("Action %.16llx (A_INTEGRATE_TIMER_START) %s", A_INTEGRATE_TIMER_START, text);
 597     }
 598     if (pcmk_is_set(action, A_INTEGRATE_TIMER_STOP)) {
 599         crm_trace("Action %.16llx (A_INTEGRATE_TIMER_STOP) %s", A_INTEGRATE_TIMER_STOP, text);
 600     }
 601     if (pcmk_is_set(action, A_FINALIZE_TIMER_START)) {
 602         crm_trace("Action %.16llx (A_FINALIZE_TIMER_START) %s", A_FINALIZE_TIMER_START, text);
 603     }
 604     if (pcmk_is_set(action, A_FINALIZE_TIMER_STOP)) {
 605         crm_trace("Action %.16llx (A_FINALIZE_TIMER_STOP) %s", A_FINALIZE_TIMER_STOP, text);
 606     }
 607     if (pcmk_is_set(action, A_ELECTION_COUNT)) {
 608         crm_trace("Action %.16llx (A_ELECTION_COUNT) %s", A_ELECTION_COUNT, text);
 609     }
 610     if (pcmk_is_set(action, A_ELECTION_VOTE)) {
 611         crm_trace("Action %.16llx (A_ELECTION_VOTE) %s", A_ELECTION_VOTE, text);
 612     }
 613     if (pcmk_is_set(action, A_ELECTION_CHECK)) {
 614         crm_trace("Action %.16llx (A_ELECTION_CHECK) %s", A_ELECTION_CHECK, text);
 615     }
 616     if (pcmk_is_set(action, A_CL_JOIN_ANNOUNCE)) {
 617         crm_trace("Action %.16llx (A_CL_JOIN_ANNOUNCE) %s", A_CL_JOIN_ANNOUNCE, text);
 618     }
 619     if (pcmk_is_set(action, A_CL_JOIN_REQUEST)) {
 620         crm_trace("Action %.16llx (A_CL_JOIN_REQUEST) %s", A_CL_JOIN_REQUEST, text);
 621     }
 622     if (pcmk_is_set(action, A_CL_JOIN_RESULT)) {
 623         crm_trace("Action %.16llx (A_CL_JOIN_RESULT) %s", A_CL_JOIN_RESULT, text);
 624     }
 625     if (pcmk_is_set(action, A_DC_JOIN_OFFER_ALL)) {
 626         crm_trace("Action %.16llx (A_DC_JOIN_OFFER_ALL) %s", A_DC_JOIN_OFFER_ALL, text);
 627     }
 628     if (pcmk_is_set(action, A_DC_JOIN_OFFER_ONE)) {
 629         crm_trace("Action %.16llx (A_DC_JOIN_OFFER_ONE) %s", A_DC_JOIN_OFFER_ONE, text);
 630     }
 631     if (pcmk_is_set(action, A_DC_JOIN_PROCESS_REQ)) {
 632         crm_trace("Action %.16llx (A_DC_JOIN_PROCESS_REQ) %s", A_DC_JOIN_PROCESS_REQ, text);
 633     }
 634     if (pcmk_is_set(action, A_DC_JOIN_PROCESS_ACK)) {
 635         crm_trace("Action %.16llx (A_DC_JOIN_PROCESS_ACK) %s", A_DC_JOIN_PROCESS_ACK, text);
 636     }
 637     if (pcmk_is_set(action, A_DC_JOIN_FINALIZE)) {
 638         crm_trace("Action %.16llx (A_DC_JOIN_FINALIZE) %s", A_DC_JOIN_FINALIZE, text);
 639     }
 640     if (pcmk_is_set(action, A_MSG_PROCESS)) {
 641         crm_trace("Action %.16llx (A_MSG_PROCESS) %s", A_MSG_PROCESS, text);
 642     }
 643     if (pcmk_is_set(action, A_MSG_ROUTE)) {
 644         crm_trace("Action %.16llx (A_MSG_ROUTE) %s", A_MSG_ROUTE, text);
 645     }
 646     if (pcmk_is_set(action, A_RECOVER)) {
 647         crm_trace("Action %.16llx (A_RECOVER) %s", A_RECOVER, text);
 648     }
 649     if (pcmk_is_set(action, A_DC_RELEASE)) {
 650         crm_trace("Action %.16llx (A_DC_RELEASE) %s", A_DC_RELEASE, text);
 651     }
 652     if (pcmk_is_set(action, A_DC_RELEASED)) {
 653         crm_trace("Action %.16llx (A_DC_RELEASED) %s", A_DC_RELEASED, text);
 654     }
 655     if (pcmk_is_set(action, A_DC_TAKEOVER)) {
 656         crm_trace("Action %.16llx (A_DC_TAKEOVER) %s", A_DC_TAKEOVER, text);
 657     }
 658     if (pcmk_is_set(action, A_SHUTDOWN)) {
 659         crm_trace("Action %.16llx (A_SHUTDOWN) %s", A_SHUTDOWN, text);
 660     }
 661     if (pcmk_is_set(action, A_SHUTDOWN_REQ)) {
 662         crm_trace("Action %.16llx (A_SHUTDOWN_REQ) %s", A_SHUTDOWN_REQ, text);
 663     }
 664     if (pcmk_is_set(action, A_STOP)) {
 665         crm_trace("Action %.16llx (A_STOP  ) %s", A_STOP, text);
 666     }
 667     if (pcmk_is_set(action, A_EXIT_0)) {
 668         crm_trace("Action %.16llx (A_EXIT_0) %s", A_EXIT_0, text);
 669     }
 670     if (pcmk_is_set(action, A_EXIT_1)) {
 671         crm_trace("Action %.16llx (A_EXIT_1) %s", A_EXIT_1, text);
 672     }
 673     if (pcmk_is_set(action, A_CIB_START)) {
 674         crm_trace("Action %.16llx (A_CIB_START) %s", A_CIB_START, text);
 675     }
 676     if (pcmk_is_set(action, A_CIB_STOP)) {
 677         crm_trace("Action %.16llx (A_CIB_STOP) %s", A_CIB_STOP, text);
 678     }
 679     if (pcmk_is_set(action, A_TE_INVOKE)) {
 680         crm_trace("Action %.16llx (A_TE_INVOKE) %s", A_TE_INVOKE, text);
 681     }
 682     if (pcmk_is_set(action, A_TE_START)) {
 683         crm_trace("Action %.16llx (A_TE_START) %s", A_TE_START, text);
 684     }
 685     if (pcmk_is_set(action, A_TE_STOP)) {
 686         crm_trace("Action %.16llx (A_TE_STOP) %s", A_TE_STOP, text);
 687     }
 688     if (pcmk_is_set(action, A_TE_CANCEL)) {
 689         crm_trace("Action %.16llx (A_TE_CANCEL) %s", A_TE_CANCEL, text);
 690     }
 691     if (pcmk_is_set(action, A_PE_INVOKE)) {
 692         crm_trace("Action %.16llx (A_PE_INVOKE) %s", A_PE_INVOKE, text);
 693     }
 694     if (pcmk_is_set(action, A_PE_START)) {
 695         crm_trace("Action %.16llx (A_PE_START) %s", A_PE_START, text);
 696     }
 697     if (pcmk_is_set(action, A_PE_STOP)) {
 698         crm_trace("Action %.16llx (A_PE_STOP) %s", A_PE_STOP, text);
 699     }
 700     if (pcmk_is_set(action, A_NODE_BLOCK)) {
 701         crm_trace("Action %.16llx (A_NODE_BLOCK) %s", A_NODE_BLOCK, text);
 702     }
 703     if (pcmk_is_set(action, A_UPDATE_NODESTATUS)) {
 704         crm_trace("Action %.16llx (A_UPDATE_NODESTATUS) %s", A_UPDATE_NODESTATUS, text);
 705     }
 706     if (pcmk_is_set(action, A_LOG)) {
 707         crm_trace("Action %.16llx (A_LOG   ) %s", A_LOG, text);
 708     }
 709     if (pcmk_is_set(action, A_ERROR)) {
 710         crm_trace("Action %.16llx (A_ERROR ) %s", A_ERROR, text);
 711     }
 712     if (pcmk_is_set(action, A_WARN)) {
 713         crm_trace("Action %.16llx (A_WARN  ) %s", A_WARN, text);
 714     }
 715 }
 716 
 717 gboolean
 718 update_dc(xmlNode * msg)
     /* [previous][next][first][last][top][bottom][index][help] */
 719 {
 720     char *last_dc = controld_globals.dc_name;
 721     const char *dc_version = NULL;
 722     const char *welcome_from = NULL;
 723 
 724     if (msg != NULL) {
 725         gboolean invalid = FALSE;
 726 
 727         dc_version = crm_element_value(msg, PCMK_XA_VERSION);
 728         welcome_from = crm_element_value(msg, PCMK__XA_SRC);
 729 
 730         CRM_CHECK(dc_version != NULL, return FALSE);
 731         CRM_CHECK(welcome_from != NULL, return FALSE);
 732 
 733         if (AM_I_DC && !controld_is_local_node(welcome_from)) {
 734             invalid = TRUE;
 735 
 736         } else if ((controld_globals.dc_name != NULL)
 737                    && !pcmk__str_eq(welcome_from, controld_globals.dc_name,
 738                                     pcmk__str_casei)) {
 739             invalid = TRUE;
 740         }
 741 
 742         if (invalid) {
 743             if (AM_I_DC) {
 744                 crm_err("Not updating DC to %s (%s): we are also a DC",
 745                         welcome_from, dc_version);
 746             } else {
 747                 crm_warn("New DC %s is not %s",
 748                          welcome_from, controld_globals.dc_name);
 749             }
 750 
 751             controld_set_fsa_action_flags(A_CL_JOIN_QUERY | A_DC_TIMER_START);
 752             controld_trigger_fsa();
 753             return FALSE;
 754         }
 755     }
 756 
 757     controld_globals.dc_name = NULL;    // freed as last_dc
 758     pcmk__str_update(&(controld_globals.dc_name), welcome_from);
 759     pcmk__str_update(&(controld_globals.dc_version), dc_version);
 760 
 761     if (pcmk__str_eq(controld_globals.dc_name, last_dc, pcmk__str_casei)) {
 762         /* do nothing */
 763 
 764     } else if (controld_globals.dc_name != NULL) {
 765         pcmk__node_status_t *dc_node =
 766             pcmk__get_node(0, controld_globals.dc_name, NULL,
 767                            pcmk__node_search_cluster_member);
 768 
 769         crm_info("Set DC to %s (%s)",
 770                  controld_globals.dc_name,
 771                  pcmk__s(controld_globals.dc_version, "unknown version"));
 772         pcmk__update_peer_expected(__func__, dc_node, CRMD_JOINSTATE_MEMBER);
 773 
 774     } else if (last_dc != NULL) {
 775         crm_info("Unset DC (was %s)", last_dc);
 776     }
 777 
 778     free(last_dc);
 779     return TRUE;
 780 }
 781 
 782 void crmd_peer_down(pcmk__node_status_t *peer, bool full) 
     /* [previous][next][first][last][top][bottom][index][help] */
 783 {
 784     if(full && peer->state == NULL) {
 785         pcmk__update_peer_state(__func__, peer, PCMK__VALUE_LOST, 0);
 786         crm_update_peer_proc(__func__, peer, crm_proc_none, NULL);
 787     }
 788     crm_update_peer_join(__func__, peer, controld_join_none);
 789     pcmk__update_peer_expected(__func__, peer, CRMD_JOINSTATE_DOWN);
 790 }
 791 
 792 /*!
 793  * \internal
 794  * \brief Check feature set compatibility of DC and joining node
 795  *
 796  * Return true if a joining node's CRM feature set is compatible with the
 797  * current DC's. The feature sets are compatible if they have the same major
 798  * version number, and the DC's minor version number is the same or older than
 799  * the joining node's. The minor-minor version is intended solely to allow
 800  * resource agents to detect feature support, and so is ignored.
 801  *
 802  * \param[in] dc_version    DC's feature set
 803  * \param[in] join_version  Joining node's version
 804  */
 805 bool
 806 feature_set_compatible(const char *dc_version, const char *join_version)
     /* [previous][next][first][last][top][bottom][index][help] */
 807 {
 808     char *dc_minor = NULL;
 809     char *join_minor = NULL;
 810     long dc_v = 0;
 811     long join_v = 0;
 812 
 813     // Get DC's major version
 814     errno = 0;
 815     dc_v = strtol(dc_version, &dc_minor, 10);
 816     if (errno) {
 817         return FALSE;
 818     }
 819 
 820     // Get joining node's major version
 821     errno = 0;
 822     join_v = strtol(join_version, &join_minor, 10);
 823     if (errno) {
 824         return FALSE;
 825     }
 826 
 827     // Major version component must be identical
 828     if (dc_v != join_v) {
 829         return FALSE;
 830     }
 831 
 832     // Get DC's minor version
 833     if (*dc_minor == '.') {
 834         ++dc_minor;
 835     }
 836     errno = 0;
 837     dc_v = strtol(dc_minor, NULL, 10);
 838     if (errno) {
 839         return FALSE;
 840     }
 841 
 842     // Get joining node's minor version
 843     if (*join_minor == '.') {
 844         ++join_minor;
 845     }
 846     errno = 0;
 847     join_v = strtol(join_minor, NULL, 10);
 848     if (errno) {
 849         return FALSE;
 850     }
 851 
 852     // DC's minor version must be the same or older
 853     return dc_v <= join_v;
 854 }
 855 
 856 const char *
 857 get_node_id(xmlNode *lrm_rsc_op)
     /* [previous][next][first][last][top][bottom][index][help] */
 858 {
 859     xmlNode *node = lrm_rsc_op;
 860 
 861     while ((node != NULL) && !pcmk__xe_is(node, PCMK__XE_NODE_STATE)) {
 862         node = node->parent;
 863     }
 864 
 865     CRM_CHECK(node != NULL, return NULL);
 866     return pcmk__xe_id(node);
 867 }

/* [previous][next][first][last][top][bottom][index][help] */