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