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