root/include/crm/cluster/election_internal.h

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

INCLUDED FROM


   1 /*
   2  * Copyright 2009-2019 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 Lesser General Public License
   7  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
   8  */
   9 
  10 #ifndef CRM_COMMON_ELECTION__H
  11 #  define CRM_COMMON_ELECTION__H
  12 
  13 #ifdef __cplusplus
  14 extern "C" {
  15 #endif
  16 
  17 /**
  18  * \file
  19  * \brief Functions for conducting elections
  20  *
  21  * An election is useful for a daemon that runs on all nodes but needs any one
  22  * instance to perform a special role.
  23  *
  24  * Elections are closely tied to the cluster peer cache. Peers in the cache that
  25  * are active members are eligible to vote. Elections are named for logging
  26  * purposes, but only one election may exist at any time, so typically an
  27  * election would be created at daemon start-up and freed at shutdown.
  28  *
  29  * Pacemaker's election procedure has been heavily adapted from the
  30  * Invitation Algorithm variant of the Garcia-Molina Bully Algorithm:
  31  *
  32  *   https://en.wikipedia.org/wiki/Bully_algorithm
  33  *
  34  * Elections are conducted via cluster messages. There are two types of
  35  * messages: a "vote" is a declaration of the voting node's candidacy, and is
  36  * always broadcast; a "no-vote" is a concession by the responding node, and is
  37  * always a reply to the preferred node's vote. (These correspond to "invite"
  38  * and "accept" in the traditional algorithm.)
  39  *
  40  * A vote together with any no-vote replies to it is considered an election
  41  * round. Rounds are numbered with a simple counter unique to each node
  42  * (this would be the group number in the traditional algorithm). Concurrent
  43  * election rounds are possible.
  44  *
  45  * An election round is started when any node broadcasts a vote. When a node
  46  * receives another node's vote, it compares itself against the sending node
  47  * according to certain metrics, and either starts a new round (if it prefers
  48  * itself) or replies to the other node with a no-vote (if it prefers that
  49  * node).
  50  *
  51  * If a node receives no-votes from all other active nodes, it declares itself
  52  * the winner. The library API does not notify other nodes of this; callers
  53  * must implement that if desired.
  54  */
  55 
  56 typedef struct election_s election_t;
  57 
  58 /*! Possible election states */
  59 enum election_result {
  60     election_start = 0,     /*! new election needed */
  61     election_in_progress,   /*! election started but not all peers have voted */
  62     election_lost,          /*! local node lost most recent election */
  63     election_won,           /*! local node won most recent election */
  64     election_error,         /*! election message or election object invalid */
  65 };
  66 
  67 void election_fini(election_t *e);
  68 void election_reset(election_t *e);
  69 election_t *election_init(const char *name, const char *uname, guint period_ms, GSourceFunc cb);
  70 
  71 void election_timeout_set_period(election_t *e, guint period_ms);
  72 void election_timeout_stop(election_t *e);
  73 
  74 void election_vote(election_t *e);
  75 bool election_check(election_t *e);
  76 void election_remove(election_t *e, const char *uname);
  77 enum election_result election_state(election_t *e);
  78 enum election_result election_count_vote(election_t *e, xmlNode *vote, bool can_win);
  79 void election_clear_dampening(election_t *e);
  80 
  81 #ifdef __cplusplus
  82 }
  83 #endif
  84 
  85 #endif

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