This source file includes following definitions.
- ra_param_free
- metadata_free
- metadata_cache_new
- metadata_cache_free
- metadata_cache_reset
- valid_version_format
- metadata_cache_fini
- ra_version_from_xml
- ra_param_from_xml
- metadata_cache_update
- metadata_cache_get
1
2
3
4
5
6
7
8 #include <crm_internal.h>
9
10 #include <stdio.h>
11 #include <glib.h>
12 #include <regex.h>
13
14 #include <crm/crm.h>
15 #include <crm/lrmd.h>
16
17 #include "crmd_lrm.h"
18
19 #if ENABLE_VERSIONED_ATTRS
20 static regex_t *version_format_regex = NULL;
21 #endif
22
23 static void
24 ra_param_free(void *param)
25 {
26 if (param) {
27 struct ra_param_s *p = (struct ra_param_s *) param;
28
29 if (p->rap_name) {
30 free(p->rap_name);
31 }
32 free(param);
33 }
34 }
35
36 static void
37 metadata_free(void *metadata)
38 {
39 if (metadata) {
40 struct ra_metadata_s *md = (struct ra_metadata_s *) metadata;
41
42 if (md->ra_version) {
43 free(md->ra_version);
44 }
45 g_list_free_full(md->ra_params, ra_param_free);
46 free(metadata);
47 }
48 }
49
50 GHashTable *
51 metadata_cache_new()
52 {
53 return g_hash_table_new_full(crm_str_hash, g_str_equal, g_hash_destroy_str,
54 metadata_free);
55 }
56
57 void
58 metadata_cache_free(GHashTable *mdc)
59 {
60 if (mdc) {
61 crm_trace("Destroying metadata cache with %d members", g_hash_table_size(mdc));
62 g_hash_table_destroy(mdc);
63 }
64 }
65
66 void
67 metadata_cache_reset(GHashTable *mdc)
68 {
69 if (mdc) {
70 crm_trace("Resetting metadata cache with %d members",
71 g_hash_table_size(mdc));
72 g_hash_table_remove_all(mdc);
73 }
74 }
75
76 #if ENABLE_VERSIONED_ATTRS
77 static gboolean
78 valid_version_format(const char *version)
79 {
80 if (version == NULL) {
81 return FALSE;
82 }
83
84 if (version_format_regex == NULL) {
85
86
87
88
89
90 const char *regex_string = "^[[:digit:]]+([.][[:digit:]]+)*$";
91
92 version_format_regex = calloc(1, sizeof(regex_t));
93 regcomp(version_format_regex, regex_string, REG_EXTENDED | REG_NOSUB);
94
95
96
97
98
99
100 CRM_CHECK(version_format_regex != NULL, return TRUE);
101 }
102
103 return regexec(version_format_regex, version, 0, NULL, 0) == 0;
104 }
105 #endif
106
107 void
108 metadata_cache_fini()
109 {
110 #if ENABLE_VERSIONED_ATTRS
111 if (version_format_regex) {
112 regfree(version_format_regex);
113 free(version_format_regex);
114 version_format_regex = NULL;
115 }
116 #endif
117 }
118
119 #if ENABLE_VERSIONED_ATTRS
120 static char *
121 ra_version_from_xml(xmlNode *metadata_xml, const lrmd_rsc_info_t *rsc)
122 {
123 const char *version = crm_element_value(metadata_xml, XML_ATTR_VERSION);
124
125 if (version == NULL) {
126 crm_debug("Metadata for %s:%s:%s does not specify a version",
127 rsc->class, rsc->provider, rsc->type);
128 version = PCMK_DEFAULT_AGENT_VERSION;
129
130 } else if (!valid_version_format(version)) {
131 crm_notice("%s:%s:%s metadata version has unrecognized format",
132 rsc->class, rsc->provider, rsc->type);
133 version = PCMK_DEFAULT_AGENT_VERSION;
134
135 } else {
136 crm_debug("Metadata for %s:%s:%s has version %s",
137 rsc->class, rsc->provider, rsc->type, version);
138 }
139 return strdup(version);
140 }
141 #endif
142
143 static struct ra_param_s *
144 ra_param_from_xml(xmlNode *param_xml)
145 {
146 const char *param_name = crm_element_value(param_xml, "name");
147 const char *value;
148 struct ra_param_s *p;
149
150 p = calloc(1, sizeof(struct ra_param_s));
151 if (p == NULL) {
152 crm_crit("Could not allocate memory for resource metadata");
153 return NULL;
154 }
155
156 p->rap_name = strdup(param_name);
157 if (p->rap_name == NULL) {
158 crm_crit("Could not allocate memory for resource metadata");
159 free(p);
160 return NULL;
161 }
162
163 value = crm_element_value(param_xml, "unique");
164 if (crm_is_true(value)) {
165 set_bit(p->rap_flags, ra_param_unique);
166 }
167
168 value = crm_element_value(param_xml, "private");
169 if (crm_is_true(value)) {
170 set_bit(p->rap_flags, ra_param_private);
171 }
172 return p;
173 }
174
175 struct ra_metadata_s *
176 metadata_cache_update(GHashTable *mdc, lrmd_rsc_info_t *rsc,
177 const char *metadata_str)
178 {
179 char *key = NULL;
180 xmlNode *metadata = NULL;
181 xmlNode *match = NULL;
182 struct ra_metadata_s *md = NULL;
183
184 CRM_CHECK(mdc && rsc && metadata_str, return NULL);
185
186 key = crm_generate_ra_key(rsc->class, rsc->provider, rsc->type);
187 if (!key) {
188 crm_crit("Could not allocate memory for resource metadata");
189 goto err;
190 }
191
192 metadata = string2xml(metadata_str);
193 if (!metadata) {
194 crm_err("Metadata for %s:%s:%s is not valid XML",
195 rsc->class, rsc->provider, rsc->type);
196 goto err;
197 }
198
199 md = calloc(1, sizeof(struct ra_metadata_s));
200 if (md == NULL) {
201 crm_crit("Could not allocate memory for resource metadata");
202 goto err;
203 }
204
205 #if ENABLE_VERSIONED_ATTRS
206 md->ra_version = ra_version_from_xml(metadata, rsc);
207 #endif
208
209
210 match = first_named_child(metadata, "actions");
211 for (match = first_named_child(match, "action"); match != NULL;
212 match = crm_next_same_xml(match)) {
213
214 const char *action_name = crm_element_value(match, "name");
215
216 if (safe_str_eq(action_name, "reload")) {
217 set_bit(md->ra_flags, ra_supports_reload);
218 break;
219 }
220 }
221
222
223 match = first_named_child(metadata, "parameters");
224 for (match = first_named_child(match, "parameter"); match != NULL;
225 match = crm_next_same_xml(match)) {
226
227 const char *param_name = crm_element_value(match, "name");
228
229 if (param_name == NULL) {
230 crm_warn("Metadata for %s:%s:%s has parameter without a name",
231 rsc->class, rsc->provider, rsc->type);
232 } else {
233 struct ra_param_s *p = ra_param_from_xml(match);
234
235 if (p == NULL) {
236 goto err;
237 }
238 if (is_set(p->rap_flags, ra_param_private)) {
239 set_bit(md->ra_flags, ra_uses_private);
240 }
241 md->ra_params = g_list_prepend(md->ra_params, p);
242 }
243 }
244
245 g_hash_table_replace(mdc, key, md);
246 free_xml(metadata);
247 return md;
248
249 err:
250 free(key);
251 free_xml(metadata);
252 metadata_free(md);
253 return NULL;
254 }
255
256 struct ra_metadata_s *
257 metadata_cache_get(GHashTable *mdc, lrmd_rsc_info_t *rsc)
258 {
259 char *key = NULL;
260 struct ra_metadata_s *metadata = NULL;
261
262 CRM_CHECK(mdc && rsc, return NULL);
263 key = crm_generate_ra_key(rsc->class, rsc->provider, rsc->type);
264 if (key) {
265 metadata = g_hash_table_lookup(mdc, key);
266 free(key);
267 }
268 return metadata;
269 }