This source file includes following definitions.
- attrd_election_init
 
- attrd_election_fini
 
- attrd_start_election_if_needed
 
- attrd_election_won
 
- attrd_handle_election_op
 
- attrd_check_for_new_writer
 
- attrd_declare_winner
 
- attrd_remove_voter
 
- attrd_xml_add_writer
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #include <crm_internal.h>
  11 #include <crm/msg_xml.h>
  12 #include <crm/cluster.h>
  13 #include <crm/cluster/election_internal.h>
  14 
  15 #include "pacemaker-attrd.h"
  16 
  17 static char *peer_writer = NULL;
  18 static election_t *writer = NULL;
  19 
  20 void
  21 attrd_election_init()
     
  22 {
  23     writer = election_init(T_ATTRD, attrd_cluster->uname, 120000,
  24                            attrd_election_cb);
  25 }
  26 
  27 void
  28 attrd_election_fini()
     
  29 {
  30     election_fini(writer);
  31 }
  32 
  33 void
  34 attrd_start_election_if_needed()
     
  35 {
  36     if ((peer_writer == NULL)
  37         && (election_state(writer) != election_in_progress)
  38         && !attrd_shutting_down()) {
  39 
  40         crm_info("Starting an election to determine the writer");
  41         election_vote(writer);
  42     }
  43 }
  44 
  45 bool
  46 attrd_election_won()
     
  47 {
  48     return (election_state(writer) == election_won);
  49 }
  50 
  51 void
  52 attrd_handle_election_op(const crm_node_t *peer, xmlNode *xml)
     
  53 {
  54     enum election_result rc = 0;
  55     enum election_result previous = election_state(writer);
  56 
  57     crm_xml_add(xml, F_CRM_HOST_FROM, peer->uname);
  58 
  59     
  60     rc = election_count_vote(writer, xml, !attrd_shutting_down());
  61 
  62     switch(rc) {
  63         case election_start:
  64             crm_debug("Unsetting writer (was %s) and starting new election",
  65                       peer_writer? peer_writer : "unset");
  66             free(peer_writer);
  67             peer_writer = NULL;
  68             election_vote(writer);
  69             break;
  70 
  71         case election_lost:
  72             
  73 
  74 
  75 
  76 
  77 
  78 
  79 
  80 
  81 
  82 
  83             if ((peer_writer == NULL) || (previous != election_lost)) {
  84                 pcmk__str_update(&peer_writer, peer->uname);
  85                 crm_debug("Election lost, presuming %s is writer for now",
  86                           peer_writer);
  87             }
  88             break;
  89 
  90         case election_in_progress:
  91             election_check(writer);
  92             break;
  93 
  94         default:
  95             crm_info("Ignoring election op from %s due to error", peer->uname);
  96             break;
  97     }
  98 }
  99 
 100 bool
 101 attrd_check_for_new_writer(const crm_node_t *peer, const xmlNode *xml)
     
 102 {
 103     int peer_state = 0;
 104 
 105     crm_element_value_int(xml, PCMK__XA_ATTR_WRITER, &peer_state);
 106     if (peer_state == election_won) {
 107         if ((election_state(writer) == election_won)
 108            && !pcmk__str_eq(peer->uname, attrd_cluster->uname, pcmk__str_casei)) {
 109             crm_notice("Detected another attribute writer (%s), starting new election",
 110                        peer->uname);
 111             election_vote(writer);
 112 
 113         } else if (!pcmk__str_eq(peer->uname, peer_writer, pcmk__str_casei)) {
 114             crm_notice("Recorded new attribute writer: %s (was %s)",
 115                        peer->uname, (peer_writer? peer_writer : "unset"));
 116             pcmk__str_update(&peer_writer, peer->uname);
 117         }
 118     }
 119     return (peer_state == election_won);
 120 }
 121 
 122 void
 123 attrd_declare_winner()
     
 124 {
 125     crm_notice("Recorded local node as attribute writer (was %s)",
 126                (peer_writer? peer_writer : "unset"));
 127     pcmk__str_update(&peer_writer, attrd_cluster->uname);
 128 }
 129 
 130 void
 131 attrd_remove_voter(const crm_node_t *peer)
     
 132 {
 133     election_remove(writer, peer->uname);
 134     if (peer_writer && pcmk__str_eq(peer->uname, peer_writer, pcmk__str_casei)) {
 135         free(peer_writer);
 136         peer_writer = NULL;
 137         crm_notice("Lost attribute writer %s", peer->uname);
 138 
 139         
 140 
 141 
 142         election_clear_dampening(writer);
 143 
 144         
 145 
 146 
 147 
 148 
 149 
 150         attrd_start_election_if_needed();
 151 
 152     
 153 
 154 
 155 
 156     } else if (election_state(writer) == election_in_progress) {
 157        crm_debug("Checking election status upon loss of voter %s", peer->uname);
 158        election_check(writer);
 159     }
 160 }
 161 
 162 void
 163 attrd_xml_add_writer(xmlNode *xml)
     
 164 {
 165     crm_xml_add_int(xml, PCMK__XA_ATTR_WRITER, election_state(writer));
 166 }