/src/pacemaker/include/crm/cib/internal.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2004-2026 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_INTERNAL__H |
11 | | #define PCMK__CRM_CIB_INTERNAL__H |
12 | | |
13 | | #include <stdbool.h> |
14 | | #include <stdint.h> // UINT32_C |
15 | | |
16 | | #include <crm/cib.h> |
17 | | #include <crm/common/internal.h> |
18 | | |
19 | | #ifdef __cplusplus |
20 | | extern "C" { |
21 | | #endif |
22 | | |
23 | | // Request types for CIB manager IPC/CPG |
24 | 0 | #define PCMK__CIB_REQUEST_SECONDARY "cib_slave" |
25 | 0 | #define PCMK__CIB_REQUEST_PRIMARY "cib_master" |
26 | 0 | #define PCMK__CIB_REQUEST_SYNC "cib_sync" |
27 | | #define PCMK__CIB_REQUEST_IS_PRIMARY "cib_ismaster" |
28 | 0 | #define PCMK__CIB_REQUEST_BUMP "cib_bump" |
29 | 0 | #define PCMK__CIB_REQUEST_QUERY "cib_query" |
30 | 0 | #define PCMK__CIB_REQUEST_CREATE "cib_create" |
31 | 0 | #define PCMK__CIB_REQUEST_MODIFY "cib_modify" |
32 | 0 | #define PCMK__CIB_REQUEST_DELETE "cib_delete" |
33 | 0 | #define PCMK__CIB_REQUEST_ERASE "cib_erase" |
34 | 0 | #define PCMK__CIB_REQUEST_REPLACE "cib_replace" |
35 | | #define PCMK__CIB_REQUEST_APPLY_PATCH "cib_apply_diff" |
36 | 0 | #define PCMK__CIB_REQUEST_UPGRADE "cib_upgrade" |
37 | | #define PCMK__CIB_REQUEST_ABS_DELETE "cib_delete_alt" |
38 | 0 | #define PCMK__CIB_REQUEST_NOOP "noop" |
39 | | #define PCMK__CIB_REQUEST_SHUTDOWN "cib_shutdown_req" |
40 | 0 | #define PCMK__CIB_REQUEST_COMMIT_TRANSACT "cib_commit_transact" |
41 | 0 | #define PCMK__CIB_REQUEST_SCHEMAS "cib_schemas" |
42 | | |
43 | | /*! |
44 | | * \internal |
45 | | * \brief Flags for CIB operation attributes |
46 | | */ |
47 | | enum cib__op_attr { |
48 | | //! No special attributes |
49 | | cib__op_attr_none = 0, |
50 | | |
51 | | //! Modifies CIB |
52 | | cib__op_attr_modifies = (UINT32_C(1) << 1), |
53 | | |
54 | | //! Requires privileges |
55 | | cib__op_attr_privileged = (UINT32_C(1) << 2), |
56 | | |
57 | | //! Must only be processed locally |
58 | | cib__op_attr_local = (UINT32_C(1) << 3), |
59 | | |
60 | | //! Replaces CIB |
61 | | cib__op_attr_replaces = (UINT32_C(1) << 4), |
62 | | |
63 | | //! Writes to disk on success |
64 | | cib__op_attr_writes_through = (UINT32_C(1) << 5), |
65 | | |
66 | | //! Supported in a transaction |
67 | | cib__op_attr_transaction = (UINT32_C(1) << 6), |
68 | | }; |
69 | | |
70 | | /*! |
71 | | * \internal |
72 | | * \brief Types of CIB operations |
73 | | */ |
74 | | enum cib__op_type { |
75 | | cib__op_abs_delete, |
76 | | cib__op_apply_patch, |
77 | | cib__op_bump, |
78 | | cib__op_commit_transact, |
79 | | cib__op_create, |
80 | | cib__op_delete, |
81 | | cib__op_erase, |
82 | | cib__op_is_primary, |
83 | | cib__op_modify, |
84 | | cib__op_noop, |
85 | | cib__op_ping, |
86 | | cib__op_primary, |
87 | | cib__op_query, |
88 | | cib__op_replace, |
89 | | cib__op_schemas, |
90 | | cib__op_secondary, |
91 | | cib__op_shutdown, |
92 | | cib__op_sync, |
93 | | cib__op_upgrade, |
94 | | }; |
95 | | |
96 | | typedef int (*cib__op_fn_t)(const char *, int, const char *, xmlNode *, |
97 | | xmlNode *, xmlNode **, xmlNode **); |
98 | | |
99 | | typedef struct { |
100 | | const char *name; |
101 | | enum cib__op_type type; |
102 | | uint32_t flags; //!< Group of <tt>enum cib__op_attr</tt> flags |
103 | | } cib__operation_t; |
104 | | |
105 | | typedef struct { |
106 | | const char *event; |
107 | | const char *obj_id; /* implement one day */ |
108 | | const char *obj_type; /* implement one day */ |
109 | | void (*callback) (const char *event, xmlNode * msg); |
110 | | |
111 | | } cib_notify_client_t; |
112 | | |
113 | | typedef struct { |
114 | | void (*callback) (xmlNode *, int, int, xmlNode *, void *); |
115 | | const char *id; |
116 | | void *user_data; |
117 | | gboolean only_success; |
118 | | struct timer_rec_s *timer; |
119 | | void (*free_func)(void *); |
120 | | } cib_callback_client_t; |
121 | | |
122 | | struct timer_rec_s { |
123 | | int call_id; |
124 | | int timeout; |
125 | | guint ref; |
126 | | cib_t *cib; |
127 | | }; |
128 | | |
129 | 0 | #define cib__set_call_options(cib_call_opts, call_for, flags_to_set) do { \ |
130 | 0 | cib_call_opts = pcmk__set_flags_as(__func__, __LINE__, \ |
131 | 0 | LOG_TRACE, "CIB call", (call_for), (cib_call_opts), \ |
132 | 0 | (flags_to_set), #flags_to_set); \ |
133 | 0 | } while (0) |
134 | | |
135 | | #define cib__clear_call_options(cib_call_opts, call_for, flags_to_clear) do { \ |
136 | | cib_call_opts = pcmk__clear_flags_as(__func__, __LINE__, \ |
137 | | LOG_TRACE, "CIB call", (call_for), (cib_call_opts), \ |
138 | | (flags_to_clear), #flags_to_clear); \ |
139 | | } while (0) |
140 | | |
141 | | cib_t *cib_new_variant(void); |
142 | | |
143 | | /*! |
144 | | * \internal |
145 | | * \brief Check whether a given CIB client's update should trigger a refresh |
146 | | * |
147 | | * Here, "refresh" means that Pacemaker daemons write out their current state. |
148 | | * |
149 | | * If a Pacemaker daemon or one of certain Pacemaker CLI tools modifies the CIB, |
150 | | * we can assume that the CIB hasn't diverged from the true cluster state. A |
151 | | * "safe" CLI tool requests that all relevant daemons update their state before |
152 | | * the tool requests any CIB modifications directly. |
153 | | * |
154 | | * In contrast, other "unsafe" tools (for example, \c cibadmin and external |
155 | | * tools) may request arbitrary CIB changes. |
156 | | * |
157 | | * A Pacemaker daemon can write out its current state to the CIB when it's |
158 | | * notified of an update from an unsafe client, to ensure the CIB still contains |
159 | | * the daemon's correct state. |
160 | | * |
161 | | * \param[in] name CIB client name |
162 | | * |
163 | | * \return \c true if the CIB client should trigger a refresh, or \c false |
164 | | * otherwise |
165 | | */ |
166 | | static inline bool |
167 | | cib__client_triggers_refresh(const char *name) |
168 | 0 | { |
169 | 0 | return (pcmk__parse_server(name) == pcmk_ipc_unknown) |
170 | 0 | && !pcmk__str_any_of(name, |
171 | 0 | "attrd_updater", |
172 | 0 | "crm_attribute", |
173 | 0 | "crm_node", |
174 | 0 | "crm_resource", |
175 | 0 | "crm_ticket", |
176 | 0 | NULL); |
177 | 0 | } Unexecuted instantiation: utils.c:cib__client_triggers_refresh Unexecuted instantiation: cib_client.c:cib__client_triggers_refresh Unexecuted instantiation: cib_file.c:cib__client_triggers_refresh Unexecuted instantiation: cib_native.c:cib__client_triggers_refresh Unexecuted instantiation: cib_ops.c:cib__client_triggers_refresh Unexecuted instantiation: cib_remote.c:cib__client_triggers_refresh Unexecuted instantiation: cib_utils.c:cib__client_triggers_refresh |
178 | | |
179 | | int cib__get_notify_patchset(const xmlNode *msg, const xmlNode **patchset); |
180 | | |
181 | | int cib__perform_query(const char *op, uint32_t call_options, cib__op_fn_t fn, |
182 | | const char *section, xmlNode *req, xmlNode *input, |
183 | | xmlNode **current_cib, xmlNode **output); |
184 | | |
185 | | int cib_perform_op(enum cib_variant variant, const char *op, |
186 | | uint32_t call_options, cib__op_fn_t fn, const char *section, |
187 | | xmlNode *req, xmlNode *input, bool manage_counters, |
188 | | bool *config_changed, xmlNode **current_cib, |
189 | | xmlNode **result_cib, xmlNode **diff, xmlNode **output); |
190 | | |
191 | | int cib__create_op(cib_t *cib, const char *op, const char *host, |
192 | | const char *section, xmlNode *data, int call_options, |
193 | | const char *user_name, const char *client_name, |
194 | | xmlNode **op_msg); |
195 | | |
196 | | int cib__extend_transaction(cib_t *cib, xmlNode *request); |
197 | | |
198 | | void cib_native_callback(cib_t * cib, xmlNode * msg, int call_id, int rc); |
199 | | void cib_native_notify(gpointer data, gpointer user_data); |
200 | | |
201 | | int cib__get_operation(const char *op, const cib__operation_t **operation); |
202 | | |
203 | | int cib__process_apply_patch(const char *op, int options, const char *section, |
204 | | xmlNode *req, xmlNode *input, xmlNode **cib, |
205 | | xmlNode **answer); |
206 | | |
207 | | int cib__process_bump(const char *op, int options, const char *section, |
208 | | xmlNode *req, xmlNode *input, xmlNode **cib, |
209 | | xmlNode **answer); |
210 | | |
211 | | int cib__process_create(const char *op, int options, const char *section, |
212 | | xmlNode *req, xmlNode *input, xmlNode **cib, |
213 | | xmlNode **answer); |
214 | | |
215 | | int cib__process_delete(const char *op, int options, const char *section, |
216 | | xmlNode *req, xmlNode *input, xmlNode **cib, |
217 | | xmlNode **answer); |
218 | | |
219 | | int cib__process_erase(const char *op, int options, const char *section, |
220 | | xmlNode *req, xmlNode *input, xmlNode **cib, |
221 | | xmlNode **answer); |
222 | | |
223 | | int cib__process_modify(const char *op, int options, const char *section, |
224 | | xmlNode *req, xmlNode *input, xmlNode **cib, |
225 | | xmlNode **answer); |
226 | | |
227 | | int cib__process_query(const char *op, int options, const char *section, |
228 | | xmlNode *req, xmlNode *input, xmlNode **cib, |
229 | | xmlNode **answer); |
230 | | |
231 | | int cib__process_replace(const char *op, int options, const char *section, |
232 | | xmlNode *req, xmlNode *input, xmlNode **cib, |
233 | | xmlNode **answer); |
234 | | |
235 | | int cib__process_upgrade(const char *op, int options, const char *section, |
236 | | xmlNode *req, xmlNode *input, xmlNode **cib, |
237 | | xmlNode **answer); |
238 | | |
239 | | int cib_internal_op(cib_t * cib, const char *op, const char *host, |
240 | | const char *section, xmlNode * data, |
241 | | xmlNode ** output_data, int call_options, const char *user_name); |
242 | | |
243 | | |
244 | | int cib_file_read_and_verify(const char *filename, const char *sigfile, |
245 | | xmlNode **root); |
246 | | int cib_file_write_with_digest(xmlNode *cib_root, const char *cib_dirname, |
247 | | const char *cib_filename); |
248 | | |
249 | | void cib__set_output(cib_t *cib, pcmk__output_t *out); |
250 | | |
251 | | cib_callback_client_t* cib__lookup_id (int call_id); |
252 | | |
253 | | /*! |
254 | | * \internal |
255 | | * \brief Connect to, query, and optionally disconnect from the CIB |
256 | | * |
257 | | * Open a read-write connection to the CIB manager if an already connected |
258 | | * client is not passed in. Then query the CIB and store the resulting XML. |
259 | | * Finally, disconnect if the CIB connection isn't being returned to the caller. |
260 | | * |
261 | | * \param[in,out] out Output object (may be \p NULL) |
262 | | * \param[in,out] cib If not \p NULL, where to store CIB connection |
263 | | * \param[out] cib_object Where to store query result |
264 | | * |
265 | | * \return Standard Pacemaker return code |
266 | | * |
267 | | * \note If \p cib is not \p NULL, the caller is responsible for freeing \p *cib |
268 | | * using \p cib_delete(). |
269 | | * \note If \p *cib points to an existing \p cib_t object, this function will |
270 | | * reuse it instead of creating a new one. If the existing client is |
271 | | * already connected, the connection will be reused, even if it's |
272 | | * read-only. |
273 | | */ |
274 | | int cib__signon_query(pcmk__output_t *out, cib_t **cib, xmlNode **cib_object); |
275 | | |
276 | | int cib__create_signon(cib_t **cib); |
277 | | |
278 | | int cib__clean_up_connection(cib_t **cib); |
279 | | |
280 | | int cib__update_node_attr(pcmk__output_t *out, cib_t *cib, int call_options, |
281 | | const char *section, const char *node_uuid, const char *set_type, |
282 | | const char *set_name, const char *attr_id, const char *attr_name, |
283 | | const char *attr_value, const char *user_name, |
284 | | const char *node_type); |
285 | | |
286 | | int cib__get_node_attrs(pcmk__output_t *out, cib_t *cib, const char *section, |
287 | | const char *node_uuid, const char *set_type, const char *set_name, |
288 | | const char *attr_id, const char *attr_name, const char *user_name, |
289 | | xmlNode **result); |
290 | | |
291 | | int cib__delete_node_attr(pcmk__output_t *out, cib_t *cib, int options, |
292 | | const char *section, const char *node_uuid, const char *set_type, |
293 | | const char *set_name, const char *attr_id, const char *attr_name, |
294 | | const char *attr_value, const char *user_name); |
295 | | |
296 | | #ifdef __cplusplus |
297 | | } |
298 | | #endif |
299 | | |
300 | | #endif // PCMK__CRM_CIB_INTERNAL__H |