pacemaker 3.0.1-16e74fc4da
Scalable High-Availability cluster resource manager
Loading...
Searching...
No Matches
xml_idref.c
Go to the documentation of this file.
1/*
2 * Copyright 2004-2025 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#include <crm_internal.h>
11
12#include <stdio.h> // NULL
13#include <stdlib.h> // free()
14#include <glib.h> // GList, GHashTable, etc.
15#include <libxml/tree.h> // xmlNode
16
17#include <crm/crm.h>
18#include <crm/common/xml.h> // PCMK_XA_ID_REF
19
31void
32pcmk__add_idref(GHashTable *table, const char *id, const char *referrer)
33{
34 pcmk__idref_t *idref = NULL;
35
36 pcmk__assert((table != NULL) && (id != NULL) && (referrer != NULL));
37
38 idref = g_hash_table_lookup(table, id);
39 if (idref == NULL) {
40 idref = pcmk__assert_alloc(1, sizeof(pcmk__idref_t));
41 idref->id = pcmk__str_copy(id);
42 g_hash_table_insert(table, pcmk__str_copy(id), idref);
43 }
44 for (GList *iter = idref->refs; iter != NULL; iter = iter->next) {
45 if (pcmk__str_eq(referrer, (const char *) iter->data,
47 return; // Already present
48 }
49 }
50 idref->refs = g_list_append(idref->refs, pcmk__str_copy(referrer));
51 crm_trace("Added ID %s referrer %s", id, referrer);
52}
53
60void
62{
63 pcmk__idref_t *idref = data;
64
65 if (idref != NULL) {
66 free(idref->id);
67 g_list_free_full(idref->refs, free);
68 free(idref);
69 }
70}
71
84xmlNode *
85pcmk__xe_resolve_idref(xmlNode *xml, xmlNode *search)
86{
87 char *xpath = NULL;
88 const char *ref = NULL;
89 xmlNode *result = NULL;
90
91 if (xml == NULL) {
92 return NULL;
93 }
94
96 if (ref == NULL) {
97 return xml;
98 }
99
100 if (search == NULL) {
101 search = xml;
102 }
103
104 xpath = crm_strdup_printf("//%s[@" PCMK_XA_ID "='%s']", xml->name, ref);
105 result = pcmk__xpath_find_one(search->doc, xpath, LOG_DEBUG);
106 if (result == NULL) {
107 // Not possible with schema validation enabled
108 pcmk__config_err("Ignoring invalid %s configuration: "
109 PCMK_XA_ID_REF " '%s' does not reference "
110 "a valid object " QB_XS " xpath=%s",
111 xml->name, ref, xpath);
112 }
113 free(xpath);
114 return result;
115}
116
127GList *
128pcmk__xe_dereference_children(const xmlNode *xml, const char *element_name)
129{
130 GList *result = NULL;
131
132 if (xml == NULL) {
133 return NULL;
134 }
135 for (xmlNode *child = pcmk__xe_first_child(xml, element_name, NULL, NULL);
136 child != NULL; child = pcmk__xe_next(child, element_name)) {
137
138 xmlNode *resolved = pcmk__xe_resolve_idref(child, NULL);
139
140 if (resolved == NULL) {
141 continue; // Not possible with schema validation enabled
142 }
143 result = g_list_prepend(result, resolved);
144 }
145 return result;
146}
#define pcmk__assert_alloc(nmemb, size)
Definition internal.h:246
char data[0]
Definition cpg.c:10
A dumping ground.
#define crm_trace(fmt, args...)
Definition logging.h:370
#define pcmk__config_err(fmt...)
pcmk__action_result_t result
Definition pcmk_fence.c:37
#define pcmk__assert(expr)
char * crm_strdup_printf(char const *format,...) G_GNUC_PRINTF(1
@ pcmk__str_none
#define pcmk__str_copy(str)
Wrappers for and extensions to libxml2.
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
xmlNode * pcmk__xe_first_child(const xmlNode *parent, const char *node_name, const char *attr_n, const char *attr_v)
Definition xml_element.c:43
xmlNode * pcmk__xe_next(const xmlNode *node, const char *element_name)
GList * pcmk__xe_dereference_children(const xmlNode *xml, const char *element_name)
Definition xml_idref.c:128
xmlNode * pcmk__xe_resolve_idref(xmlNode *xml, xmlNode *search)
Definition xml_idref.c:85
void pcmk__free_idref(gpointer data)
Definition xml_idref.c:61
void pcmk__add_idref(GHashTable *table, const char *id, const char *referrer)
Definition xml_idref.c:32
#define PCMK_XA_ID
Definition xml_names.h:301
#define PCMK_XA_ID_REF
Definition xml_names.h:303
xmlNode * pcmk__xpath_find_one(xmlDoc *doc, const char *path, uint8_t level)
Definition xpath.c:206