root/crmd/utils.c

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

DEFINITIONS

This source file includes following definitions.
  1. do_timer_control
  2. get_timer_desc
  3. crm_timer_popped
  4. is_timer_started
  5. crm_timer_start
  6. crm_timer_stop
  7. fsa_input2string
  8. fsa_state2string
  9. fsa_cause2string
  10. fsa_action2string
  11. fsa_dump_inputs
  12. fsa_dump_actions
  13. update_dc
  14. erase_xpath_callback
  15. erase_status_tag
  16. crmd_peer_down
  17. cib_op_timeout

   1 /*
   2  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU General Public
   6  * License as published by the Free Software Foundation; either
   7  * version 2 of the License, or (at your option) any later version.
   8  *
   9  * This software is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12  * General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU General Public
  15  * License along with this library; if not, write to the Free Software
  16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  17  */
  18 
  19 #include <crm_internal.h>
  20 
  21 #include <crm/crm.h>
  22 #include <crm/cib.h>
  23 #include <crm/msg_xml.h>
  24 #include <crm/common/xml.h>
  25 #include <crm/cluster.h>
  26 
  27 #include <crmd_fsa.h>
  28 #include <crmd_utils.h>
  29 #include <crmd_messages.h>
  30 
  31 /*      A_DC_TIMER_STOP, A_DC_TIMER_START,
  32  *      A_FINALIZE_TIMER_STOP, A_FINALIZE_TIMER_START
  33  *      A_INTEGRATE_TIMER_STOP, A_INTEGRATE_TIMER_START
  34  */
  35 void
  36 do_timer_control(long long action,
     /* [previous][next][first][last][top][bottom][index][help] */
  37                  enum crmd_fsa_cause cause,
  38                  enum crmd_fsa_state cur_state,
  39                  enum crmd_fsa_input current_input, fsa_data_t * msg_data)
  40 {
  41     gboolean timer_op_ok = TRUE;
  42 
  43     if (action & A_DC_TIMER_STOP) {
  44         timer_op_ok = crm_timer_stop(election_trigger);
  45 
  46     } else if (action & A_FINALIZE_TIMER_STOP) {
  47         timer_op_ok = crm_timer_stop(finalization_timer);
  48 
  49     } else if (action & A_INTEGRATE_TIMER_STOP) {
  50         timer_op_ok = crm_timer_stop(integration_timer);
  51 
  52 /*      } else if(action & A_ELECTION_TIMEOUT_STOP) { */
  53 /*              timer_op_ok = crm_timer_stop(election_timeout); */
  54     }
  55 
  56     /* don't start a timer that wasn't already running */
  57     if (action & A_DC_TIMER_START && timer_op_ok) {
  58         crm_timer_start(election_trigger);
  59         if (AM_I_DC) {
  60             /* there can be only one */
  61             register_fsa_input(cause, I_ELECTION, NULL);
  62         }
  63 
  64     } else if (action & A_FINALIZE_TIMER_START) {
  65         crm_timer_start(finalization_timer);
  66 
  67     } else if (action & A_INTEGRATE_TIMER_START) {
  68         crm_timer_start(integration_timer);
  69 
  70 /*      } else if(action & A_ELECTION_TIMEOUT_START) { */
  71 /*              crm_timer_start(election_timeout); */
  72     }
  73 }
  74 
  75 const char *
  76 get_timer_desc(fsa_timer_t * timer)
     /* [previous][next][first][last][top][bottom][index][help] */
  77 {
  78     if (timer == election_trigger) {
  79         return "Election Trigger";
  80 
  81     } else if (timer == shutdown_escalation_timer) {
  82         return "Shutdown Escalation";
  83 
  84     } else if (timer == integration_timer) {
  85         return "Integration Timer";
  86 
  87     } else if (timer == finalization_timer) {
  88         return "Finalization Timer";
  89 
  90     } else if (timer == transition_timer) {
  91         return "New Transition Timer";
  92 
  93     } else if (timer == wait_timer) {
  94         return "Wait Timer";
  95 
  96     } else if (timer == recheck_timer) {
  97         return "PEngine Recheck Timer";
  98 
  99     }
 100     return "Unknown Timer";
 101 }
 102 
 103 gboolean
 104 crm_timer_popped(gpointer data)
     /* [previous][next][first][last][top][bottom][index][help] */
 105 {
 106     fsa_timer_t *timer = (fsa_timer_t *) data;
 107 
 108     if (timer == wait_timer
 109         || timer == recheck_timer
 110         || timer == transition_timer || timer == finalization_timer || timer == election_trigger) {
 111         crm_info("%s (%s) just popped (%dms)",
 112                  get_timer_desc(timer), fsa_input2string(timer->fsa_input), timer->period_ms);
 113         timer->counter++;
 114 
 115     } else {
 116         crm_err("%s (%s) just popped in state %s! (%dms)",
 117                 get_timer_desc(timer), fsa_input2string(timer->fsa_input),
 118                 fsa_state2string(fsa_state), timer->period_ms);
 119     }
 120 
 121     if (timer == election_trigger && election_trigger->counter > 5) {
 122         crm_notice("We appear to be in an election loop, something may be wrong");
 123         crm_write_blackbox(0, NULL);
 124         election_trigger->counter = 0;
 125     }
 126 
 127     if (timer->repeat == FALSE) {
 128         crm_timer_stop(timer);  /* make it _not_ go off again */
 129     }
 130 
 131     if (timer->fsa_input == I_INTEGRATED) {
 132         crm_info("Welcomed: %d, Integrated: %d",
 133                  crmd_join_phase_count(crm_join_welcomed),
 134                  crmd_join_phase_count(crm_join_integrated));
 135         if (crmd_join_phase_count(crm_join_welcomed) == 0) {
 136             /* If we don't even have ourself, start again */
 137             register_fsa_error_adv(C_FSA_INTERNAL, I_ELECTION, NULL, NULL, __FUNCTION__);
 138 
 139         } else {
 140             register_fsa_input_before(C_TIMER_POPPED, timer->fsa_input, NULL);
 141         }
 142 
 143     } else if (timer == recheck_timer && fsa_state != S_IDLE) {
 144         crm_debug("Discarding %s event in state: %s",
 145                   fsa_input2string(timer->fsa_input), fsa_state2string(fsa_state));
 146 
 147     } else if (timer == finalization_timer && fsa_state != S_FINALIZE_JOIN) {
 148         crm_debug("Discarding %s event in state: %s",
 149                   fsa_input2string(timer->fsa_input), fsa_state2string(fsa_state));
 150 
 151     } else if (timer->fsa_input != I_NULL) {
 152         register_fsa_input(C_TIMER_POPPED, timer->fsa_input, NULL);
 153     }
 154 
 155     crm_trace("Triggering FSA: %s", __FUNCTION__);
 156     mainloop_set_trigger(fsa_source);
 157 
 158     return TRUE;
 159 }
 160 
 161 gboolean
 162 is_timer_started(fsa_timer_t * timer)
     /* [previous][next][first][last][top][bottom][index][help] */
 163 {
 164     if (timer->period_ms > 0) {
 165         if (timer->source_id == 0) {
 166             return FALSE;
 167         } else {
 168             return TRUE;
 169         }
 170     }
 171     return FALSE;
 172 }
 173 
 174 gboolean
 175 crm_timer_start(fsa_timer_t * timer)
     /* [previous][next][first][last][top][bottom][index][help] */
 176 {
 177     const char *timer_desc = get_timer_desc(timer);
 178 
 179     if (timer->source_id == 0 && timer->period_ms > 0) {
 180         timer->source_id = g_timeout_add(timer->period_ms, timer->callback, (void *)timer);
 181         CRM_ASSERT(timer->source_id != 0);
 182         crm_debug("Started %s (%s:%dms), src=%d",
 183                   timer_desc, fsa_input2string(timer->fsa_input),
 184                   timer->period_ms, timer->source_id);
 185 
 186     } else if (timer->period_ms < 0) {
 187         crm_err("Tried to start %s (%s:%dms) with a -ve period",
 188                 timer_desc, fsa_input2string(timer->fsa_input), timer->period_ms);
 189 
 190     } else {
 191         crm_debug("%s (%s:%dms) already running: src=%d",
 192                   timer_desc, fsa_input2string(timer->fsa_input),
 193                   timer->period_ms, timer->source_id);
 194         return FALSE;
 195     }
 196     return TRUE;
 197 }
 198 
 199 gboolean
 200 crm_timer_stop(fsa_timer_t * timer)
     /* [previous][next][first][last][top][bottom][index][help] */
 201 {
 202     const char *timer_desc = get_timer_desc(timer);
 203 
 204     if (timer == NULL) {
 205         crm_err("Attempted to stop NULL timer");
 206         return FALSE;
 207 
 208     } else if (timer->source_id != 0) {
 209         crm_trace("Stopping %s (%s:%dms), src=%d",
 210                   timer_desc, fsa_input2string(timer->fsa_input),
 211                   timer->period_ms, timer->source_id);
 212         g_source_remove(timer->source_id);
 213         timer->source_id = 0;
 214 
 215     } else {
 216         crm_trace("%s (%s:%dms) already stopped",
 217                   timer_desc, fsa_input2string(timer->fsa_input), timer->period_ms);
 218         return FALSE;
 219     }
 220     return TRUE;
 221 }
 222 
 223 const char *
 224 fsa_input2string(enum crmd_fsa_input input)
     /* [previous][next][first][last][top][bottom][index][help] */
 225 {
 226     const char *inputAsText = NULL;
 227 
 228     switch (input) {
 229         case I_NULL:
 230             inputAsText = "I_NULL";
 231             break;
 232         case I_CIB_OP:
 233             inputAsText = "I_CIB_OP (unused)";
 234             break;
 235         case I_CIB_UPDATE:
 236             inputAsText = "I_CIB_UPDATE";
 237             break;
 238         case I_DC_TIMEOUT:
 239             inputAsText = "I_DC_TIMEOUT";
 240             break;
 241         case I_ELECTION:
 242             inputAsText = "I_ELECTION";
 243             break;
 244         case I_PE_CALC:
 245             inputAsText = "I_PE_CALC";
 246             break;
 247         case I_RELEASE_DC:
 248             inputAsText = "I_RELEASE_DC";
 249             break;
 250         case I_ELECTION_DC:
 251             inputAsText = "I_ELECTION_DC";
 252             break;
 253         case I_ERROR:
 254             inputAsText = "I_ERROR";
 255             break;
 256         case I_FAIL:
 257             inputAsText = "I_FAIL";
 258             break;
 259         case I_INTEGRATED:
 260             inputAsText = "I_INTEGRATED";
 261             break;
 262         case I_FINALIZED:
 263             inputAsText = "I_FINALIZED";
 264             break;
 265         case I_NODE_JOIN:
 266             inputAsText = "I_NODE_JOIN";
 267             break;
 268         case I_JOIN_OFFER:
 269             inputAsText = "I_JOIN_OFFER";
 270             break;
 271         case I_JOIN_REQUEST:
 272             inputAsText = "I_JOIN_REQUEST";
 273             break;
 274         case I_JOIN_RESULT:
 275             inputAsText = "I_JOIN_RESULT";
 276             break;
 277         case I_NOT_DC:
 278             inputAsText = "I_NOT_DC";
 279             break;
 280         case I_RECOVERED:
 281             inputAsText = "I_RECOVERED";
 282             break;
 283         case I_RELEASE_FAIL:
 284             inputAsText = "I_RELEASE_FAIL";
 285             break;
 286         case I_RELEASE_SUCCESS:
 287             inputAsText = "I_RELEASE_SUCCESS";
 288             break;
 289         case I_RESTART:
 290             inputAsText = "I_RESTART";
 291             break;
 292         case I_PE_SUCCESS:
 293             inputAsText = "I_PE_SUCCESS";
 294             break;
 295         case I_ROUTER:
 296             inputAsText = "I_ROUTER";
 297             break;
 298         case I_SHUTDOWN:
 299             inputAsText = "I_SHUTDOWN";
 300             break;
 301         case I_STARTUP:
 302             inputAsText = "I_STARTUP";
 303             break;
 304         case I_TE_SUCCESS:
 305             inputAsText = "I_TE_SUCCESS";
 306             break;
 307         case I_STOP:
 308             inputAsText = "I_STOP";
 309             break;
 310         case I_DC_HEARTBEAT:
 311             inputAsText = "I_DC_HEARTBEAT";
 312             break;
 313         case I_WAIT_FOR_EVENT:
 314             inputAsText = "I_WAIT_FOR_EVENT";
 315             break;
 316         case I_LRM_EVENT:
 317             inputAsText = "I_LRM_EVENT";
 318             break;
 319         case I_PENDING:
 320             inputAsText = "I_PENDING";
 321             break;
 322         case I_HALT:
 323             inputAsText = "I_HALT";
 324             break;
 325         case I_TERMINATE:
 326             inputAsText = "I_TERMINATE";
 327             break;
 328         case I_ILLEGAL:
 329             inputAsText = "I_ILLEGAL";
 330             break;
 331     }
 332 
 333     if (inputAsText == NULL) {
 334         crm_err("Input %d is unknown", input);
 335         inputAsText = "<UNKNOWN_INPUT>";
 336     }
 337 
 338     return inputAsText;
 339 }
 340 
 341 const char *
 342 fsa_state2string(enum crmd_fsa_state state)
     /* [previous][next][first][last][top][bottom][index][help] */
 343 {
 344     const char *stateAsText = NULL;
 345 
 346     switch (state) {
 347         case S_IDLE:
 348             stateAsText = "S_IDLE";
 349             break;
 350         case S_ELECTION:
 351             stateAsText = "S_ELECTION";
 352             break;
 353         case S_INTEGRATION:
 354             stateAsText = "S_INTEGRATION";
 355             break;
 356         case S_FINALIZE_JOIN:
 357             stateAsText = "S_FINALIZE_JOIN";
 358             break;
 359         case S_NOT_DC:
 360             stateAsText = "S_NOT_DC";
 361             break;
 362         case S_POLICY_ENGINE:
 363             stateAsText = "S_POLICY_ENGINE";
 364             break;
 365         case S_RECOVERY:
 366             stateAsText = "S_RECOVERY";
 367             break;
 368         case S_RELEASE_DC:
 369             stateAsText = "S_RELEASE_DC";
 370             break;
 371         case S_PENDING:
 372             stateAsText = "S_PENDING";
 373             break;
 374         case S_STOPPING:
 375             stateAsText = "S_STOPPING";
 376             break;
 377         case S_TERMINATE:
 378             stateAsText = "S_TERMINATE";
 379             break;
 380         case S_TRANSITION_ENGINE:
 381             stateAsText = "S_TRANSITION_ENGINE";
 382             break;
 383         case S_STARTING:
 384             stateAsText = "S_STARTING";
 385             break;
 386         case S_HALT:
 387             stateAsText = "S_HALT";
 388             break;
 389         case S_ILLEGAL:
 390             stateAsText = "S_ILLEGAL";
 391             break;
 392     }
 393 
 394     if (stateAsText == NULL) {
 395         crm_err("State %d is unknown", state);
 396         stateAsText = "<UNKNOWN_STATE>";
 397     }
 398 
 399     return stateAsText;
 400 }
 401 
 402 const char *
 403 fsa_cause2string(enum crmd_fsa_cause cause)
     /* [previous][next][first][last][top][bottom][index][help] */
 404 {
 405     const char *causeAsText = NULL;
 406 
 407     switch (cause) {
 408         case C_UNKNOWN:
 409             causeAsText = "C_UNKNOWN";
 410             break;
 411         case C_STARTUP:
 412             causeAsText = "C_STARTUP";
 413             break;
 414         case C_IPC_MESSAGE:
 415             causeAsText = "C_IPC_MESSAGE";
 416             break;
 417         case C_HA_MESSAGE:
 418             causeAsText = "C_HA_MESSAGE";
 419             break;
 420         case C_CCM_CALLBACK:
 421             causeAsText = "C_CCM_CALLBACK";
 422             break;
 423         case C_TIMER_POPPED:
 424             causeAsText = "C_TIMER_POPPED";
 425             break;
 426         case C_SHUTDOWN:
 427             causeAsText = "C_SHUTDOWN";
 428             break;
 429         case C_HEARTBEAT_FAILED:
 430             causeAsText = "C_HEARTBEAT_FAILED";
 431             break;
 432         case C_SUBSYSTEM_CONNECT:
 433             causeAsText = "C_SUBSYSTEM_CONNECT";
 434             break;
 435         case C_LRM_OP_CALLBACK:
 436             causeAsText = "C_LRM_OP_CALLBACK";
 437             break;
 438         case C_LRM_MONITOR_CALLBACK:
 439             causeAsText = "C_LRM_MONITOR_CALLBACK";
 440             break;
 441         case C_CRMD_STATUS_CALLBACK:
 442             causeAsText = "C_CRMD_STATUS_CALLBACK";
 443             break;
 444         case C_HA_DISCONNECT:
 445             causeAsText = "C_HA_DISCONNECT";
 446             break;
 447         case C_FSA_INTERNAL:
 448             causeAsText = "C_FSA_INTERNAL";
 449             break;
 450         case C_ILLEGAL:
 451             causeAsText = "C_ILLEGAL";
 452             break;
 453     }
 454 
 455     if (causeAsText == NULL) {
 456         crm_err("Cause %d is unknown", cause);
 457         causeAsText = "<UNKNOWN_CAUSE>";
 458     }
 459 
 460     return causeAsText;
 461 }
 462 
 463 const char *
 464 fsa_action2string(long long action)
     /* [previous][next][first][last][top][bottom][index][help] */
 465 {
 466     const char *actionAsText = NULL;
 467 
 468     switch (action) {
 469 
 470         case A_NOTHING:
 471             actionAsText = "A_NOTHING";
 472             break;
 473         case A_ELECTION_START:
 474             actionAsText = "A_ELECTION_START";
 475             break;
 476         case A_DC_JOIN_FINAL:
 477             actionAsText = "A_DC_JOIN_FINAL";
 478             break;
 479         case A_READCONFIG:
 480             actionAsText = "A_READCONFIG";
 481             break;
 482         case O_RELEASE:
 483             actionAsText = "O_RELEASE";
 484             break;
 485         case A_STARTUP:
 486             actionAsText = "A_STARTUP";
 487             break;
 488         case A_STARTED:
 489             actionAsText = "A_STARTED";
 490             break;
 491         case A_HA_CONNECT:
 492             actionAsText = "A_HA_CONNECT";
 493             break;
 494         case A_HA_DISCONNECT:
 495             actionAsText = "A_HA_DISCONNECT";
 496             break;
 497         case A_LRM_CONNECT:
 498             actionAsText = "A_LRM_CONNECT";
 499             break;
 500         case A_LRM_EVENT:
 501             actionAsText = "A_LRM_EVENT";
 502             break;
 503         case A_LRM_INVOKE:
 504             actionAsText = "A_LRM_INVOKE";
 505             break;
 506         case A_LRM_DISCONNECT:
 507             actionAsText = "A_LRM_DISCONNECT";
 508             break;
 509         case O_LRM_RECONNECT:
 510             actionAsText = "O_LRM_RECONNECT";
 511             break;
 512         case A_CL_JOIN_QUERY:
 513             actionAsText = "A_CL_JOIN_QUERY";
 514             break;
 515         case A_DC_TIMER_STOP:
 516             actionAsText = "A_DC_TIMER_STOP";
 517             break;
 518         case A_DC_TIMER_START:
 519             actionAsText = "A_DC_TIMER_START";
 520             break;
 521         case A_INTEGRATE_TIMER_START:
 522             actionAsText = "A_INTEGRATE_TIMER_START";
 523             break;
 524         case A_INTEGRATE_TIMER_STOP:
 525             actionAsText = "A_INTEGRATE_TIMER_STOP";
 526             break;
 527         case A_FINALIZE_TIMER_START:
 528             actionAsText = "A_FINALIZE_TIMER_START";
 529             break;
 530         case A_FINALIZE_TIMER_STOP:
 531             actionAsText = "A_FINALIZE_TIMER_STOP";
 532             break;
 533         case A_ELECTION_COUNT:
 534             actionAsText = "A_ELECTION_COUNT";
 535             break;
 536         case A_ELECTION_VOTE:
 537             actionAsText = "A_ELECTION_VOTE";
 538             break;
 539         case A_ELECTION_CHECK:
 540             actionAsText = "A_ELECTION_CHECK";
 541             break;
 542         case A_CL_JOIN_ANNOUNCE:
 543             actionAsText = "A_CL_JOIN_ANNOUNCE";
 544             break;
 545         case A_CL_JOIN_REQUEST:
 546             actionAsText = "A_CL_JOIN_REQUEST";
 547             break;
 548         case A_CL_JOIN_RESULT:
 549             actionAsText = "A_CL_JOIN_RESULT";
 550             break;
 551         case A_DC_JOIN_OFFER_ALL:
 552             actionAsText = "A_DC_JOIN_OFFER_ALL";
 553             break;
 554         case A_DC_JOIN_OFFER_ONE:
 555             actionAsText = "A_DC_JOIN_OFFER_ONE";
 556             break;
 557         case A_DC_JOIN_PROCESS_REQ:
 558             actionAsText = "A_DC_JOIN_PROCESS_REQ";
 559             break;
 560         case A_DC_JOIN_PROCESS_ACK:
 561             actionAsText = "A_DC_JOIN_PROCESS_ACK";
 562             break;
 563         case A_DC_JOIN_FINALIZE:
 564             actionAsText = "A_DC_JOIN_FINALIZE";
 565             break;
 566         case A_MSG_PROCESS:
 567             actionAsText = "A_MSG_PROCESS";
 568             break;
 569         case A_MSG_ROUTE:
 570             actionAsText = "A_MSG_ROUTE";
 571             break;
 572         case A_RECOVER:
 573             actionAsText = "A_RECOVER";
 574             break;
 575         case A_DC_RELEASE:
 576             actionAsText = "A_DC_RELEASE";
 577             break;
 578         case A_DC_RELEASED:
 579             actionAsText = "A_DC_RELEASED";
 580             break;
 581         case A_DC_TAKEOVER:
 582             actionAsText = "A_DC_TAKEOVER";
 583             break;
 584         case A_SHUTDOWN:
 585             actionAsText = "A_SHUTDOWN";
 586             break;
 587         case A_SHUTDOWN_REQ:
 588             actionAsText = "A_SHUTDOWN_REQ";
 589             break;
 590         case A_STOP:
 591             actionAsText = "A_STOP  ";
 592             break;
 593         case A_EXIT_0:
 594             actionAsText = "A_EXIT_0";
 595             break;
 596         case A_EXIT_1:
 597             actionAsText = "A_EXIT_1";
 598             break;
 599         case A_CCM_CONNECT:
 600             actionAsText = "A_CCM_CONNECT";
 601             break;
 602         case A_CCM_DISCONNECT:
 603             actionAsText = "A_CCM_DISCONNECT";
 604             break;
 605         case O_CIB_RESTART:
 606             actionAsText = "O_CIB_RESTART";
 607             break;
 608         case A_CIB_START:
 609             actionAsText = "A_CIB_START";
 610             break;
 611         case A_CIB_STOP:
 612             actionAsText = "A_CIB_STOP";
 613             break;
 614         case A_TE_INVOKE:
 615             actionAsText = "A_TE_INVOKE";
 616             break;
 617         case O_TE_RESTART:
 618             actionAsText = "O_TE_RESTART";
 619             break;
 620         case A_TE_START:
 621             actionAsText = "A_TE_START";
 622             break;
 623         case A_TE_STOP:
 624             actionAsText = "A_TE_STOP";
 625             break;
 626         case A_TE_HALT:
 627             actionAsText = "A_TE_HALT";
 628             break;
 629         case A_TE_CANCEL:
 630             actionAsText = "A_TE_CANCEL";
 631             break;
 632         case A_PE_INVOKE:
 633             actionAsText = "A_PE_INVOKE";
 634             break;
 635         case O_PE_RESTART:
 636             actionAsText = "O_PE_RESTART";
 637             break;
 638         case A_PE_START:
 639             actionAsText = "A_PE_START";
 640             break;
 641         case A_PE_STOP:
 642             actionAsText = "A_PE_STOP";
 643             break;
 644         case A_NODE_BLOCK:
 645             actionAsText = "A_NODE_BLOCK";
 646             break;
 647         case A_UPDATE_NODESTATUS:
 648             actionAsText = "A_UPDATE_NODESTATUS";
 649             break;
 650         case A_LOG:
 651             actionAsText = "A_LOG   ";
 652             break;
 653         case A_ERROR:
 654             actionAsText = "A_ERROR ";
 655             break;
 656         case A_WARN:
 657             actionAsText = "A_WARN  ";
 658             break;
 659             /* Composite actions */
 660         case A_DC_TIMER_START | A_CL_JOIN_QUERY:
 661             actionAsText = "A_DC_TIMER_START|A_CL_JOIN_QUERY";
 662             break;
 663     }
 664 
 665     if (actionAsText == NULL) {
 666         crm_err("Action %.16llx is unknown", action);
 667         actionAsText = "<UNKNOWN_ACTION>";
 668     }
 669 
 670     return actionAsText;
 671 }
 672 
 673 void
 674 fsa_dump_inputs(int log_level, const char *text, long long input_register)
     /* [previous][next][first][last][top][bottom][index][help] */
 675 {
 676     if (input_register == A_NOTHING) {
 677         return;
 678     }
 679     if (text == NULL) {
 680         text = "Input register contents:";
 681     }
 682 
 683     if (is_set(input_register, R_THE_DC)) {
 684         crm_trace("%s %.16llx (R_THE_DC)", text, R_THE_DC);
 685     }
 686     if (is_set(input_register, R_STARTING)) {
 687         crm_trace("%s %.16llx (R_STARTING)", text, R_STARTING);
 688     }
 689     if (is_set(input_register, R_SHUTDOWN)) {
 690         crm_trace("%s %.16llx (R_SHUTDOWN)", text, R_SHUTDOWN);
 691     }
 692     if (is_set(input_register, R_STAYDOWN)) {
 693         crm_trace("%s %.16llx (R_STAYDOWN)", text, R_STAYDOWN);
 694     }
 695     if (is_set(input_register, R_JOIN_OK)) {
 696         crm_trace("%s %.16llx (R_JOIN_OK)", text, R_JOIN_OK);
 697     }
 698     if (is_set(input_register, R_READ_CONFIG)) {
 699         crm_trace("%s %.16llx (R_READ_CONFIG)", text, R_READ_CONFIG);
 700     }
 701     if (is_set(input_register, R_INVOKE_PE)) {
 702         crm_trace("%s %.16llx (R_INVOKE_PE)", text, R_INVOKE_PE);
 703     }
 704     if (is_set(input_register, R_CIB_CONNECTED)) {
 705         crm_trace("%s %.16llx (R_CIB_CONNECTED)", text, R_CIB_CONNECTED);
 706     }
 707     if (is_set(input_register, R_PE_CONNECTED)) {
 708         crm_trace("%s %.16llx (R_PE_CONNECTED)", text, R_PE_CONNECTED);
 709     }
 710     if (is_set(input_register, R_TE_CONNECTED)) {
 711         crm_trace("%s %.16llx (R_TE_CONNECTED)", text, R_TE_CONNECTED);
 712     }
 713     if (is_set(input_register, R_LRM_CONNECTED)) {
 714         crm_trace("%s %.16llx (R_LRM_CONNECTED)", text, R_LRM_CONNECTED);
 715     }
 716     if (is_set(input_register, R_CIB_REQUIRED)) {
 717         crm_trace("%s %.16llx (R_CIB_REQUIRED)", text, R_CIB_REQUIRED);
 718     }
 719     if (is_set(input_register, R_PE_REQUIRED)) {
 720         crm_trace("%s %.16llx (R_PE_REQUIRED)", text, R_PE_REQUIRED);
 721     }
 722     if (is_set(input_register, R_TE_REQUIRED)) {
 723         crm_trace("%s %.16llx (R_TE_REQUIRED)", text, R_TE_REQUIRED);
 724     }
 725     if (is_set(input_register, R_REQ_PEND)) {
 726         crm_trace("%s %.16llx (R_REQ_PEND)", text, R_REQ_PEND);
 727     }
 728     if (is_set(input_register, R_PE_PEND)) {
 729         crm_trace("%s %.16llx (R_PE_PEND)", text, R_PE_PEND);
 730     }
 731     if (is_set(input_register, R_TE_PEND)) {
 732         crm_trace("%s %.16llx (R_TE_PEND)", text, R_TE_PEND);
 733     }
 734     if (is_set(input_register, R_RESP_PEND)) {
 735         crm_trace("%s %.16llx (R_RESP_PEND)", text, R_RESP_PEND);
 736     }
 737     if (is_set(input_register, R_CIB_DONE)) {
 738         crm_trace("%s %.16llx (R_CIB_DONE)", text, R_CIB_DONE);
 739     }
 740     if (is_set(input_register, R_HAVE_CIB)) {
 741         crm_trace("%s %.16llx (R_HAVE_CIB)", text, R_HAVE_CIB);
 742     }
 743     if (is_set(input_register, R_CIB_ASKED)) {
 744         crm_trace("%s %.16llx (R_CIB_ASKED)", text, R_CIB_ASKED);
 745     }
 746     if (is_set(input_register, R_MEMBERSHIP)) {
 747         crm_trace("%s %.16llx (R_MEMBERSHIP)", text, R_MEMBERSHIP);
 748     }
 749     if (is_set(input_register, R_PEER_DATA)) {
 750         crm_trace("%s %.16llx (R_PEER_DATA)", text, R_PEER_DATA);
 751     }
 752     if (is_set(input_register, R_IN_RECOVERY)) {
 753         crm_trace("%s %.16llx (R_IN_RECOVERY)", text, R_IN_RECOVERY);
 754     }
 755 }
 756 
 757 void
 758 fsa_dump_actions(long long action, const char *text)
     /* [previous][next][first][last][top][bottom][index][help] */
 759 {
 760     if (is_set(action, A_READCONFIG)) {
 761         crm_trace("Action %.16llx (A_READCONFIG) %s", A_READCONFIG, text);
 762     }
 763     if (is_set(action, A_STARTUP)) {
 764         crm_trace("Action %.16llx (A_STARTUP) %s", A_STARTUP, text);
 765     }
 766     if (is_set(action, A_STARTED)) {
 767         crm_trace("Action %.16llx (A_STARTED) %s", A_STARTED, text);
 768     }
 769     if (is_set(action, A_HA_CONNECT)) {
 770         crm_trace("Action %.16llx (A_CONNECT) %s", A_HA_CONNECT, text);
 771     }
 772     if (is_set(action, A_HA_DISCONNECT)) {
 773         crm_trace("Action %.16llx (A_DISCONNECT) %s", A_HA_DISCONNECT, text);
 774     }
 775     if (is_set(action, A_LRM_CONNECT)) {
 776         crm_trace("Action %.16llx (A_LRM_CONNECT) %s", A_LRM_CONNECT, text);
 777     }
 778     if (is_set(action, A_LRM_EVENT)) {
 779         crm_trace("Action %.16llx (A_LRM_EVENT) %s", A_LRM_EVENT, text);
 780     }
 781     if (is_set(action, A_LRM_INVOKE)) {
 782         crm_trace("Action %.16llx (A_LRM_INVOKE) %s", A_LRM_INVOKE, text);
 783     }
 784     if (is_set(action, A_LRM_DISCONNECT)) {
 785         crm_trace("Action %.16llx (A_LRM_DISCONNECT) %s", A_LRM_DISCONNECT, text);
 786     }
 787     if (is_set(action, A_DC_TIMER_STOP)) {
 788         crm_trace("Action %.16llx (A_DC_TIMER_STOP) %s", A_DC_TIMER_STOP, text);
 789     }
 790     if (is_set(action, A_DC_TIMER_START)) {
 791         crm_trace("Action %.16llx (A_DC_TIMER_START) %s", A_DC_TIMER_START, text);
 792     }
 793     if (is_set(action, A_INTEGRATE_TIMER_START)) {
 794         crm_trace("Action %.16llx (A_INTEGRATE_TIMER_START) %s", A_INTEGRATE_TIMER_START, text);
 795     }
 796     if (is_set(action, A_INTEGRATE_TIMER_STOP)) {
 797         crm_trace("Action %.16llx (A_INTEGRATE_TIMER_STOP) %s", A_INTEGRATE_TIMER_STOP, text);
 798     }
 799     if (is_set(action, A_FINALIZE_TIMER_START)) {
 800         crm_trace("Action %.16llx (A_FINALIZE_TIMER_START) %s", A_FINALIZE_TIMER_START, text);
 801     }
 802     if (is_set(action, A_FINALIZE_TIMER_STOP)) {
 803         crm_trace("Action %.16llx (A_FINALIZE_TIMER_STOP) %s", A_FINALIZE_TIMER_STOP, text);
 804     }
 805     if (is_set(action, A_ELECTION_COUNT)) {
 806         crm_trace("Action %.16llx (A_ELECTION_COUNT) %s", A_ELECTION_COUNT, text);
 807     }
 808     if (is_set(action, A_ELECTION_VOTE)) {
 809         crm_trace("Action %.16llx (A_ELECTION_VOTE) %s", A_ELECTION_VOTE, text);
 810     }
 811     if (is_set(action, A_ELECTION_CHECK)) {
 812         crm_trace("Action %.16llx (A_ELECTION_CHECK) %s", A_ELECTION_CHECK, text);
 813     }
 814     if (is_set(action, A_CL_JOIN_ANNOUNCE)) {
 815         crm_trace("Action %.16llx (A_CL_JOIN_ANNOUNCE) %s", A_CL_JOIN_ANNOUNCE, text);
 816     }
 817     if (is_set(action, A_CL_JOIN_REQUEST)) {
 818         crm_trace("Action %.16llx (A_CL_JOIN_REQUEST) %s", A_CL_JOIN_REQUEST, text);
 819     }
 820     if (is_set(action, A_CL_JOIN_RESULT)) {
 821         crm_trace("Action %.16llx (A_CL_JOIN_RESULT) %s", A_CL_JOIN_RESULT, text);
 822     }
 823     if (is_set(action, A_DC_JOIN_OFFER_ALL)) {
 824         crm_trace("Action %.16llx (A_DC_JOIN_OFFER_ALL) %s", A_DC_JOIN_OFFER_ALL, text);
 825     }
 826     if (is_set(action, A_DC_JOIN_OFFER_ONE)) {
 827         crm_trace("Action %.16llx (A_DC_JOIN_OFFER_ONE) %s", A_DC_JOIN_OFFER_ONE, text);
 828     }
 829     if (is_set(action, A_DC_JOIN_PROCESS_REQ)) {
 830         crm_trace("Action %.16llx (A_DC_JOIN_PROCESS_REQ) %s", A_DC_JOIN_PROCESS_REQ, text);
 831     }
 832     if (is_set(action, A_DC_JOIN_PROCESS_ACK)) {
 833         crm_trace("Action %.16llx (A_DC_JOIN_PROCESS_ACK) %s", A_DC_JOIN_PROCESS_ACK, text);
 834     }
 835     if (is_set(action, A_DC_JOIN_FINALIZE)) {
 836         crm_trace("Action %.16llx (A_DC_JOIN_FINALIZE) %s", A_DC_JOIN_FINALIZE, text);
 837     }
 838     if (is_set(action, A_MSG_PROCESS)) {
 839         crm_trace("Action %.16llx (A_MSG_PROCESS) %s", A_MSG_PROCESS, text);
 840     }
 841     if (is_set(action, A_MSG_ROUTE)) {
 842         crm_trace("Action %.16llx (A_MSG_ROUTE) %s", A_MSG_ROUTE, text);
 843     }
 844     if (is_set(action, A_RECOVER)) {
 845         crm_trace("Action %.16llx (A_RECOVER) %s", A_RECOVER, text);
 846     }
 847     if (is_set(action, A_DC_RELEASE)) {
 848         crm_trace("Action %.16llx (A_DC_RELEASE) %s", A_DC_RELEASE, text);
 849     }
 850     if (is_set(action, A_DC_RELEASED)) {
 851         crm_trace("Action %.16llx (A_DC_RELEASED) %s", A_DC_RELEASED, text);
 852     }
 853     if (is_set(action, A_DC_TAKEOVER)) {
 854         crm_trace("Action %.16llx (A_DC_TAKEOVER) %s", A_DC_TAKEOVER, text);
 855     }
 856     if (is_set(action, A_SHUTDOWN)) {
 857         crm_trace("Action %.16llx (A_SHUTDOWN) %s", A_SHUTDOWN, text);
 858     }
 859     if (is_set(action, A_SHUTDOWN_REQ)) {
 860         crm_trace("Action %.16llx (A_SHUTDOWN_REQ) %s", A_SHUTDOWN_REQ, text);
 861     }
 862     if (is_set(action, A_STOP)) {
 863         crm_trace("Action %.16llx (A_STOP  ) %s", A_STOP, text);
 864     }
 865     if (is_set(action, A_EXIT_0)) {
 866         crm_trace("Action %.16llx (A_EXIT_0) %s", A_EXIT_0, text);
 867     }
 868     if (is_set(action, A_EXIT_1)) {
 869         crm_trace("Action %.16llx (A_EXIT_1) %s", A_EXIT_1, text);
 870     }
 871     if (is_set(action, A_CCM_CONNECT)) {
 872         crm_trace("Action %.16llx (A_CCM_CONNECT) %s", A_CCM_CONNECT, text);
 873     }
 874     if (is_set(action, A_CCM_DISCONNECT)) {
 875         crm_trace("Action %.16llx (A_CCM_DISCONNECT) %s", A_CCM_DISCONNECT, text);
 876     }
 877     if (is_set(action, A_CIB_START)) {
 878         crm_trace("Action %.16llx (A_CIB_START) %s", A_CIB_START, text);
 879     }
 880     if (is_set(action, A_CIB_STOP)) {
 881         crm_trace("Action %.16llx (A_CIB_STOP) %s", A_CIB_STOP, text);
 882     }
 883     if (is_set(action, A_TE_INVOKE)) {
 884         crm_trace("Action %.16llx (A_TE_INVOKE) %s", A_TE_INVOKE, text);
 885     }
 886     if (is_set(action, A_TE_START)) {
 887         crm_trace("Action %.16llx (A_TE_START) %s", A_TE_START, text);
 888     }
 889     if (is_set(action, A_TE_STOP)) {
 890         crm_trace("Action %.16llx (A_TE_STOP) %s", A_TE_STOP, text);
 891     }
 892     if (is_set(action, A_TE_CANCEL)) {
 893         crm_trace("Action %.16llx (A_TE_CANCEL) %s", A_TE_CANCEL, text);
 894     }
 895     if (is_set(action, A_PE_INVOKE)) {
 896         crm_trace("Action %.16llx (A_PE_INVOKE) %s", A_PE_INVOKE, text);
 897     }
 898     if (is_set(action, A_PE_START)) {
 899         crm_trace("Action %.16llx (A_PE_START) %s", A_PE_START, text);
 900     }
 901     if (is_set(action, A_PE_STOP)) {
 902         crm_trace("Action %.16llx (A_PE_STOP) %s", A_PE_STOP, text);
 903     }
 904     if (is_set(action, A_NODE_BLOCK)) {
 905         crm_trace("Action %.16llx (A_NODE_BLOCK) %s", A_NODE_BLOCK, text);
 906     }
 907     if (is_set(action, A_UPDATE_NODESTATUS)) {
 908         crm_trace("Action %.16llx (A_UPDATE_NODESTATUS) %s", A_UPDATE_NODESTATUS, text);
 909     }
 910     if (is_set(action, A_LOG)) {
 911         crm_trace("Action %.16llx (A_LOG   ) %s", A_LOG, text);
 912     }
 913     if (is_set(action, A_ERROR)) {
 914         crm_trace("Action %.16llx (A_ERROR ) %s", A_ERROR, text);
 915     }
 916     if (is_set(action, A_WARN)) {
 917         crm_trace("Action %.16llx (A_WARN  ) %s", A_WARN, text);
 918     }
 919 }
 920 
 921 gboolean
 922 update_dc(xmlNode * msg)
     /* [previous][next][first][last][top][bottom][index][help] */
 923 {
 924     char *last_dc = fsa_our_dc;
 925     const char *dc_version = NULL;
 926     const char *welcome_from = NULL;
 927 
 928     if (msg != NULL) {
 929         gboolean invalid = FALSE;
 930 
 931         dc_version = crm_element_value(msg, F_CRM_VERSION);
 932         welcome_from = crm_element_value(msg, F_CRM_HOST_FROM);
 933 
 934         CRM_CHECK(dc_version != NULL, return FALSE);
 935         CRM_CHECK(welcome_from != NULL, return FALSE);
 936 
 937         if (AM_I_DC && safe_str_neq(welcome_from, fsa_our_uname)) {
 938             invalid = TRUE;
 939 
 940         } else if (fsa_our_dc && safe_str_neq(welcome_from, fsa_our_dc)) {
 941             invalid = TRUE;
 942         }
 943 
 944         if (invalid) {
 945             CRM_CHECK(fsa_our_dc != NULL, crm_err("We have no DC"));
 946             if (AM_I_DC) {
 947                 crm_err("Not updating DC to %s (%s): we are also a DC", welcome_from, dc_version);
 948             } else {
 949                 crm_warn("New DC %s is not %s", welcome_from, fsa_our_dc);
 950             }
 951 
 952             register_fsa_action(A_CL_JOIN_QUERY | A_DC_TIMER_START);
 953             return FALSE;
 954         }
 955     }
 956 
 957     free(fsa_our_dc_version);
 958     fsa_our_dc_version = NULL;
 959 
 960     fsa_our_dc = NULL;          /* Free'd as last_dc */
 961 
 962     if (welcome_from != NULL) {
 963         fsa_our_dc = strdup(welcome_from);
 964     }
 965     if (dc_version != NULL) {
 966         fsa_our_dc_version = strdup(dc_version);
 967     }
 968 
 969     if (safe_str_eq(fsa_our_dc, last_dc)) {
 970         /* do nothing */
 971 
 972     } else if (fsa_our_dc != NULL) {
 973         crm_node_t *dc_node = crm_get_peer(0, fsa_our_dc);
 974 
 975         crm_info("Set DC to %s (%s)", crm_str(fsa_our_dc), crm_str(fsa_our_dc_version));
 976         crm_update_peer_expected(__FUNCTION__, dc_node, CRMD_JOINSTATE_MEMBER);
 977 
 978     } else if (last_dc != NULL) {
 979         crm_info("Unset DC. Was %s", crm_str(last_dc));
 980     }
 981 
 982     free(last_dc);
 983     return TRUE;
 984 }
 985 
 986 #define STATUS_PATH_MAX 512
 987 static void
 988 erase_xpath_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
     /* [previous][next][first][last][top][bottom][index][help] */
 989 {
 990     char *xpath = user_data;
 991 
 992     do_crm_log_unlikely(rc == 0 ? LOG_DEBUG : LOG_NOTICE,
 993                         "Deletion of \"%s\": %s (rc=%d)", xpath, pcmk_strerror(rc), rc);
 994 }
 995 
 996 #define XPATH_STATUS_TAG "//node_state[@uname='%s']/%s"
 997 
 998 void
 999 erase_status_tag(const char *uname, const char *tag, int options)
     /* [previous][next][first][last][top][bottom][index][help] */
