This source file includes following definitions.
- election_win_cb
- controld_election_init
- controld_remove_voter
- controld_election_fini
- controld_set_election_period
- controld_stop_election_timer
- do_election_vote
- do_election_check
- do_election_count_vote
- feature_update_callback
- do_dc_takeover
- do_dc_release
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <sys/time.h>
13 #include <sys/resource.h>
14
15 #include <crm/msg_xml.h>
16 #include <crm/common/xml.h>
17 #include <crm/cluster/internal.h>
18 #include <crm/cluster/election_internal.h>
19 #include <crm/crm.h>
20
21 #include <pacemaker-controld.h>
22
23 extern pcmk__output_t *logger_out;
24
25 static election_t *fsa_election = NULL;
26
27 static gboolean
28 election_win_cb(gpointer data)
29 {
30 register_fsa_input(C_FSA_INTERNAL, I_ELECTION_DC, NULL);
31 return FALSE;
32 }
33
34 void
35 controld_election_init(const char *uname)
36 {
37 fsa_election = election_init("DC", uname, 60000 , election_win_cb);
38 }
39
40 void
41 controld_remove_voter(const char *uname)
42 {
43 election_remove(fsa_election, uname);
44
45 if (pcmk__str_eq(uname, fsa_our_dc, pcmk__str_casei)) {
46
47
48
49 election_clear_dampening(fsa_election);
50 }
51 }
52
53 void
54 controld_election_fini(void)
55 {
56 election_fini(fsa_election);
57 fsa_election = NULL;
58 }
59
60 void
61 controld_set_election_period(const char *value)
62 {
63 election_timeout_set_period(fsa_election, crm_parse_interval_spec(value));
64 }
65
66 void
67 controld_stop_election_timer(void)
68 {
69 election_timeout_stop(fsa_election);
70 }
71
72
73 void
74 do_election_vote(long long action,
75 enum crmd_fsa_cause cause,
76 enum crmd_fsa_state cur_state,
77 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
78 {
79 gboolean not_voting = FALSE;
80
81
82 switch (cur_state) {
83 case S_STARTING:
84 case S_RECOVERY:
85 case S_STOPPING:
86 case S_TERMINATE:
87 crm_warn("Not voting in election, we're in state %s", fsa_state2string(cur_state));
88 not_voting = TRUE;
89 break;
90 case S_ELECTION:
91 case S_INTEGRATION:
92 case S_RELEASE_DC:
93 break;
94 default:
95 crm_err("Broken? Voting in state %s", fsa_state2string(cur_state));
96 break;
97 }
98
99 if (not_voting == FALSE) {
100 if (pcmk_is_set(fsa_input_register, R_STARTING)) {
101 not_voting = TRUE;
102 }
103 }
104
105 if (not_voting) {
106 if (AM_I_DC) {
107 register_fsa_input(C_FSA_INTERNAL, I_RELEASE_DC, NULL);
108
109 } else {
110 register_fsa_input(C_FSA_INTERNAL, I_PENDING, NULL);
111 }
112 return;
113 }
114
115 election_vote(fsa_election);
116 return;
117 }
118
119 void
120 do_election_check(long long action,
121 enum crmd_fsa_cause cause,
122 enum crmd_fsa_state cur_state,
123 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
124 {
125 if (fsa_state == S_ELECTION) {
126 election_check(fsa_election);
127 } else {
128 crm_debug("Ignoring election check because we are not in an election");
129 }
130 }
131
132
133 void
134 do_election_count_vote(long long action,
135 enum crmd_fsa_cause cause,
136 enum crmd_fsa_state cur_state,
137 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
138 {
139 enum election_result rc = 0;
140 ha_msg_input_t *vote = fsa_typed_data(fsa_dt_ha_msg);
141
142 if(crm_peer_cache == NULL) {
143 if (!pcmk_is_set(fsa_input_register, R_SHUTDOWN)) {
144 crm_err("Internal error, no peer cache");
145 }
146 return;
147 }
148
149 rc = election_count_vote(fsa_election, vote->msg, cur_state != S_STARTING);
150 switch(rc) {
151 case election_start:
152 election_reset(fsa_election);
153 register_fsa_input(C_FSA_INTERNAL, I_ELECTION, NULL);
154 break;
155
156 case election_lost:
157 update_dc(NULL);
158
159 if (fsa_input_register & R_THE_DC) {
160 register_fsa_input(C_FSA_INTERNAL, I_RELEASE_DC, NULL);
161 fsa_cib_conn->cmds->set_secondary(fsa_cib_conn,
162 cib_scope_local);
163
164 } else if (cur_state != S_STARTING) {
165 register_fsa_input(C_FSA_INTERNAL, I_PENDING, NULL);
166 }
167 break;
168
169 default:
170 crm_trace("Election message resulted in state %d", rc);
171 }
172 }
173
174 static void
175 feature_update_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
176 {
177 if (rc != pcmk_ok) {
178 fsa_data_t *msg_data = NULL;
179
180 crm_notice("Feature update failed: %s "CRM_XS" rc=%d",
181 pcmk_strerror(rc), rc);
182 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
183 }
184 }
185
186
187 void
188 do_dc_takeover(long long action,
189 enum crmd_fsa_cause cause,
190 enum crmd_fsa_state cur_state,
191 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
192 {
193 int rc = pcmk_ok;
194 xmlNode *cib = NULL;
195 const char *cluster_type = name_for_cluster_type(get_cluster_type());
196 pid_t watchdog = pcmk__locate_sbd();
197
198 crm_info("Taking over DC status for this partition");
199 controld_set_fsa_input_flags(R_THE_DC);
200 execute_stonith_cleanup();
201
202 election_reset(fsa_election);
203 controld_set_fsa_input_flags(R_JOIN_OK|R_INVOKE_PE);
204
205 fsa_cib_conn->cmds->set_primary(fsa_cib_conn, cib_scope_local);
206
207 cib = create_xml_node(NULL, XML_TAG_CIB);
208 crm_xml_add(cib, XML_ATTR_CRM_VERSION, CRM_FEATURE_SET);
209 fsa_cib_update(XML_TAG_CIB, cib, cib_quorum_override, rc, NULL);
210 fsa_register_cib_callback(rc, FALSE, NULL, feature_update_callback);
211
212 cib__update_node_attr(logger_out, fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG,
213 NULL, NULL, NULL, NULL, XML_ATTR_HAVE_WATCHDOG,
214 pcmk__btoa(watchdog), NULL, NULL);
215
216 cib__update_node_attr(logger_out, fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG,
217 NULL, NULL, NULL, NULL, "dc-version",
218 PACEMAKER_VERSION "-" BUILD_VERSION, NULL, NULL);
219
220 cib__update_node_attr(logger_out, fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG,
221 NULL, NULL, NULL, NULL, "cluster-infrastructure",
222 cluster_type, NULL, NULL);
223
224 #if SUPPORT_COROSYNC
225 if (fsa_cluster_name == NULL && is_corosync_cluster()) {
226 char *cluster_name = pcmk__corosync_cluster_name();
227
228 if (cluster_name) {
229 cib__update_node_attr(logger_out, fsa_cib_conn, cib_none,
230 XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL,
231 "cluster-name", cluster_name, NULL, NULL);
232 }
233 free(cluster_name);
234 }
235 #endif
236
237 mainloop_set_trigger(config_read);
238 free_xml(cib);
239 }
240
241
242 void
243 do_dc_release(long long action,
244 enum crmd_fsa_cause cause,
245 enum crmd_fsa_state cur_state,
246 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
247 {
248 if (action & A_DC_RELEASE) {
249 crm_debug("Releasing the role of DC");
250 controld_clear_fsa_input_flags(R_THE_DC);
251 controld_expect_sched_reply(NULL);
252
253 } else if (action & A_DC_RELEASED) {
254 crm_info("DC role released");
255 #if 0
256 if (are there errors) {
257
258
259 result = I_SHUTDOWN;
260 }
261 #endif
262 if (pcmk_is_set(fsa_input_register, R_SHUTDOWN)) {
263 xmlNode *update = NULL;
264 crm_node_t *node = crm_get_peer(0, fsa_our_uname);
265
266 pcmk__update_peer_expected(__func__, node, CRMD_JOINSTATE_DOWN);
267 update = create_node_state_update(node, node_update_expected, NULL,
268 __func__);
269
270 fsa_cib_anon_update_discard_reply(XML_CIB_TAG_STATUS, update);
271 free_xml(update);
272 }
273 register_fsa_input(C_FSA_INTERNAL, I_RELEASE_SUCCESS, NULL);
274
275 } else {
276 crm_err("Unknown DC action %s", fsa_action2string(action));
277 }
278
279 crm_trace("Am I still the DC? %s", AM_I_DC ? XML_BOOLEAN_YES : XML_BOOLEAN_NO);
280
281 }