Coverage Report

Created: 2026-10-30 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/pacemaker/lib/common/cib.c
Line
Count
Source
1
/*
2
 * Original copyright 2004 International Business Machines
3
 * Later changes copyright 2008-2026 the Pacemaker project contributors
4
 *
5
 * The version control history for this file may have further details.
6
 *
7
 * This source code is licensed under the GNU Lesser General Public License
8
 * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
9
 */
10
11
#include <crm_internal.h>
12
13
#include <stdio.h>
14
15
#include <glib.h>           // G_N_ELEMENTS
16
#include <libxml/tree.h>    // xmlNode
17
18
#include <crm/common/xml.h>
19
#include <crm/common/cib.h>
20
21
/*
22
 * Functions to help find particular sections of the CIB
23
 */
24
25
// Map CIB element names to their parent elements and XPath searches
26
static struct {
27
    const char *name;   // Name of this CIB element
28
    const char *parent; // CIB element that this element is a child of
29
    const char *path;   // XPath to find this CIB element
30
} cib_sections[] = {
31
    {
32
        // This first entry is also the default if a NULL is compared
33
        PCMK_XE_CIB,
34
        NULL,
35
        "//" PCMK_XE_CIB
36
    },
37
    {
38
        PCMK_XE_STATUS,
39
        "/" PCMK_XE_CIB,
40
        "//" PCMK_XE_CIB "/" PCMK_XE_STATUS
41
    },
42
    {
43
        PCMK_XE_CONFIGURATION,
44
        "/" PCMK_XE_CIB,
45
        "//" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION
46
    },
47
    {
48
        PCMK_XE_CRM_CONFIG,
49
        "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION,
50
        "//" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_CRM_CONFIG
51
    },
52
    {
53
        PCMK_XE_NODES,
54
        "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION,
55
        "//" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_NODES
56
    },
57
    {
58
        PCMK_XE_RESOURCES,
59
        "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION,
60
        "//" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_RESOURCES
61
    },
62
    {
63
        PCMK_XE_CONSTRAINTS,
64
        "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION,
65
        "//" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_CONSTRAINTS
66
    },
67
    {
68
        PCMK_XE_OP_DEFAULTS,
69
        "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION,
70
        "//" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_OP_DEFAULTS
71
    },
72
    {
73
        PCMK_XE_RSC_DEFAULTS,
74
        "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION,
75
        "//" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_RSC_DEFAULTS
76
    },
77
    {
78
        PCMK_XE_ACLS,
79
        "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION,
80
        "//" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_ACLS
81
    },
82
    {
83
        PCMK_XE_FENCING_TOPOLOGY,
84
        "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION,
85
        "//" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_FENCING_TOPOLOGY
86
    },
87
    {
88
        PCMK_XE_TAGS,
89
        "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION,
90
        "//" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_TAGS
91
    },
92
    {
93
        PCMK_XE_ALERTS,
94
        "/" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION,
95
        "//" PCMK_XE_CIB "/" PCMK_XE_CONFIGURATION "/" PCMK_XE_ALERTS
96
    },
97
    {
98
        PCMK__XE_ALL,
99
        NULL,
100
        "//" PCMK_XE_CIB
101
    },
102
};
103
104
/*!
105
 * \brief Get the relative XPath needed to find a specified CIB element name
106
 *
107
 * \param[in] element_name  Name of CIB element
108
 *
109
 * \return XPath for finding \p element_name in CIB XML (or NULL if unknown)
110
 * \note The return value is constant and should not be freed.
111
 */
112
const char *
113
pcmk_cib_xpath_for(const char *element_name)
114
0
{
115
0
    for (int lpc = 0; lpc < G_N_ELEMENTS(cib_sections); lpc++) {
116
        // A NULL element_name will match the first entry
117
0
        if (pcmk__str_eq(element_name, cib_sections[lpc].name,
118
0
                         pcmk__str_null_matches)) {
119
0
            return cib_sections[lpc].path;
120
0
        }
121
0
    }
122
0
    return NULL;
123
0
}
124
125
/*!
126
 * \internal
127
 * \brief Get the absolute XPath needed to find a specified CIB element name
128
 *
129
 * \param[in] element  Name of CIB element
130
 *
131
 * \return XPath for finding \p element in CIB XML (or \c NULL if unknown)
132
 */
133
const char *
134
pcmk__cib_abs_xpath_for(const char *element)
135
0
{
136
0
    const char *xpath = pcmk_cib_xpath_for(element);
137
138
    // XPaths returned by pcmk_cib_xpath_for() are relative (starting with "//")
139
0
    return ((xpath != NULL)? (xpath + 1) : NULL);
140
0
}
141
142
/*!
143
 * \brief Get the parent element name of a given CIB element name
144
 *
145
 * \param[in] element_name  Name of CIB element
146
 *
147
 * \return Parent element of \p element_name (or NULL if none or unknown)
148
 * \note The return value is constant and should not be freed.
149
 */
150
const char *
151
pcmk_cib_parent_name_for(const char *element_name)
152
0
{
153
0
    for (int lpc = 0; lpc < G_N_ELEMENTS(cib_sections); lpc++) {
154
        // A NULL element_name will match the first entry
155
0
        if (pcmk__str_eq(element_name, cib_sections[lpc].name,
156
0
                         pcmk__str_null_matches)) {
157
0
            return cib_sections[lpc].parent;
158
0
        }
159
0
    }
160
0
    return NULL;
161
0
}
162
163
/*!
164
 * \brief Find an element in the CIB
165
 *
166
 * \param[in] cib           Top-level CIB XML to search
167
 * \param[in] element_name  Name of CIB element to search for
168
 *
169
 * \return XML element in \p cib corresponding to \p element_name
170
 *         (or \p cib itself if element is unknown or not found)
171
 */
172
xmlNode *
173
pcmk_find_cib_element(xmlNode *cib, const char *element_name)
174
0
{
175
0
    return pcmk__xpath_find_one(cib->doc, pcmk_cib_xpath_for(element_name),
176
0
                                LOG_TRACE);
177
0
}
178
179
/*!
180
 * \internal
181
 * \brief Check that the feature set in the CIB is supported on this node
182
 *
183
 * \param[in] new_version   PCMK_XA_CRM_FEATURE_SET attribute from the CIB
184
 */
185
int
186
pcmk__check_feature_set(const char *cib_version)
187
0
{
188
0
    if ((cib_version != NULL)
189
0
        && (pcmk__compare_versions(cib_version, CRM_FEATURE_SET) > 0)) {
190
0
        return EPROTONOSUPPORT;
191
0
    }
192
193
0
    return pcmk_rc_ok;
194
0
}