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/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 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);
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(PCMK__VALUE_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, PCMK__XA_SRC, 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 }