This source file includes following definitions.
- map_rule_input
- populate_hash
- unpack_attr_set
- make_pairs
- pe_eval_nvpairs
- pe_unpack_nvpairs
- test_rule
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <glib.h>
13
14 #include <crm/crm.h>
15 #include <crm/common/xml.h>
16 #include <crm/pengine/rules.h>
17
18 #include <crm/common/iso8601_internal.h>
19 #include <crm/common/nvpair_internal.h>
20 #include <crm/common/rules_internal.h>
21 #include <crm/common/xml_internal.h>
22 #include <crm/pengine/internal.h>
23 #include <crm/pengine/rules_internal.h>
24
25 #include <sys/types.h>
26 #include <regex.h>
27
28 CRM_TRACE_INIT_DATA(pe_rules);
29
30
31
32
33
34
35
36
37 static void
38 map_rule_input(pcmk_rule_input_t *new, const pe_rule_eval_data_t *old)
39 {
40 if (old == NULL) {
41 return;
42 }
43 new->now = old->now;
44 new->node_attrs = old->node_hash;
45 if (old->rsc_data != NULL) {
46 new->rsc_standard = old->rsc_data->standard;
47 new->rsc_provider = old->rsc_data->provider;
48 new->rsc_agent = old->rsc_data->agent;
49 }
50 if (old->match_data != NULL) {
51 new->rsc_params = old->match_data->params;
52 new->rsc_meta = old->match_data->meta;
53 if (old->match_data->re != NULL) {
54 new->rsc_id = old->match_data->re->string;
55 new->rsc_id_submatches = old->match_data->re->pmatch;
56 new->rsc_id_nmatches = old->match_data->re->nregs;
57 }
58 }
59 if (old->op_data != NULL) {
60 new->op_name = old->op_data->op_name;
61 new->op_interval_ms = old->op_data->interval;
62 }
63 }
64
65 static void
66 populate_hash(xmlNode *nvpair_list, GHashTable *hash, bool overwrite)
67 {
68 if (pcmk__xe_is(nvpair_list->children, PCMK__XE_ATTRIBUTES)) {
69 nvpair_list = nvpair_list->children;
70 }
71
72 for (xmlNode *nvpair = pcmk__xe_first_child(nvpair_list, PCMK_XE_NVPAIR,
73 NULL, NULL);
74 nvpair != NULL; nvpair = pcmk__xe_next(nvpair, PCMK_XE_NVPAIR)) {
75
76 xmlNode *ref_nvpair = pcmk__xe_resolve_idref(nvpair, NULL);
77 const char *name = NULL;
78 const char *value = NULL;
79 const char *old_value = NULL;
80
81 if (ref_nvpair == NULL) {
82
83
84
85 continue;
86 }
87
88 name = crm_element_value(ref_nvpair, PCMK_XA_NAME);
89 value = crm_element_value(ref_nvpair, PCMK_XA_VALUE);
90 if ((name == NULL) || (value == NULL)) {
91 continue;
92 }
93
94 old_value = g_hash_table_lookup(hash, name);
95
96 if (pcmk__str_eq(value, "#default", pcmk__str_casei)) {
97
98 pcmk__config_warn("Support for setting meta-attributes (such as "
99 "%s) to the explicit value '#default' is "
100 "deprecated and will be removed in a future "
101 "release", name);
102 if (old_value != NULL) {
103 crm_trace("Letting %s default (removing explicit value \"%s\")",
104 name, value);
105 g_hash_table_remove(hash, name);
106 }
107
108 } else if (old_value == NULL) {
109 crm_trace("Setting %s=\"%s\"", name, value);
110 pcmk__insert_dup(hash, name, value);
111
112 } else if (overwrite) {
113 crm_trace("Setting %s=\"%s\" (overwriting old value \"%s\")",
114 name, value, old_value);
115 pcmk__insert_dup(hash, name, value);
116 }
117 }
118 }
119
120 static void
121 unpack_attr_set(gpointer data, gpointer user_data)
122 {
123 xmlNode *pair = data;
124 pcmk__nvpair_unpack_t *unpack_data = user_data;
125
126 xmlNode *rule_xml = pcmk__xe_first_child(pair, PCMK_XE_RULE, NULL, NULL);
127
128 if ((rule_xml != NULL)
129 && (pcmk_evaluate_rule(rule_xml, &(unpack_data->rule_input),
130 unpack_data->next_change) != pcmk_rc_ok)) {
131 return;
132 }
133
134 crm_trace("Adding name/value pairs from %s %s overwrite",
135 pcmk__xe_id(pair), (unpack_data->overwrite? "with" : "without"));
136 populate_hash(pair, unpack_data->values, unpack_data->overwrite);
137 }
138
139
140
141
142
143
144
145
146
147
148 static GList *
149 make_pairs(const xmlNode *xml_obj, const char *set_name)
150 {
151 GList *unsorted = NULL;
152
153 if (xml_obj == NULL) {
154 return NULL;
155 }
156 for (xmlNode *attr_set = pcmk__xe_first_child(xml_obj, NULL, NULL, NULL);
157 attr_set != NULL; attr_set = pcmk__xe_next(attr_set, NULL)) {
158
159 if ((set_name == NULL) || pcmk__xe_is(attr_set, set_name)) {
160 xmlNode *expanded_attr_set = pcmk__xe_resolve_idref(attr_set, NULL);
161
162 if (expanded_attr_set == NULL) {
163 continue;
164 }
165 unsorted = g_list_prepend(unsorted, expanded_attr_set);
166 }
167 }
168 return unsorted;
169 }
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184 void
185 pe_eval_nvpairs(xmlNode *top, const xmlNode *xml_obj, const char *set_name,
186 const pe_rule_eval_data_t *rule_data, GHashTable *hash,
187 const char *always_first, gboolean overwrite,
188 crm_time_t *next_change)
189 {
190 GList *pairs = make_pairs(xml_obj, set_name);
191
192 if (pairs) {
193 pcmk__nvpair_unpack_t data = {
194 .values = hash,
195 .first_id = always_first,
196 .overwrite = overwrite,
197 .next_change = next_change,
198 };
199
200 map_rule_input(&(data.rule_input), rule_data);
201
202 pairs = g_list_sort_with_data(pairs, pcmk__cmp_nvpair_blocks, &data);
203 g_list_foreach(pairs, unpack_attr_set, &data);
204 g_list_free(pairs);
205 }
206 }
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222 void
223 pe_unpack_nvpairs(xmlNode *top, const xmlNode *xml_obj, const char *set_name,
224 GHashTable *node_hash, GHashTable *hash,
225 const char *always_first, gboolean overwrite,
226 crm_time_t *now, crm_time_t *next_change)
227 {
228 pe_rule_eval_data_t rule_data = {
229 .node_hash = node_hash,
230 .now = now,
231 .match_data = NULL,
232 .rsc_data = NULL,
233 .op_data = NULL
234 };
235
236 pe_eval_nvpairs(NULL, xml_obj, set_name, &rule_data, hash,
237 always_first, overwrite, next_change);
238 }
239
240
241
242
243 #include <crm/pengine/rules_compat.h>
244
245 gboolean
246 test_rule(xmlNode * rule, GHashTable * node_hash, enum rsc_role_e role, crm_time_t * now)
247 {
248 pcmk_rule_input_t rule_input = {
249 .node_attrs = node_hash,
250 .now = now,
251 };
252
253 return pcmk_evaluate_rule(rule, &rule_input, NULL) == pcmk_rc_ok;
254 }
255
256
257