1 /*
2 * Copyright 2004-2023 the Pacemaker project contributors
3 *
4 * The version control history for this file may have further details.
5 *
6 * This source code is licensed under the GNU Lesser General Public License
7 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
8 */
9
10 #ifndef CRMD_FSA__H
11 # define CRMD_FSA__H
12
13 # include <crm/crm.h>
14 # include <crm/cib.h>
15 # include <crm/common/xml.h>
16 # include <crm/common/mainloop.h>
17 # include <crm/cluster.h>
18 # include <crm/cluster/election_internal.h>
19 # include <crm/common/ipc_internal.h>
20
21 /*! States the controller can be in */
22 enum crmd_fsa_state {
23 S_IDLE = 0, /* Nothing happening */
24
25 S_ELECTION, /* Take part in the election algorithm as
26 * described below
27 */
28 S_INTEGRATION, /* integrate that status of new nodes (which is
29 * all of them if we have just been elected DC)
30 * to form a complete and up-to-date picture of
31 * the CIB
32 */
33 S_FINALIZE_JOIN, /* integrate that status of new nodes (which is
34 * all of them if we have just been elected DC)
35 * to form a complete and up-to-date picture of
36 * the CIB
37 */
38 S_NOT_DC, /* we are in non-DC mode */
39 S_POLICY_ENGINE, /* Determine next stable state of the cluster */
40 S_RECOVERY, /* Something bad happened, check everything is ok
41 * before continuing and attempt to recover if
42 * required
43 */
44 S_RELEASE_DC, /* we were the DC, but now we arent anymore,
45 * possibly by our own request, and we should
46 * release all unnecessary sub-systems, finish
47 * any pending actions, do general cleanup and
48 * unset anything that makes us think we are
49 * special :)
50 */
51 S_STARTING, /* we are just starting out */
52 S_PENDING, /* we are not a full/active member yet */
53 S_STOPPING, /* We are in the final stages of shutting down */
54 S_TERMINATE, /* We are going to shutdown, this is the equiv of
55 * "Sending TERM signal to all processes" in Linux
56 * and in worst case scenarios could be considered
57 * a self STONITH
58 */
59 S_TRANSITION_ENGINE, /* Attempt to make the calculated next stable
60 * state of the cluster a reality
61 */
62
63 S_HALT, /* Freeze - don't do anything
64 * Something bad happened that needs the admin to fix
65 * Wait for I_ELECTION
66 */
67
68 /* ----------- Last input found in table is above ---------- */
69 S_ILLEGAL /* This is an illegal FSA state */
70 /* (must be last) */
71 };
72
73 # define MAXSTATE S_ILLEGAL
74
75 /*
76 Once we start and do some basic sanity checks, we go into the
77 S_NOT_DC state and await instructions from the DC or input from
78 the cluster layer which indicates the election algorithm needs to run.
79
80 If the election algorithm is triggered, we enter the S_ELECTION state
81 from where we can either go back to the S_NOT_DC state or progress
82 to the S_INTEGRATION state (or S_RELEASE_DC if we used to be the DC
83 but aren't anymore). See the libcrmcluster API documentation for more
84 information about the election algorithm.
85
86 Once the election is complete, if we are the DC, we enter the
87 S_INTEGRATION state which is a DC-in-waiting style state. We are
88 the DC, but we shouldn't do anything yet because we may not have an
89 up-to-date picture of the cluster. There may of course be times
90 when this fails, so we should go back to the S_RECOVERY stage and
91 check everything is ok. We may also end up here if a new node came
92 online, since each node is authoritative about itself, and we would want
93 to incorporate its information into the CIB.
94
95 Once we have the latest CIB, we then enter the S_POLICY_ENGINE state
96 where invoke the scheduler. It is possible that between
97 invoking the scheduler and receiving an answer, that we receive
98 more input. In this case, we would discard the orginal result and
99 invoke it again.
100
101 Once we are satisfied with the output from the scheduler, we
102 enter S_TRANSITION_ENGINE and feed the scheduler's output to the
103 Transition Engine who attempts to make the scheduler's
104 calculation a reality. If the transition completes successfully,
105 we enter S_IDLE, otherwise we go back to S_POLICY_ENGINE with the
106 current unstable state and try again.
107
108 Of course, we may be asked to shutdown at any time, however we must
109 progress to S_NOT_DC before doing so. Once we have handed over DC
110 duties to another node, we can then shut down like everyone else,
111 that is, by asking the DC for permission and waiting for it to take all
112 our resources away.
113
114 The case where we are the DC and the only node in the cluster is a
115 special case and handled as an escalation which takes us to
116 S_SHUTDOWN. Similarly, if any other point in the shutdown
117 fails or stalls, this is escalated and we end up in S_TERMINATE.
118
119 At any point, the controller can relay messages for its subsystems,
120 but outbound messages (from subsystems) should probably be blocked
121 until S_INTEGRATION (for the DC) or the join protocol has
122 completed (for non-DC controllers).
123 */
124
125 /*======================================
126 *
127 * Inputs/Events/Stimuli to be given to the finite state machine
128 *
129 * Some of these a true events, and others are synthesised based on
130 * the "register" (see below) and the contents or source of messages.
131 *
132 * The machine keeps processing until receiving I_NULL
133 *
134 *======================================*/
135 enum crmd_fsa_input {
136 /* 0 */
137 I_NULL, /* Nothing happened */
138 /* 1 */
139
140 I_CIB_OP, /* An update to the CIB occurred */
141 I_CIB_UPDATE, /* An update to the CIB occurred */
142 I_DC_TIMEOUT, /* We have lost communication with the DC */
143 I_ELECTION, /* Someone started an election */
144 I_PE_CALC, /* The scheduler needs to be invoked */
145 I_RELEASE_DC, /* The election completed and we were not
146 * elected, but we were the DC beforehand
147 */
148 I_ELECTION_DC, /* The election completed and we were (re-)elected
149 * DC
150 */
151 I_ERROR, /* Something bad happened (more serious than
152 * I_FAIL) and may not have been due to the action
153 * being performed. For example, we may have lost
154 * our connection to the CIB.
155 */
156 /* 9 */
157 I_FAIL, /* The action failed to complete successfully */
158 I_INTEGRATED,
159 I_FINALIZED,
160 I_NODE_JOIN, /* A node has entered the cluster */
161 I_NOT_DC, /* We are not and were not the DC before or after
162 * the current operation or state
163 */
164 I_RECOVERED, /* The recovery process completed successfully */
165 I_RELEASE_FAIL, /* We could not give up DC status for some reason
166 */
167 I_RELEASE_SUCCESS, /* We are no longer the DC */
168 I_RESTART, /* The current set of actions needs to be
169 * restarted
170 */
171 I_TE_SUCCESS, /* Some non-resource, non-cluster-layer action
172 * is required of us, e.g. ping
173 */
174 /* 20 */
175 I_ROUTER, /* Do our job as router and forward this to the
176 * right place
177 */
178 I_SHUTDOWN, /* We are asking to shutdown */
179 I_STOP, /* We have been told to shutdown */
180 I_TERMINATE, /* Actually exit */
181 I_STARTUP,
182 I_PE_SUCCESS, /* The action completed successfully */
183
184 I_JOIN_OFFER, /* The DC is offering membership */
185 I_JOIN_REQUEST, /* The client is requesting membership */
186 I_JOIN_RESULT, /* If not the DC: The result of a join request
187 * Else: A client is responding with its local state info
188 */
189
190 I_WAIT_FOR_EVENT, /* we may be waiting for an async task to "happen"
191 * and until it does, we can't do anything else
192 */
193
194 I_DC_HEARTBEAT, /* The DC is telling us that it is alive and well */
195
196 I_LRM_EVENT,
197
198 /* 30 */
199 I_PENDING,
200 I_HALT,
201
202 /* ------------ Last input found in table is above ----------- */
203 I_ILLEGAL /* This is an illegal value for an FSA input */
204 /* (must be last) */
205 };
206
207 # define MAXINPUT I_ILLEGAL
208
209 # define I_MESSAGE I_ROUTER
210
211 /*======================================
212 *
213 * actions
214 *
215 * Some of the actions below will always occur together for now, but this may
216 * not always be the case, so they are split up so that they can easily be
217 * called independently in the future, if necessary.
218 *
219 * For example, separating A_LRM_CONNECT from A_STARTUP might be useful
220 * if we ever try to recover from a faulty or disconnected executor.
221 *
222 *======================================*/
223
224 /* Don't do anything */
225 # define A_NOTHING 0x0000000000000000ULL
226
227 /* -- Startup actions -- */
228 /* Hook to perform any actions (other than connecting to other daemons)
229 * that might be needed as part of the startup.
230 */
231 # define A_STARTUP 0x0000000000000001ULL
232 /* Hook to perform any actions that might be needed as part
233 * after startup is successful.
234 */
235 # define A_STARTED 0x0000000000000002ULL
236 /* Connect to cluster layer */
237 # define A_HA_CONNECT 0x0000000000000004ULL
238 # define A_HA_DISCONNECT 0x0000000000000008ULL
239
240 # define A_INTEGRATE_TIMER_START 0x0000000000000010ULL
241 # define A_INTEGRATE_TIMER_STOP 0x0000000000000020ULL
242 # define A_FINALIZE_TIMER_START 0x0000000000000040ULL
243 # define A_FINALIZE_TIMER_STOP 0x0000000000000080ULL
244
245 /* -- Election actions -- */
246 # define A_DC_TIMER_START 0x0000000000000100ULL
247 # define A_DC_TIMER_STOP 0x0000000000000200ULL
248 # define A_ELECTION_COUNT 0x0000000000000400ULL
249 # define A_ELECTION_VOTE 0x0000000000000800ULL
250
251 # define A_ELECTION_START 0x0000000000001000ULL
252
253 /* -- Message processing -- */
254 /* Process the queue of requests */
255 # define A_MSG_PROCESS 0x0000000000002000ULL
256 /* Send the message to the correct recipient */
257 # define A_MSG_ROUTE 0x0000000000004000ULL
258
259 /* Send a welcome message to new node(s) */
260 # define A_DC_JOIN_OFFER_ONE 0x0000000000008000ULL
261
262 /* -- Server Join protocol actions -- */
263 /* Send a welcome message to all nodes */
264 # define A_DC_JOIN_OFFER_ALL 0x0000000000010000ULL
265 /* Process the remote node's ack of our join message */
266 # define A_DC_JOIN_PROCESS_REQ 0x0000000000020000ULL
267 /* Send out the results of the Join phase */
268 # define A_DC_JOIN_FINALIZE 0x0000000000040000ULL
269 /* Send out the results of the Join phase */
270 # define A_DC_JOIN_PROCESS_ACK 0x0000000000080000ULL
271
272 /* -- Client Join protocol actions -- */
273 # define A_CL_JOIN_QUERY 0x0000000000100000ULL
274 # define A_CL_JOIN_ANNOUNCE 0x0000000000200000ULL
275 /* Request membership to the DC list */
276 # define A_CL_JOIN_REQUEST 0x0000000000400000ULL
277 /* Did the DC accept or reject the request */
278 # define A_CL_JOIN_RESULT 0x0000000000800000ULL
279
280 /* -- Recovery, DC start/stop -- */
281 /* Something bad happened, try to recover */
282 # define A_RECOVER 0x0000000001000000ULL
283 /* Hook to perform any actions (apart from starting, the TE, scheduler,
284 * and gathering the latest CIB) that might be necessary before
285 * giving up the responsibilities of being the DC.
286 */
287 # define A_DC_RELEASE 0x0000000002000000ULL
288 /* */
289 # define A_DC_RELEASED 0x0000000004000000ULL
290 /* Hook to perform any actions (apart from starting, the TE, scheduler,
291 * and gathering the latest CIB) that might be necessary before
292 * taking over the responsibilities of being the DC.
293 */
294 # define A_DC_TAKEOVER 0x0000000008000000ULL
295
296 /* -- Shutdown actions -- */
297 # define A_SHUTDOWN 0x0000000010000000ULL
298 # define A_STOP 0x0000000020000000ULL
299 # define A_EXIT_0 0x0000000040000000ULL
300 # define A_EXIT_1 0x0000000080000000ULL
301
302 # define A_SHUTDOWN_REQ 0x0000000100000000ULL
303 # define A_ELECTION_CHECK 0x0000000200000000ULL
304 # define A_DC_JOIN_FINAL 0x0000000400000000ULL
305
306 /* -- CIB actions -- */
307 # define A_CIB_START 0x0000020000000000ULL
308 # define A_CIB_STOP 0x0000040000000000ULL
309
310 /* -- Transition Engine actions -- */
311 /* Attempt to reach the newly calculated cluster state. This is
312 * only called once per transition (except if it is asked to
313 * stop the transition or start a new one).
314 * Once given a cluster state to reach, the TE will determine
315 * tasks that can be performed in parallel, execute them, wait
316 * for replies and then determine the next set until the new
317 * state is reached or no further tasks can be taken.
318 */
319 # define A_TE_INVOKE 0x0000100000000000ULL
320 # define A_TE_START 0x0000200000000000ULL
321 # define A_TE_STOP 0x0000400000000000ULL
322 # define A_TE_CANCEL 0x0000800000000000ULL
323 # define A_TE_HALT 0x0001000000000000ULL
324
325 /* -- Scheduler actions -- */
326 /* Calculate the next state for the cluster. This is only
327 * invoked once per needed calculation.
328 */
329 # define A_PE_INVOKE 0x0002000000000000ULL
330 # define A_PE_START 0x0004000000000000ULL
331 # define A_PE_STOP 0x0008000000000000ULL
332 /* -- Misc actions -- */
333 /* Add a system generate "block" so that resources arent moved
334 * to or are activly moved away from the affected node. This
335 * way we can return quickly even if busy with other things.
336 */
337 # define A_NODE_BLOCK 0x0010000000000000ULL
338 /* Update our information in the local CIB */
339 # define A_UPDATE_NODESTATUS 0x0020000000000000ULL
340 # define A_READCONFIG 0x0080000000000000ULL
341
342 /* -- LRM Actions -- */
343 /* Connect to pacemaker-execd */
344 # define A_LRM_CONNECT 0x0100000000000000ULL
345 /* Disconnect from pacemaker-execd */
346 # define A_LRM_DISCONNECT 0x0200000000000000ULL
347 # define A_LRM_INVOKE 0x0400000000000000ULL
348 # define A_LRM_EVENT 0x0800000000000000ULL
349
350 /* -- Logging actions -- */
351 # define A_LOG 0x1000000000000000ULL
352 # define A_ERROR 0x2000000000000000ULL
353 # define A_WARN 0x4000000000000000ULL
354
355 # define O_EXIT (A_SHUTDOWN|A_STOP|A_LRM_DISCONNECT|A_HA_DISCONNECT|A_EXIT_0|A_CIB_STOP)
356 # define O_RELEASE (A_DC_TIMER_STOP|A_DC_RELEASE|A_PE_STOP|A_TE_STOP|A_DC_RELEASED)
357 # define O_PE_RESTART (A_PE_START|A_PE_STOP)
358 # define O_TE_RESTART (A_TE_START|A_TE_STOP)
359 # define O_CIB_RESTART (A_CIB_START|A_CIB_STOP)
360 # define O_LRM_RECONNECT (A_LRM_CONNECT|A_LRM_DISCONNECT)
361 # define O_DC_TIMER_RESTART (A_DC_TIMER_STOP|A_DC_TIMER_START)
362 /*======================================
363 *
364 * "register" contents
365 *
366 * Things we may want to remember regardless of which state we are in.
367 *
368 * These also count as inputs for synthesizing I_*
369 *
370 *======================================*/
371 # define R_THE_DC 0x00000001ULL
372 /* Are we the DC? */
373 # define R_STARTING 0x00000002ULL
374 /* Are we starting up? */
375 # define R_SHUTDOWN 0x00000004ULL
376 /* Are we trying to shut down? */
377 # define R_STAYDOWN 0x00000008ULL
378 /* Should we restart? */
379
380 # define R_JOIN_OK 0x00000010ULL /* Have we completed the join process */
381 # define R_READ_CONFIG 0x00000040ULL
382 # define R_INVOKE_PE 0x00000080ULL // Should the scheduler be invoked?
383
384 # define R_CIB_CONNECTED 0x00000100ULL
385 /* Is the CIB connected? */
386 # define R_PE_CONNECTED 0x00000200ULL // Is the scheduler connected?
387 # define R_TE_CONNECTED 0x00000400ULL
388 /* Is the Transition Engine connected? */
389 # define R_LRM_CONNECTED 0x00000800ULL // Is pacemaker-execd connected?
390
391 # define R_CIB_REQUIRED 0x00001000ULL
392 /* Is the CIB required? */
393 # define R_PE_REQUIRED 0x00002000ULL // Is the scheduler required?
394 # define R_TE_REQUIRED 0x00004000ULL
395 /* Is the Transition Engine required? */
396 # define R_ST_REQUIRED 0x00008000ULL
397 /* Is the Stonith daemon required? */
398
399 # define R_CIB_DONE 0x00010000ULL
400 /* Have we calculated the CIB? */
401 # define R_HAVE_CIB 0x00020000ULL /* Do we have an up-to-date CIB */
402
403 # define R_MEMBERSHIP 0x00100000ULL /* Have we got cluster layer data yet */
404 # define R_PEER_DATA 0x00200000ULL /* Have we got T_CL_STATUS data yet */
405
406 # define R_HA_DISCONNECTED 0x00400000ULL /* did we sign out of our own accord */
407
408 # define R_REQ_PEND 0x01000000ULL
409 /* Are there Requests waiting for
410 processing? */
411 # define R_PE_PEND 0x02000000ULL // Are we awaiting reply from scheduler?
412 # define R_TE_PEND 0x04000000ULL
413 /* Has the TE been invoked and we're
414 awaiting completion? */
415 # define R_RESP_PEND 0x08000000ULL
416 /* Do we have clients waiting on a
417 response? if so perhaps we shouldn't
418 stop yet */
419
420 # define R_SENT_RSC_STOP 0x20000000ULL /* Have we sent a stop action to all
421 * resources in preparation for
422 * shutting down */
423
424 # define R_IN_RECOVERY 0x80000000ULL
425
426 #define CRM_DIRECT_NACK_RC (99) // Deprecated (see PCMK_EXEC_INVALID)
427
428 enum crmd_fsa_cause {
429 C_UNKNOWN = 0,
430 C_STARTUP,
431 C_IPC_MESSAGE,
432 C_HA_MESSAGE,
433 C_CRMD_STATUS_CALLBACK,
434 C_LRM_OP_CALLBACK,
435 C_TIMER_POPPED,
436 C_SHUTDOWN,
437 C_FSA_INTERNAL,
438 };
439
440 enum fsa_data_type {
441 fsa_dt_none,
442 fsa_dt_ha_msg,
443 fsa_dt_xml,
444 fsa_dt_lrm,
445 };
446
447 typedef struct fsa_data_s fsa_data_t;
448 struct fsa_data_s {
449 int id;
450 enum crmd_fsa_input fsa_input;
451 enum crmd_fsa_cause fsa_cause;
452 uint64_t actions;
453 const char *origin;
454 void *data;
455 enum fsa_data_type data_type;
456 };
457
458 #define controld_set_fsa_input_flags(flags_to_set) do { \
459 controld_globals.fsa_input_register \
460 = pcmk__set_flags_as(__func__, __LINE__, LOG_TRACE, \
461 "FSA input", "controller", \
462 controld_globals.fsa_input_register, \
463 (flags_to_set), #flags_to_set); \
464 } while (0)
465
466 #define controld_clear_fsa_input_flags(flags_to_clear) do { \
467 controld_globals.fsa_input_register \
468 = pcmk__clear_flags_as(__func__, __LINE__, LOG_TRACE, \
469 "FSA input", "controller", \
470 controld_globals.fsa_input_register, \
471 (flags_to_clear), \
472 #flags_to_clear); \
473 } while (0)
474
475 #define controld_set_fsa_action_flags(flags_to_set) do { \
476 controld_globals.fsa_actions \
477 = pcmk__set_flags_as(__func__, __LINE__, LOG_DEBUG, \
478 "FSA action", "controller", \
479 controld_globals.fsa_actions, \
480 (flags_to_set), #flags_to_set); \
481 } while (0)
482
483 #define controld_clear_fsa_action_flags(flags_to_clear) do { \
484 controld_globals.fsa_actions \
485 = pcmk__clear_flags_as(__func__, __LINE__, LOG_DEBUG, \
486 "FSA action", "controller", \
487 controld_globals.fsa_actions, \
488 (flags_to_clear), #flags_to_clear); \
489 } while (0)
490
491 // This should be moved elsewhere
492 xmlNode *controld_query_executor_state(void);
493
494 const char *fsa_input2string(enum crmd_fsa_input input);
495 const char *fsa_state2string(enum crmd_fsa_state state);
496 const char *fsa_cause2string(enum crmd_fsa_cause cause);
497 const char *fsa_action2string(long long action);
498
499 enum crmd_fsa_state s_crmd_fsa(enum crmd_fsa_cause cause);
500
501 enum crmd_fsa_state controld_fsa_get_next_state(enum crmd_fsa_input input);
502
503 uint64_t controld_fsa_get_action(enum crmd_fsa_input input);
504
505 void controld_init_fsa_trigger(void);
506 void controld_destroy_fsa_trigger(void);
507
508 void free_max_generation(void);
509
510 # define AM_I_DC pcmk_is_set(controld_globals.fsa_input_register, R_THE_DC)
511 # define controld_trigger_fsa() controld_trigger_fsa_as(__func__, __LINE__)
512
513 void controld_trigger_fsa_as(const char *fn, int line);
514
515 /* A_READCONFIG */
516 void do_read_config(long long action, enum crmd_fsa_cause cause,
517 enum crmd_fsa_state cur_state,
518 enum crmd_fsa_input current_input, fsa_data_t *msg_data);
519
520 /* A_PE_INVOKE */
521 void do_pe_invoke(long long action, enum crmd_fsa_cause cause,
522 enum crmd_fsa_state cur_state,
523 enum crmd_fsa_input current_input, fsa_data_t *msg_data);
524
525 /* A_LOG */
526 void do_log(long long action, enum crmd_fsa_cause cause,
527 enum crmd_fsa_state cur_state,
528 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
529
530 /* A_STARTUP */
531 void do_startup(long long action, enum crmd_fsa_cause cause,
532 enum crmd_fsa_state cur_state,
533 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
534
535 /* A_CIB_START, STOP, RESTART */
536 void do_cib_control(long long action, enum crmd_fsa_cause cause,
537 enum crmd_fsa_state cur_state,
538 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
539
540 /* A_HA_CONNECT */
541 void do_ha_control(long long action, enum crmd_fsa_cause cause,
542 enum crmd_fsa_state cur_state,
543 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
544
545 /* A_LRM_CONNECT */
546 void do_lrm_control(long long action, enum crmd_fsa_cause cause,
547 enum crmd_fsa_state cur_state,
548 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
549
550 /* A_PE_START, STOP, RESTART */
551 void do_pe_control(long long action, enum crmd_fsa_cause cause,
552 enum crmd_fsa_state cur_state,
553 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
554
555 /* A_TE_START, STOP, RESTART */
556 void do_te_control(long long action, enum crmd_fsa_cause cause,
557 enum crmd_fsa_state cur_state,
558 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
559
560 /* A_STARTED */
561 void do_started(long long action, enum crmd_fsa_cause cause,
562 enum crmd_fsa_state cur_state,
563 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
564
565 /* A_MSG_ROUTE */
566 void do_msg_route(long long action, enum crmd_fsa_cause cause,
567 enum crmd_fsa_state cur_state,
568 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
569
570 /* A_RECOVER */
571 void do_recover(long long action, enum crmd_fsa_cause cause,
572 enum crmd_fsa_state cur_state,
573 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
574
575 /* A_ELECTION_VOTE */
576 void do_election_vote(long long action, enum crmd_fsa_cause cause,
577 enum crmd_fsa_state cur_state,
578 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
579
580 /* A_ELECTION_COUNT */
581 void do_election_count_vote(long long action, enum crmd_fsa_cause cause,
582 enum crmd_fsa_state cur_state,
583 enum crmd_fsa_input cur_input,
584 fsa_data_t *msg_data);
585
586 /* A_ELECTION_CHECK */
587 void do_election_check(long long action, enum crmd_fsa_cause cause,
588 enum crmd_fsa_state cur_state,
589 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
590
591 /* A_DC_TIMER_STOP */
592 void do_timer_control(long long action, enum crmd_fsa_cause cause,
593 enum crmd_fsa_state cur_state,
594 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
595
596 /* A_DC_TAKEOVER */
597 void do_dc_takeover(long long action, enum crmd_fsa_cause cause,
598 enum crmd_fsa_state cur_state,
599 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
600
601 /* A_DC_RELEASE */
602 void do_dc_release(long long action, enum crmd_fsa_cause cause,
603 enum crmd_fsa_state cur_state,
604 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
605
606 /* A_DC_JOIN_OFFER_ALL */
607 void do_dc_join_offer_all(long long action, enum crmd_fsa_cause cause,
608 enum crmd_fsa_state cur_state,
609 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
610
611 /* A_DC_JOIN_OFFER_ONE */
612 void do_dc_join_offer_one(long long action, enum crmd_fsa_cause cause,
613 enum crmd_fsa_state cur_state,
614 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
615
616 /* A_DC_JOIN_ACK */
617 void do_dc_join_ack(long long action, enum crmd_fsa_cause cause,
618 enum crmd_fsa_state cur_state,
619 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
620
621 /* A_DC_JOIN_REQ */
622 void do_dc_join_filter_offer(long long action, enum crmd_fsa_cause cause,
623 enum crmd_fsa_state cur_state,
624 enum crmd_fsa_input cur_input,
625 fsa_data_t *msg_data);
626
627 /* A_DC_JOIN_FINALIZE */
628 void do_dc_join_finalize(long long action, enum crmd_fsa_cause cause,
629 enum crmd_fsa_state cur_state,
630 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
631
632 /* A_CL_JOIN_QUERY */
633 /* is there a DC out there? */
634 void do_cl_join_query(long long action, enum crmd_fsa_cause cause,
635 enum crmd_fsa_state cur_state,
636 enum crmd_fsa_input current_input, fsa_data_t *msg_data);
637
638 /* A_CL_JOIN_ANNOUNCE */
639 void do_cl_join_announce(long long action, enum crmd_fsa_cause cause,
640 enum crmd_fsa_state cur_state,
641 enum crmd_fsa_input current_input, fsa_data_t *msg_data);
642
643 /* A_CL_JOIN_REQUEST */
644 void do_cl_join_offer_respond(long long action, enum crmd_fsa_cause cause,
645 enum crmd_fsa_state cur_state,
646 enum crmd_fsa_input current_input,
647 fsa_data_t *msg_data);
648
649 /* A_CL_JOIN_RESULT */
650 void do_cl_join_finalize_respond(long long action, enum crmd_fsa_cause cause,
651 enum crmd_fsa_state cur_state,
652 enum crmd_fsa_input current_input,
653 fsa_data_t *msg_data);
654
655 /* A_LRM_INVOKE */
656 void do_lrm_invoke(long long action, enum crmd_fsa_cause cause,
657 enum crmd_fsa_state cur_state,
658 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
659
660 /* A_LRM_EVENT */
661 void do_lrm_event(long long action, enum crmd_fsa_cause cause,
662 enum crmd_fsa_state cur_state,
663 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
664
665 /* A_TE_INVOKE, A_TE_CANCEL */
666 void do_te_invoke(long long action, enum crmd_fsa_cause cause,
667 enum crmd_fsa_state cur_state,
668 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
669
670 /* A_SHUTDOWN_REQ */
671 void do_shutdown_req(long long action, enum crmd_fsa_cause cause,
672 enum crmd_fsa_state cur_state,
673 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
674
675 /* A_SHUTDOWN */
676 void do_shutdown(long long action, enum crmd_fsa_cause cause,
677 enum crmd_fsa_state cur_state,
678 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
679
680 /* A_STOP */
681 void do_stop(long long action, enum crmd_fsa_cause cause,
682 enum crmd_fsa_state cur_state,
683 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
684
685 /* A_EXIT_0, A_EXIT_1 */
686 void do_exit(long long action, enum crmd_fsa_cause cause,
687 enum crmd_fsa_state cur_state,
688 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
689
690 /* A_DC_JOIN_FINAL */
691 void do_dc_join_final(long long action, enum crmd_fsa_cause cause,
692 enum crmd_fsa_state cur_state,
693 enum crmd_fsa_input current_input, fsa_data_t *msg_data);
694 #endif