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