Coverage Report

Created: 2026-03-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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