1000 {
1001     if (fsa_cib_conn && uname) {
1002         int call_id;
1003         char *xpath = crm_strdup_printf(XPATH_STATUS_TAG, uname, tag);
1004 
1005         crm_info("Deleting %s status entries for %s " CRM_XS " xpath=%s",
1006                  tag, uname, xpath);
1007         call_id = fsa_cib_conn->cmds->delete(fsa_cib_conn, xpath, NULL,
1008                                              cib_quorum_override | cib_xpath | options);
1009         fsa_register_cib_callback(call_id, FALSE, xpath, erase_xpath_callback);
1010         // CIB library handles freeing xpath
1011     }
1012 }
1013 
1014 void crmd_peer_down(crm_node_t *peer, bool full) 
     /* [previous][next][first][last][top][bottom][index][help] */
1015 {
1016     if(full && peer->state == NULL) {
1017         crm_update_peer_state(__FUNCTION__, peer, CRM_NODE_LOST, 0);
1018         crm_update_peer_proc(__FUNCTION__, peer, crm_proc_none, NULL);
1019     }
1020     crm_update_peer_join(__FUNCTION__, peer, crm_join_none);
1021     crm_update_peer_expected(__FUNCTION__, peer, CRMD_JOINSTATE_DOWN);
1022 }
1023 
1024 #define MIN_CIB_OP_TIMEOUT (30)
1025 
1026 unsigned int
1027 cib_op_timeout()
     /* [previous][next][first][last][top][bottom][index][help] */
1028 {
1029     static int env_timeout = -1;
1030     unsigned int calculated_timeout = 0;
1031 
1032     if (env_timeout == -1) {
1033         const char *env = getenv("PCMK_cib_timeout");
1034 
1035         if (env) {
1036             env_timeout = crm_parse_int(env, "0");
1037         }
1038         env_timeout = QB_MAX(env_timeout, MIN_CIB_OP_TIMEOUT);
1039         crm_trace("Minimum CIB op timeout: %us (environment: %s)",
1040                   env_timeout, (env? env : "none"));
1041     }
1042 
1043     calculated_timeout = 1 + crm_active_peers();
1044     if (crm_remote_peer_cache) {
1045         calculated_timeout += g_hash_table_size(crm_remote_peer_cache);
1046     }
1047     calculated_timeout *= 10;
1048 
1049     calculated_timeout = QB_MAX(calculated_timeout, env_timeout);
1050     crm_trace("Calculated timeout: %us", calculated_timeout);
1051 
1052     if (fsa_cib_conn) {
1053         fsa_cib_conn->call_timeout = calculated_timeout;
1054     }
1055     return calculated_timeout;
1056 }

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