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()
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()
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_slave(fsa_cib_conn, cib_scope_local);
162
163 } else if (cur_state != S_STARTING) {
164 register_fsa_input(C_FSA_INTERNAL, I_PENDING, NULL);
165 }
166 break;
167
168 default:
169 crm_trace("Election message resulted in state %d", rc);
170 }
171 }
172
173 static void
174 feature_update_callback(xmlNode * msg, int call_id, int rc, xmlNode * output, void *user_data)
175 {
176 if (rc != pcmk_ok) {
177 fsa_data_t *msg_data = NULL;
178
179 crm_notice("Feature update failed: %s "CRM_XS" rc=%d",
180 pcmk_strerror(rc), rc);
181 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
182 }
183 }
184
185
186 void
187 do_dc_takeover(long long action,
188 enum crmd_fsa_cause cause,
189 enum crmd_fsa_state cur_state,
190 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
191 {
192 int rc = pcmk_ok;
193 xmlNode *cib = NULL;
194 const char *cluster_type = name_for_cluster_type(get_cluster_type());
195 pid_t watchdog = pcmk__locate_sbd();
196
197 crm_info("Taking over DC status for this partition");
198 controld_set_fsa_input_flags(R_THE_DC);
199 execute_stonith_cleanup();
200
201 election_reset(fsa_election);
202 controld_set_fsa_input_flags(R_JOIN_OK|R_INVOKE_PE);
203
204 fsa_cib_conn->cmds->set_master(fsa_cib_conn, cib_scope_local);
205
206 cib = create_xml_node(NULL, XML_TAG_CIB);
207 crm_xml_add(cib, XML_ATTR_CRM_VERSION, CRM_FEATURE_SET);
208 fsa_cib_update(XML_TAG_CIB, cib, cib_quorum_override, rc, NULL);
209 fsa_register_cib_callback(rc, FALSE, NULL, feature_update_callback);
210
211 cib__update_node_attr(logger_out, fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG,
212 NULL, NULL, NULL, NULL, XML_ATTR_HAVE_WATCHDOG,
213 pcmk__btoa(watchdog), NULL, NULL);
214
215 cib__update_node_attr(logger_out, fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG,
216 NULL, NULL, NULL, NULL, "dc-version",
217 PACEMAKER_VERSION "-" BUILD_VERSION, NULL, NULL);
218
219 cib__update_node_attr(logger_out, fsa_cib_conn, cib_none, XML_CIB_TAG_CRMCONFIG,
220 NULL, NULL, NULL, NULL, "cluster-infrastructure",
221 cluster_type, NULL, NULL);
222
223 #if SUPPORT_COROSYNC
224 if (fsa_cluster_name == NULL && is_corosync_cluster()) {
225 char *cluster_name = pcmk__corosync_cluster_name();
226
227 if (cluster_name) {
228 cib__update_node_attr(logger_out, fsa_cib_conn, cib_none,
229 XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL, NULL,
230 "cluster-name", cluster_name, NULL, NULL);
231 }
232 free(cluster_name);
233 }
234 #endif
235
236 mainloop_set_trigger(config_read);
237 free_xml(cib);
238 }
239
240
241 void
242 do_dc_release(long long action,
243 enum crmd_fsa_cause cause,
244 enum crmd_fsa_state cur_state,
245 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
246 {
247 if (action & A_DC_RELEASE) {
248 crm_debug("Releasing the role of DC");
249 controld_clear_fsa_input_flags(R_THE_DC);
250 controld_expect_sched_reply(NULL);
251
252 } else if (action & A_DC_RELEASED) {
253 crm_info("DC role released");
254 #if 0
255 if (are there errors) {
256
257
258 result = I_SHUTDOWN;
259 }
260 #endif
261 if (pcmk_is_set(fsa_input_register, R_SHUTDOWN)) {
262 xmlNode *update = NULL;
263 crm_node_t *node = crm_get_peer(0, fsa_our_uname);
264
265 pcmk__update_peer_expected(__func__, node, CRMD_JOINSTATE_DOWN);
266 update = create_node_state_update(node, node_update_expected, NULL,
267 __func__);
268
269 fsa_cib_anon_update_discard_reply(XML_CIB_TAG_STATUS, update);
270 free_xml(update);
271 }
272 register_fsa_input(C_FSA_INTERNAL, I_RELEASE_SUCCESS, NULL);
273
274 } else {
275 crm_err("Unknown DC action %s", fsa_action2string(action));
276 }
277
278 crm_trace("Am I still the DC? %s", AM_I_DC ? XML_BOOLEAN_YES : XML_BOOLEAN_NO);
279
280 }