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 PCMK__CRM_CIB_CIB_TYPES__H
11 # define PCMK__CRM_CIB_CIB_TYPES__H
12
13 # include <glib.h> // gboolean, GList
14 # include <libxml/tree.h> // xmlNode
15 # include <crm/common/ipc.h>
16 # include <crm/common/xml.h>
17
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21
22 /**
23 * \file
24 * \brief Data types for Cluster Information Base access
25 * \ingroup cib
26 */
27
28 enum cib_variant {
29 cib_undefined = 0,
30 cib_native = 1,
31 cib_file = 2,
32 cib_remote = 3,
33
34 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
35 //! \deprecated This value will be removed in a future release
36 cib_database = 4,
37 #endif // !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
38 };
39
40 enum cib_state {
41 cib_connected_command,
42 cib_connected_query,
43 cib_disconnected
44 };
45
46 enum cib_conn_type {
47 cib_command,
48 cib_query,
49 cib_no_connection,
50 cib_command_nonblocking,
51 };
52
53 enum cib_call_options {
54 cib_none = 0,
55 cib_verbose = (1 << 0), //!< Prefer stderr to logs
56 cib_xpath = (1 << 1),
57 cib_multiple = (1 << 2),
58 cib_can_create = (1 << 3),
59 cib_discard_reply = (1 << 4),
60 cib_no_children = (1 << 5),
61 cib_xpath_address = (1 << 6),
62
63 //! \deprecated This value will be removed in a future release
64 cib_mixed_update = (1 << 7),
65
66 /* @COMPAT: cib_scope_local is processed only in the legacy function
67 * parse_local_options_v1().
68 *
69 * If (host == NULL):
70 * * In legacy mode, the CIB manager forwards a request to the primary
71 * instance unless cib_scope_local is set or the local node is primary.
72 * * Outside of legacy mode:
73 * * If a request modifies the CIB, the CIB manager forwards it to all
74 * nodes.
75 * * Otherwise, the CIB manager processes the request locally.
76 *
77 * There is no current use case for this implementing this flag in
78 * non-legacy mode.
79 */
80
81 //! \deprecated This value will be removed in a future release
82 cib_scope_local = (1 << 8),
83
84 cib_dryrun = (1 << 9),
85
86 /*!
87 * \brief Process request when the client commits the active transaction
88 *
89 * Add the request to the client's active transaction instead of processing
90 * it immediately. If the client has no active transaction, or if the
91 * request is not supported in transactions, the call will fail.
92 *
93 * The request is added to the transaction synchronously, and the return
94 * value indicates whether it was added successfully.
95 *
96 * Refer to \p cib_api_operations_t:init_transaction() and
97 * \p cib_api_operations_t:end_transaction() for more details on CIB
98 * transactions.
99 */
100 cib_transaction = (1 << 10),
101
102 cib_sync_call = (1 << 12),
103 cib_no_mtime = (1 << 13),
104
105 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
106 //! \deprecated This value will be removed in a future release
107 cib_zero_copy = (1 << 14),
108 #endif // !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
109
110 cib_inhibit_notify = (1 << 16),
111
112 #if !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
113 //! \deprecated This value will be removed in a future release
114 cib_quorum_override = (1 << 20),
115 #endif // !defined(PCMK_ALLOW_DEPRECATED) || (PCMK_ALLOW_DEPRECATED == 1)
116
117 //! \deprecated This value will be removed in a future release
118 cib_inhibit_bcast = (1 << 24),
119
120 cib_force_diff = (1 << 28),
121 };
122
123 typedef struct cib_s cib_t;
124
125 typedef struct cib_api_operations_s {
126 int (*signon) (cib_t *cib, const char *name, enum cib_conn_type type);
127
128 //! \deprecated This method will be removed and should not be used
129 int (*signon_raw) (cib_t *cib, const char *name, enum cib_conn_type type,
130 int *event_fd);
131
132 int (*signoff) (cib_t *cib);
133 int (*free) (cib_t *cib);
134
135 //! \deprecated This method will be removed and should not be used
136 int (*set_op_callback) (cib_t *cib, void (*callback) (const xmlNode *msg,
137 int callid, int rc,
138 xmlNode *output));
139
140 int (*add_notify_callback) (cib_t *cib, const char *event,
141 void (*callback) (const char *event,
142 xmlNode *msg));
143 int (*del_notify_callback) (cib_t *cib, const char *event,
144 void (*callback) (const char *event,
145 xmlNode *msg));
146 int (*set_connection_dnotify) (cib_t *cib,
147 void (*dnotify) (gpointer user_data));
148
149 //! \deprecated This method will be removed and should not be used
150 int (*inputfd) (cib_t *cib);
151
152 //! \deprecated This method will be removed and should not be used
153 int (*noop) (cib_t *cib, int call_options);
154
155 int (*ping) (cib_t *cib, xmlNode **output_data, int call_options);
156 int (*query) (cib_t *cib, const char *section, xmlNode **output_data,
157 int call_options);
158 int (*query_from) (cib_t *cib, const char *host, const char *section,
159 xmlNode **output_data, int call_options);
160
161 //! \deprecated This method will be removed and should not be used
162 int (*is_master) (cib_t *cib);
163
164 //! \deprecated Use the set_primary() method instead
165 int (*set_master) (cib_t *cib, int call_options);
166
167 //! \deprecated Use the set_secondary() method instead
168 int (*set_slave) (cib_t *cib, int call_options);
169
170 //! \deprecated This method will be removed and should not be used
171 int (*set_slave_all) (cib_t *cib, int call_options);
172
173 int (*sync) (cib_t *cib, const char *section, int call_options);
174 int (*sync_from) (cib_t *cib, const char *host, const char *section,
175 int call_options);
176 int (*upgrade) (cib_t *cib, int call_options);
177 int (*bump_epoch) (cib_t *cib, int call_options);
178 int (*create) (cib_t *cib, const char *section, xmlNode *data,
179 int call_options);
180 int (*modify) (cib_t *cib, const char *section, xmlNode *data,
181 int call_options);
182
183 //! \deprecated Use the \p modify() method instead
184 int (*update) (cib_t *cib, const char *section, xmlNode *data,
185 int call_options);
186
187 int (*replace) (cib_t *cib, const char *section, xmlNode *data,
188 int call_options);
189 int (*remove) (cib_t *cib, const char *section, xmlNode *data,
190 int call_options);
191 int (*erase) (cib_t *cib, xmlNode **output_data, int call_options);
192
193 //! \deprecated This method does nothing and should not be called
194 int (*delete_absolute) (cib_t *cib, const char *section, xmlNode *data,
195 int call_options);
196
197 //! \deprecated This method is not implemented and should not be used
198 int (*quit) (cib_t *cib, int call_options);
199
200 int (*register_notification) (cib_t *cib, const char *callback,
201 int enabled);
202 gboolean (*register_callback) (cib_t *cib, int call_id, int timeout,
203 gboolean only_success, void *user_data,
204 const char *callback_name,
205 void (*callback) (xmlNode*, int, int,
206 xmlNode*, void *));
207 gboolean (*register_callback_full)(cib_t *cib, int call_id, int timeout,
208 gboolean only_success, void *user_data,
209 const char *callback_name,
210 void (*callback)(xmlNode *, int, int,
211 xmlNode *, void *),
212 void (*free_func)(void *));
213
214 /*!
215 * \brief Set the local CIB manager as the cluster's primary instance
216 *
217 * \param[in,out] cib CIB connection
218 * \param[in] call_options Group of enum cib_call_options flags
219 *
220 * \return Legacy Pacemaker return code (in particular, pcmk_ok on success)
221 */
222 int (*set_primary)(cib_t *cib, int call_options);
223
224 /*!
225 * \brief Set the local CIB manager as a secondary instance
226 *
227 * \param[in,out] cib CIB connection
228 * \param[in] call_options Group of enum cib_call_options flags
229 *
230 * \return Legacy Pacemaker return code (in particular, pcmk_ok on success)
231 */
232 int (*set_secondary)(cib_t *cib, int call_options);
233
234 /*!
235 * \brief Get the given CIB connection's unique client identifier(s)
236 *
237 * These can be used to check whether this client requested the action that
238 * triggered a CIB notification.
239 *
240 * \param[in] cib CIB connection
241 * \param[out] async_id If not \p NULL, where to store asynchronous client
242 * ID
243 * \param[out] sync_id If not \p NULL, where to store synchronous client
244 * ID
245 *
246 * \return Legacy Pacemaker return code
247 *
248 * \note Some variants may have only one client for both asynchronous and
249 * synchronous requests.
250 */
251 int (*client_id)(const cib_t *cib, const char **async_id,
252 const char **sync_id);
253
254 /*!
255 * \brief Initiate an atomic CIB transaction for this client
256 *
257 * If the client has initiated a transaction and a new request's call
258 * options contain \p cib_transaction, the new request is appended to the
259 * transaction for later processing.
260 *
261 * Supported requests are those that meet the following conditions:
262 * * can be processed synchronously (with any changes applied to a working
263 * CIB copy)
264 * * are not queries
265 * * do not involve other nodes
266 * * do not affect the state of pacemaker-based itself
267 *
268 * Currently supported CIB API functions include:
269 * * \p bump_epoch()
270 * * \p create()
271 * * \p erase()
272 * * \p modify()
273 * * \p remove()
274 * * \p replace()
275 * * \p upgrade()
276 *
277 * Because the transaction is atomic, individual requests do not trigger
278 * callbacks or notifications when they are processed, and they do not
279 * receive output XML. The commit request itself can trigger callbacks and
280 * notifications if any are registered.
281 *
282 * An \c init_transaction() call is always synchronous.
283 *
284 * \param[in,out] cib CIB connection
285 *
286 * \return Legacy Pacemaker return code
287 */
288 int (*init_transaction)(cib_t *cib);
289
290 /*!
291 * \brief End and optionally commit this client's CIB transaction
292 *
293 * When a client commits a transaction, all requests in the transaction are
294 * processed in a FIFO manner until either a request fails or all requests
295 * have been processed. Changes are applied to a working copy of the CIB.
296 * If a request fails, the transaction and working CIB copy are discarded,
297 * and an error is returned. If all requests succeed, the working CIB copy
298 * replaces the initial CIB copy.
299 *
300 * Callbacks and notifications can be triggered by the commit request itself
301 * but not by the individual requests in a transaction.
302 *
303 * An \c end_transaction() call with \p commit set to \c false is always
304 * synchronous.
305 *
306 * \param[in,out] cib CIB connection
307 * \param[in] commit If \p true, commit transaction; otherwise,
308 * discard it
309 * \param[in] call_options Group of <tt>enum cib_call_options</tt>
310 * flags
311 *
312 * \return Legacy Pacemaker return code
313 */
314 int (*end_transaction)(cib_t *cib, bool commit, int call_options);
315
316 /*!
317 * \brief Set the user as whom all CIB requests via methods will be executed
318 *
319 * By default, the value of the \c CIB_user environment variable is used if
320 * set. Otherwise, \c root is used.
321 *
322 * \param[in,out] cib CIB connection
323 * \param[in] user Name of user whose permissions to use when
324 * processing requests
325 */
326 void (*set_user)(cib_t *cib, const char *user);
327 } cib_api_operations_t;
328
329 struct cib_s {
330 enum cib_state state;
331 enum cib_conn_type type;
332 enum cib_variant variant;
333
334 int call_id;
335 int call_timeout;
336 void *variant_opaque;
337 void *delegate_fn;
338
339 GList *notify_list;
340
341 //! \deprecated This method will be removed in a future release
342 void (*op_callback) (const xmlNode *msg, int call_id, int rc,
343 xmlNode *output);
344
345 cib_api_operations_t *cmds;
346
347 xmlNode *transaction;
348
349 char *user;
350 };
351
352 #ifdef __cplusplus
353 }
354 #endif
355
356 #endif // PCMK__CRM_CIB_CIB_TYPES__H