This source file includes following definitions.
- election_win_cb
- controld_election_init
- controld_configure_election
- controld_remove_voter
- controld_stop_current_election_timeout
- 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/common/xml.h>
16 #include <crm/cluster/internal.h>
17 #include <crm/cluster/election_internal.h>
18 #include <crm/crm.h>
19
20 #include <pacemaker-controld.h>
21
22 static void
23 election_win_cb(pcmk_cluster_t *cluster)
24 {
25 register_fsa_input(C_FSA_INTERNAL, I_ELECTION_DC, NULL);
26 }
27
28 void
29 controld_election_init(void)
30 {
31 election_init(controld_globals.cluster, election_win_cb);
32 }
33
34
35
36
37
38
39
40 void
41 controld_configure_election(GHashTable *options)
42 {
43 const char *value = g_hash_table_lookup(options, PCMK_OPT_ELECTION_TIMEOUT);
44 guint interval_ms = 0U;
45
46 pcmk_parse_interval_spec(value, &interval_ms);
47 election_timeout_set_period(controld_globals.cluster, interval_ms);
48 }
49
50 void
51 controld_remove_voter(const char *uname)
52 {
53 election_remove(controld_globals.cluster, uname);
54
55 if (pcmk__str_eq(uname, controld_globals.dc_name, pcmk__str_casei)) {
56
57
58
59 election_clear_dampening(controld_globals.cluster);
60 }
61 }
62
63 void
64 controld_stop_current_election_timeout(void)
65 {
66 election_timeout_stop(controld_globals.cluster);
67 }
68
69
70 void
71 do_election_vote(long long action,
72 enum crmd_fsa_cause cause,
73 enum crmd_fsa_state cur_state,
74 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
75 {
76 gboolean not_voting = FALSE;
77
78
79 switch (cur_state) {
80 case S_STARTING:
81 case S_RECOVERY:
82 case S_STOPPING:
83 case S_TERMINATE:
84 crm_warn("Not voting in election, we're in state %s", fsa_state2string(cur_state));
85 not_voting = TRUE;
86 break;
87 case S_ELECTION:
88 case S_INTEGRATION:
89 case S_RELEASE_DC:
90 break;
91 default:
92 crm_err("Broken? Voting in state %s", fsa_state2string(cur_state));
93 break;
94 }
95
96 if (not_voting == FALSE) {
97 if (pcmk_is_set(controld_globals.fsa_input_register, R_STARTING)) {
98 not_voting = TRUE;
99 }
100 }
101
102 if (not_voting) {
103 if (AM_I_DC) {
104 register_fsa_input(C_FSA_INTERNAL, I_RELEASE_DC, NULL);
105
106 } else {
107 register_fsa_input(C_FSA_INTERNAL, I_PENDING, NULL);
108 }
109 return;
110 }
111
112 election_vote(controld_globals.cluster);
113 return;
114 }
115
116 void
117 do_election_check(long long action,
118 enum crmd_fsa_cause cause,
119 enum crmd_fsa_state cur_state,
120 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
121 {
122 if (controld_globals.fsa_state == S_ELECTION) {
123 election_check(controld_globals.cluster);
124 } else {
125 crm_debug("Ignoring election check because we are not in an election");
126 }
127 }
128
129
130 void
131 do_election_count_vote(long long action,
132 enum crmd_fsa_cause cause,
133 enum crmd_fsa_state cur_state,
134 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
135 {
136 enum election_result rc = 0;
137 ha_msg_input_t *vote = fsa_typed_data(fsa_dt_ha_msg);
138
139 if (pcmk__peer_cache == NULL) {
140 if (!pcmk_is_set(controld_globals.fsa_input_register, R_SHUTDOWN)) {
141 crm_err("Internal error, no peer cache");
142 }
143 return;
144 }
145
146 rc = election_count_vote(controld_globals.cluster, vote->msg,
147 (cur_state != S_STARTING));
148 switch(rc) {
149 case election_start:
150 election_reset(controld_globals.cluster);
151 register_fsa_input(C_FSA_INTERNAL, I_ELECTION, NULL);
152 break;
153
154 case election_lost:
155 update_dc(NULL);
156
157 if (pcmk_is_set(controld_globals.fsa_input_register, R_THE_DC)) {
158 cib_t *cib_conn = controld_globals.cib_conn;
159
160 register_fsa_input(C_FSA_INTERNAL, I_RELEASE_DC, NULL);
161 cib_conn->cmds->set_secondary(cib_conn, cib_none);
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 " QB_XS " rc=%d",
180 pcmk_strerror(rc), rc);
181 register_fsa_error(C_FSA_INTERNAL, I_ERROR, NULL);
182 }
183 }
184
185
186
187
188
189
190
191
192 #define dc_takeover_update_attr(name, value) do { \
193 cib__update_node_attr(controld_globals.logger_out, \
194 controld_globals.cib_conn, cib_none, \
195 PCMK_XE_CRM_CONFIG, NULL, NULL, NULL, NULL, \
196 name, value, NULL, NULL); \
197 } while (0)
198
199
200 void
201 do_dc_takeover(long long action,
202 enum crmd_fsa_cause cause,
203 enum crmd_fsa_state cur_state,
204 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
205 {
206 xmlNode *cib = NULL;
207 const enum pcmk_cluster_layer cluster_layer = pcmk_get_cluster_layer();
208 const char *cluster_layer_s = pcmk_cluster_layer_text(cluster_layer);
209 pid_t watchdog = pcmk__locate_sbd();
210
211 crm_info("Taking over DC status for this partition");
212 controld_set_fsa_input_flags(R_THE_DC);
213 execute_stonith_cleanup();
214
215 election_reset(controld_globals.cluster);
216 controld_set_fsa_input_flags(R_JOIN_OK|R_INVOKE_PE);
217
218 controld_globals.cib_conn->cmds->set_primary(controld_globals.cib_conn,
219 cib_none);
220
221 cib = pcmk__xe_create(NULL, PCMK_XE_CIB);
222 crm_xml_add(cib, PCMK_XA_CRM_FEATURE_SET, CRM_FEATURE_SET);
223 controld_update_cib(PCMK_XE_CIB, cib, cib_none, feature_update_callback);
224
225 dc_takeover_update_attr(PCMK_OPT_HAVE_WATCHDOG, pcmk__btoa(watchdog));
226 dc_takeover_update_attr(PCMK_OPT_DC_VERSION,
227 PACEMAKER_VERSION "-" BUILD_VERSION);
228 dc_takeover_update_attr(PCMK_OPT_CLUSTER_INFRASTRUCTURE, cluster_layer_s);
229
230 #if SUPPORT_COROSYNC
231 if ((controld_globals.cluster_name == NULL)
232 && (pcmk_get_cluster_layer() == pcmk_cluster_layer_corosync)) {
233
234 char *cluster_name = pcmk__corosync_cluster_name();
235
236 if (cluster_name != NULL) {
237 dc_takeover_update_attr(PCMK_OPT_CLUSTER_NAME, cluster_name);
238 }
239 free(cluster_name);
240 }
241 #endif
242
243 controld_trigger_config();
244 pcmk__xml_free(cib);
245 }
246
247
248 void
249 do_dc_release(long long action,
250 enum crmd_fsa_cause cause,
251 enum crmd_fsa_state cur_state,
252 enum crmd_fsa_input current_input, fsa_data_t * msg_data)
253 {
254 if (action & A_DC_RELEASE) {
255 crm_debug("Releasing the role of DC");
256 controld_clear_fsa_input_flags(R_THE_DC);
257 controld_expect_sched_reply(NULL);
258
259 } else if (action & A_DC_RELEASED) {
260 crm_info("DC role released");
261 if (pcmk_is_set(controld_globals.fsa_input_register, R_SHUTDOWN)) {
262 xmlNode *update = NULL;
263 pcmk__node_status_t *node = controld_get_local_node_status();
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(PCMK_XE_STATUS, update);
270 pcmk__xml_free(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", pcmk__btoa(AM_I_DC));
279 }