root/daemons/controld/controld_utils.c

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

DEFINITIONS

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

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