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