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