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 #ifndef CONTROLD_LRM__H
10 #  define CONTROLD_LRM__H
11 
12 #include <controld_messages.h>
13 
14 extern gboolean verify_stopped(enum crmd_fsa_state cur_state, int log_level);
15 void lrm_clear_last_failure(const char *rsc_id, const char *node_name,
16                             const char *operation, guint interval_ms);
17 void lrm_op_callback(lrmd_event_data_t * op);
18 lrmd_t *crmd_local_lrmd_conn(void);
19 
20 typedef struct resource_history_s {
21     char *id;
22     uint32_t last_callid;
23     lrmd_rsc_info_t rsc;
24     lrmd_event_data_t *last;
25     lrmd_event_data_t *failed;
26     GList *recurring_op_list;
27 
28     /* Resources must be stopped using the same
29      * parameters they were started with.  This hashtable
30      * holds the parameters that should be used for the next stop
31      * cmd on this resource. */
32     GHashTable *stop_params;
33 } rsc_history_t;
34 
35 void history_free(gpointer data);
36 
37 enum active_op_e {
38     active_op_remove    = (1 << 0),
39     active_op_cancelled = (1 << 1),
40 };
41 
42 // In-flight action (recurring or pending)
43 typedef struct active_op_s {
44     guint interval_ms;
45     int call_id;
46     uint32_t flags; // bitmask of active_op_e
47     time_t start_time;
48     time_t lock_time;
49     char *rsc_id;
50     char *op_type;
51     char *op_key;
52     char *user_data;
53     GHashTable *params;
54 } active_op_t;
55 
56 #define controld_set_active_op_flags(active_op, flags_to_set) do {          \
57         (active_op)->flags = pcmk__set_flags_as(__func__, __LINE__,         \
58             LOG_TRACE, "Active operation", (active_op)->op_key,             \
59             (active_op)->flags, (flags_to_set), #flags_to_set);             \
60     } while (0)
61 
62 #define controld_clear_active_op_flags(active_op, flags_to_clear) do {      \
63         (active_op)->flags = pcmk__clear_flags_as(__func__, __LINE__,       \
64             LOG_TRACE, "Active operation", (active_op)->op_key,             \
65             (active_op)->flags, (flags_to_clear), #flags_to_clear);         \
66     } while (0)
67 
68 typedef struct lrm_state_s {
69     const char *node_name;
70     void *conn;                 // Reserved for controld_execd_state.c usage
71     void *remote_ra_data;       // Reserved for controld_remote_ra.c usage
72 
73     GHashTable *resource_history;
74     GHashTable *pending_ops;
75     GHashTable *deletion_ops;
76     GHashTable *rsc_info_cache;
77     GHashTable *metadata_cache; // key = class[:provider]:agent, value = ra_metadata_s
78 
79     int num_lrm_register_fails;
80 } lrm_state_t;
81 
82 struct pending_deletion_op_s {
83     char *rsc;
84     ha_msg_input_t *input;
85 };
86 
87 /*!
88  * \brief Check whether this the local IPC connection to the executor
89  */
90 gboolean
91 lrm_state_is_local(lrm_state_t *lrm_state);
92 
93 /*!
94  * \brief Clear all state information from a single state entry.
95  * \note It sometimes useful to save metadata cache when it won't go stale.
96  * \note This does not close the executor connection
97  */
98 void lrm_state_reset_tables(lrm_state_t * lrm_state, gboolean reset_metadata);
99 GList *lrm_state_get_list(void);
100 
101 /*!
102  * \brief Initiate internal state tables
103  */
104 gboolean lrm_state_init_local(void);
105 
106 /*!
107  * \brief Destroy all state entries and internal state tables
108  */
109 void lrm_state_destroy_all(void);
110 
111 /*!
112  * \brief Create executor connection entry
113  */
114 lrm_state_t *lrm_state_create(const char *node_name);
115 
116 /*!
117  * \brief Destroy executor connection by node name
118  */
119 void lrm_state_destroy(const char *node_name);
120 
121 /*!
122  * \brief Find lrm_state data by node name
123  */
124 lrm_state_t *lrm_state_find(const char *node_name);
125 
126 /*!
127  * \brief Either find or create a new entry
128  */
129 lrm_state_t *lrm_state_find_or_create(const char *node_name);
130 
131 /*!
132  * The functions below are wrappers for the executor API the the controller
133  * uses. These wrapper functions allow us to treat the controller's remote
134  * executor connection resources the same as regular resources. Internally,
135  * regular resources go to the executor, and remote connection resources are
136  * handled locally in the controller.
137  */
138 void lrm_state_disconnect_only(lrm_state_t * lrm_state);
139 void lrm_state_disconnect(lrm_state_t * lrm_state);
140 int lrm_state_ipc_connect(lrm_state_t * lrm_state);
141 int lrm_state_remote_connect_async(lrm_state_t * lrm_state, const char *server, int port,
142                                    int timeout);
143 int lrm_state_is_connected(lrm_state_t * lrm_state);
144 int lrm_state_poke_connection(lrm_state_t * lrm_state);
145 
146 int lrm_state_get_metadata(lrm_state_t * lrm_state,
147                            const char *class,
148                            const char *provider,
149                            const char *agent, char **output, enum lrmd_call_options options);
150 int lrm_state_cancel(lrm_state_t *lrm_state, const char *rsc_id,
151                      const char *action, guint interval_ms);
152 int lrm_state_exec(lrm_state_t *lrm_state, const char *rsc_id,
153                    const char *action, const char *userdata, guint interval_ms,
154                    int timeout, /* ms */
155                    int start_delay,     /* ms */
156                    lrmd_key_value_t * params);
157 lrmd_rsc_info_t *lrm_state_get_rsc_info(lrm_state_t * lrm_state,
158                                         const char *rsc_id, enum lrmd_call_options options);
159 int lrm_state_register_rsc(lrm_state_t * lrm_state,
160                            const char *rsc_id,
161                            const char *class,
162                            const char *provider, const char *agent, enum lrmd_call_options options);
163 int lrm_state_unregister_rsc(lrm_state_t * lrm_state,
164                              const char *rsc_id, enum lrmd_call_options options);
165 
166 // Functions used to manage remote executor connection resources
167 void remote_lrm_op_callback(lrmd_event_data_t * op);
168 gboolean is_remote_lrmd_ra(const char *agent, const char *provider, const char *id);
169 lrmd_rsc_info_t *remote_ra_get_rsc_info(lrm_state_t * lrm_state, const char *rsc_id);
170 int remote_ra_cancel(lrm_state_t *lrm_state, const char *rsc_id,
171                      const char *action, guint interval_ms);
172 int remote_ra_exec(lrm_state_t *lrm_state, const char *rsc_id,
173                    const char *action, const char *userdata, guint interval_ms,
174                    int timeout, /* ms */
175                    int start_delay,     /* ms */
176                    lrmd_key_value_t * params);
177 void remote_ra_cleanup(lrm_state_t * lrm_state);
178 void remote_ra_fail(const char *node_name);
179 void remote_ra_process_pseudo(xmlNode *xml);
180 gboolean remote_ra_is_in_maintenance(lrm_state_t * lrm_state);
181 void remote_ra_process_maintenance_nodes(xmlNode *xml);
182 gboolean remote_ra_controlling_guest(lrm_state_t * lrm_state);
183 
184 void process_lrm_event(lrm_state_t *lrm_state, lrmd_event_data_t *op,
185                        active_op_t *pending, xmlNode *action_xml);
186 void controld_ack_event_directly(const char *to_host, const char *to_sys,
187                                  lrmd_rsc_info_t *rsc, lrmd_event_data_t *op,
188                                  const char *rsc_id);
189 void controld_rc2event(lrmd_event_data_t *event, int rc);
190 void controld_trigger_delete_refresh(const char *from_sys, const char *rsc_id);
191 
192 #endif
193