1 /*
2  * Copyright 2004-2021 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 #  define R_CIB_ASKED       0x00040000ULL   /* Have we asked for an up-to-date CIB */
403 
404 #  define R_MEMBERSHIP      0x00100000ULL   /* Have we got cluster layer data yet */
405 #  define R_PEER_DATA       0x00200000ULL   /* Have we got T_CL_STATUS data yet */
406 
407 #  define R_HA_DISCONNECTED 0x00400000ULL      /* did we sign out of our own accord */
408 
409 #  define R_REQ_PEND        0x01000000ULL
410                                         /* Are there Requests waiting for
411                                            processing? */
412 #  define R_PE_PEND         0x02000000ULL   // Are we awaiting reply from scheduler?
413 #  define R_TE_PEND         0x04000000ULL
414                                         /* Has the TE been invoked and we're
415                                            awaiting completion? */
416 #  define R_RESP_PEND       0x08000000ULL
417                                         /* Do we have clients waiting on a
418                                            response? if so perhaps we shouldn't
419                                            stop yet */
420 
421 #  define R_IN_TRANSITION   0x10000000ULL
422                                         /*  */
423 #  define R_SENT_RSC_STOP   0x20000000ULL /* Have we sent a stop action to all
424                                          * resources in preparation for
425                                          * shutting down */
426 
427 #  define R_IN_RECOVERY     0x80000000ULL
428 
429 #define CRM_DIRECT_NACK_RC (99) // Deprecated (see PCMK_LRM_OP_INVALID)
430 
431 enum crmd_fsa_cause {
432     C_UNKNOWN = 0,
433     C_STARTUP,
434     C_IPC_MESSAGE,
435     C_HA_MESSAGE,
436     C_CRMD_STATUS_CALLBACK,
437     C_LRM_OP_CALLBACK,
438     C_TIMER_POPPED,
439     C_SHUTDOWN,
440     C_FSA_INTERNAL,
441 };
442 
443 enum fsa_data_type {
444     fsa_dt_none,
445     fsa_dt_ha_msg,
446     fsa_dt_xml,
447     fsa_dt_lrm,
448 };
449 
450 typedef struct fsa_data_s fsa_data_t;
451 struct fsa_data_s {
452     int id;
453     enum crmd_fsa_input fsa_input;
454     enum crmd_fsa_cause fsa_cause;
455     uint64_t actions;
456     const char *origin;
457     void *data;
458     enum fsa_data_type data_type;
459 };
460 
461 /* Global FSA stuff */
462 extern gboolean do_fsa_stall;
463 extern enum crmd_fsa_state fsa_state;
464 extern uint64_t fsa_input_register;
465 extern uint64_t fsa_actions;
466 
467 #define controld_set_fsa_input_flags(flags_to_set) do {                     \
468         fsa_input_register = pcmk__set_flags_as(__func__, __LINE__,         \
469                                                 LOG_TRACE,                  \
470                                                 "FSA input", "controller",  \
471                                                 fsa_input_register,         \
472                                                 (flags_to_set),             \
473                                                 #flags_to_set);             \
474     } while (0)
475 
476 #define controld_clear_fsa_input_flags(flags_to_clear) do {                 \
477         fsa_input_register = pcmk__clear_flags_as(__func__, __LINE__,       \
478                                                   LOG_TRACE,                \
479                                                   "FSA input", "controller",\
480                                                   fsa_input_register,       \
481                                                   (flags_to_clear),         \
482                                                   #flags_to_clear);         \
483     } while (0)
484 
485 #define controld_set_fsa_action_flags(flags_to_set) do {                    \
486         fsa_actions = pcmk__set_flags_as(__func__, __LINE__,                \
487                                          LOG_DEBUG,                         \
488                                          "FSA action", "controller",        \
489                                          fsa_actions, (flags_to_set),       \
490                                          #flags_to_set);                    \
491     } while (0)
492 
493 #define controld_clear_fsa_action_flags(flags_to_clear) do {                \
494         fsa_actions = pcmk__clear_flags_as(__func__, __LINE__,              \
495                                            LOG_DEBUG,                       \
496                                            "FSA action", "controller",      \
497                                            fsa_actions, (flags_to_clear),   \
498                                            #flags_to_clear);                \
499     } while (0)
500 
501 extern cib_t *fsa_cib_conn;
502 
503 extern char *fsa_our_uname;
504 extern char *fsa_our_uuid;
505 extern char *fsa_pe_ref;        // Last invocation of the scheduler
506 extern char *fsa_our_dc;
507 extern char *fsa_our_dc_version;
508 extern GList *fsa_message_queue;
509 
510 extern char *fsa_cluster_name;
511 
512 extern crm_trigger_t *fsa_source;
513 extern crm_trigger_t *config_read;
514 
515 extern unsigned long long saved_ccm_membership_id;
516 extern gboolean ever_had_quorum;
517 
518 // These should be moved elsewhere
519 void do_update_cib_nodes(gboolean overwrite, const char *caller);
520 int crmd_cib_smart_opt(void);
521 xmlNode *controld_query_executor_state(const char *node_name);
522 
523 const char *fsa_input2string(enum crmd_fsa_input input);
524 const char *fsa_state2string(enum crmd_fsa_state state);
525 const char *fsa_cause2string(enum crmd_fsa_cause cause);
526 const char *fsa_action2string(long long action);
527 
528 enum crmd_fsa_state s_crmd_fsa(enum crmd_fsa_cause cause);
529 
530 #  define AM_I_DC pcmk_is_set(fsa_input_register, R_THE_DC)
531 #  define AM_I_OPERATIONAL !pcmk_is_set(fsa_input_register, R_STARTING)
532 #  define trigger_fsa() do {                    \
533         if (fsa_source != NULL) {               \
534             crm_trace("Triggering FSA");        \
535             mainloop_set_trigger(fsa_source);   \
536         }                                       \
537     } while(0)
538 
539 /* A_READCONFIG */
540 void do_read_config(long long action, enum crmd_fsa_cause cause,
541                     enum crmd_fsa_state cur_state,
542                     enum crmd_fsa_input current_input, fsa_data_t *msg_data);
543 
544 /* A_PE_INVOKE */
545 void do_pe_invoke(long long action, enum crmd_fsa_cause cause,
546                   enum crmd_fsa_state cur_state,
547                   enum crmd_fsa_input current_input, fsa_data_t *msg_data);
548 
549 /* A_LOG */
550 void do_log(long long action, enum crmd_fsa_cause cause,
551             enum crmd_fsa_state cur_state,
552             enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
553 
554 /* A_STARTUP */
555 void do_startup(long long action, enum crmd_fsa_cause cause,
556                 enum crmd_fsa_state cur_state,
557                 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
558 
559 /* A_CIB_START, STOP, RESTART */
560 void do_cib_control(long long action, enum crmd_fsa_cause cause,
561                     enum crmd_fsa_state cur_state,
562                     enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
563 
564 /* A_HA_CONNECT */
565 void do_ha_control(long long action, enum crmd_fsa_cause cause,
566                    enum crmd_fsa_state cur_state,
567                    enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
568 
569 /* A_LRM_CONNECT */
570 void do_lrm_control(long long action, enum crmd_fsa_cause cause,
571                     enum crmd_fsa_state cur_state,
572                     enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
573 
574 /* A_PE_START, STOP, RESTART */
575 void do_pe_control(long long action, enum crmd_fsa_cause cause,
576                    enum crmd_fsa_state cur_state,
577                    enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
578 
579 /* A_TE_START, STOP, RESTART */
580 void do_te_control(long long action, enum crmd_fsa_cause cause,
581                    enum crmd_fsa_state cur_state,
582                    enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
583 
584 /* A_STARTED */
585 void do_started(long long action, enum crmd_fsa_cause cause,
586                 enum crmd_fsa_state cur_state,
587                 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
588 
589 /* A_MSG_ROUTE */
590 void do_msg_route(long long action, enum crmd_fsa_cause cause,
591                   enum crmd_fsa_state cur_state,
592                   enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
593 
594 /* A_RECOVER */
595 void do_recover(long long action, enum crmd_fsa_cause cause,
596                 enum crmd_fsa_state cur_state,
597                 enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
598 
599 /* A_ELECTION_VOTE */
600 void do_election_vote(long long action, enum crmd_fsa_cause cause,
601                       enum crmd_fsa_state cur_state,
602                       enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
603 
604 /* A_ELECTION_COUNT */
605 void do_election_count_vote(long long action, enum crmd_fsa_cause cause,
606                             enum crmd_fsa_state cur_state,
607                             enum crmd_fsa_input cur_input,
608                             fsa_data_t *msg_data);
609 
610 /* A_ELECTION_CHECK */
611 void do_election_check(long long action, enum crmd_fsa_cause cause,
612                        enum crmd_fsa_state cur_state,
613                        enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
614 
615 /* A_DC_TIMER_STOP */
616 void do_timer_control(long long action, enum crmd_fsa_cause cause,
617                       enum crmd_fsa_state cur_state,
618                       enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
619 
620 /* A_DC_TAKEOVER */
621 void do_dc_takeover(long long action, enum crmd_fsa_cause cause,
622                     enum crmd_fsa_state cur_state,
623                     enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
624 
625 /* A_DC_RELEASE */
626 void do_dc_release(long long action, enum crmd_fsa_cause cause,
627                    enum crmd_fsa_state cur_state,
628                    enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
629 
630 /* A_DC_JOIN_OFFER_ALL */
631 void do_dc_join_offer_all(long long action, enum crmd_fsa_cause cause,
632                           enum crmd_fsa_state cur_state,
633                           enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
634 
635 /* A_DC_JOIN_OFFER_ONE */
636 void do_dc_join_offer_one(long long action, enum crmd_fsa_cause cause,
637                           enum crmd_fsa_state cur_state,
638                           enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
639 
640 /* A_DC_JOIN_ACK */
641 void do_dc_join_ack(long long action, enum crmd_fsa_cause cause,
642                     enum crmd_fsa_state cur_state,
643                     enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
644 
645 /* A_DC_JOIN_REQ */
646 void do_dc_join_filter_offer(long long action, enum crmd_fsa_cause cause,
647                              enum crmd_fsa_state cur_state,
648                              enum crmd_fsa_input cur_input,
649                              fsa_data_t *msg_data);
650 
651 /* A_DC_JOIN_FINALIZE */
652 void do_dc_join_finalize(long long action, enum crmd_fsa_cause cause,
653                          enum crmd_fsa_state cur_state,
654                          enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
655 
656 /* A_CL_JOIN_QUERY */
657 /* is there a DC out there? */
658 void do_cl_join_query(long long action, enum crmd_fsa_cause cause,
659                       enum crmd_fsa_state cur_state,
660                       enum crmd_fsa_input current_input, fsa_data_t *msg_data);
661 
662 /* A_CL_JOIN_ANNOUNCE */
663 void do_cl_join_announce(long long action, enum crmd_fsa_cause cause,
664                          enum crmd_fsa_state cur_state,
665                          enum crmd_fsa_input current_input, fsa_data_t *msg_data);
666 
667 /* A_CL_JOIN_REQUEST */
668 void do_cl_join_offer_respond(long long action, enum crmd_fsa_cause cause,
669                               enum crmd_fsa_state cur_state,
670                               enum crmd_fsa_input current_input,
671                               fsa_data_t *msg_data);
672 
673 /* A_CL_JOIN_RESULT */
674 void do_cl_join_finalize_respond(long long action, enum crmd_fsa_cause cause,
675                                  enum crmd_fsa_state cur_state,
676                                  enum crmd_fsa_input current_input,
677                                  fsa_data_t *msg_data);
678 
679 /* A_LRM_INVOKE */
680 void do_lrm_invoke(long long action, enum crmd_fsa_cause cause,
681                    enum crmd_fsa_state cur_state,
682                    enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
683 
684 /* A_LRM_EVENT */
685 void do_lrm_event(long long action, enum crmd_fsa_cause cause,
686                   enum crmd_fsa_state cur_state,
687                   enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
688 
689 /* A_TE_INVOKE, A_TE_CANCEL */
690 void do_te_invoke(long long action, enum crmd_fsa_cause cause,
691                   enum crmd_fsa_state cur_state,
692                   enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
693 
694 /* A_SHUTDOWN_REQ */
695 void do_shutdown_req(long long action, enum crmd_fsa_cause cause,
696                      enum crmd_fsa_state cur_state,
697                      enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
698 
699 /* A_SHUTDOWN */
700 void do_shutdown(long long action, enum crmd_fsa_cause cause,
701                  enum crmd_fsa_state cur_state,
702                  enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
703 
704 /* A_STOP */
705 void do_stop(long long action, enum crmd_fsa_cause cause,
706              enum crmd_fsa_state cur_state,
707              enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
708 
709 /* A_EXIT_0, A_EXIT_1 */
710 void do_exit(long long action, enum crmd_fsa_cause cause,
711              enum crmd_fsa_state cur_state,
712              enum crmd_fsa_input cur_input, fsa_data_t *msg_data);
713 
714 /* A_DC_JOIN_FINAL */
715 void do_dc_join_final(long long action, enum crmd_fsa_cause cause,
716                       enum crmd_fsa_state cur_state,
717                       enum crmd_fsa_input current_input, fsa_data_t *msg_data);
718 #endif
719