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 free(peer_writer);
85 peer_writer = strdup(peer->uname);
86 crm_debug("Election lost, presuming %s is writer for now",
87 peer_writer);
88 }
89 break;
90
91 case election_in_progress:
92 election_check(writer);
93 break;
94
95 default:
96 crm_info("Ignoring election op from %s due to error", peer->uname);
97 break;
98 }
99 }
100
101 bool
102 attrd_check_for_new_writer(const crm_node_t *peer, const xmlNode *xml)
103 {
104 int peer_state = 0;
105
106 crm_element_value_int(xml, PCMK__XA_ATTR_WRITER, &peer_state);
107 if (peer_state == election_won) {
108 if ((election_state(writer) == election_won)
109 && !pcmk__str_eq(peer->uname, attrd_cluster->uname, pcmk__str_casei)) {
110 crm_notice("Detected another attribute writer (%s), starting new election",
111 peer->uname);
112 election_vote(writer);
113
114 } else if (!pcmk__str_eq(peer->uname, peer_writer, pcmk__str_casei)) {
115 crm_notice("Recorded new attribute writer: %s (was %s)",
116 peer->uname, (peer_writer? peer_writer : "unset"));
117 free(peer_writer);
118 peer_writer = strdup(peer->uname);
119 }
120 }
121 return (peer_state == election_won);
122 }
123
124 void
125 attrd_declare_winner()
126 {
127 crm_notice("Recorded local node as attribute writer (was %s)",
128 (peer_writer? peer_writer : "unset"));
129 free(peer_writer);
130 peer_writer = strdup(attrd_cluster->uname);
131 }
132
133 void
134 attrd_remove_voter(const crm_node_t *peer)
135 {
136 election_remove(writer, peer->uname);
137 if (peer_writer && pcmk__str_eq(peer->uname, peer_writer, pcmk__str_casei)) {
138 free(peer_writer);
139 peer_writer = NULL;
140 crm_notice("Lost attribute writer %s", peer->uname);
141
142
143
144
145 election_clear_dampening(writer);
146
147
148
149
150
151
152
153 attrd_start_election_if_needed();
154
155
156
157
158
159 } else if (election_state(writer) == election_in_progress) {
160 crm_debug("Checking election status upon loss of voter %s", peer->uname);
161 election_check(writer);
162 }
163 }
164
165 void
166 attrd_xml_add_writer(xmlNode *xml)
167 {
168 crm_xml_add_int(xml, PCMK__XA_ATTR_WRITER, election_state(writer));
169 }