This source file includes following definitions.
- group_unpack
- group_active
- group_print_xml
- group_print
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- PCMK__OUTPUT_ARGS
- group_free
- group_resource_state
- pe__group_is_filtered
1
2
3
4
5
6
7
8
9
10 #include <crm_internal.h>
11
12 #include <crm/pengine/rules.h>
13 #include <crm/pengine/status.h>
14 #include <crm/pengine/internal.h>
15 #include <crm/msg_xml.h>
16 #include <crm/common/xml_internal.h>
17 #include <pe_status_private.h>
18
19 #define VARIANT_GROUP 1
20 #include "./variant.h"
21
22 gboolean
23 group_unpack(pe_resource_t * rsc, pe_working_set_t * data_set)
24 {
25 xmlNode *xml_obj = rsc->xml;
26 xmlNode *xml_native_rsc = NULL;
27 group_variant_data_t *group_data = NULL;
28 const char *group_ordered = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_ORDERED);
29 const char *group_colocated = g_hash_table_lookup(rsc->meta, "collocated");
30 const char *clone_id = NULL;
31
32 pe_rsc_trace(rsc, "Processing resource %s...", rsc->id);
33
34 group_data = calloc(1, sizeof(group_variant_data_t));
35 group_data->num_children = 0;
36 group_data->first_child = NULL;
37 group_data->last_child = NULL;
38 rsc->variant_opaque = group_data;
39
40
41 if ((group_ordered == NULL)
42 || (crm_str_to_boolean(group_ordered, &(group_data->ordered)) < 0)) {
43 group_data->ordered = TRUE;
44 }
45 if ((group_colocated == NULL)
46 || (crm_str_to_boolean(group_colocated, &(group_data->colocated)) < 0)) {
47 group_data->colocated = TRUE;
48 }
49
50 clone_id = crm_element_value(rsc->xml, XML_RSC_ATTR_INCARNATION);
51
52 for (xml_native_rsc = pcmk__xe_first_child(xml_obj); xml_native_rsc != NULL;
53 xml_native_rsc = pcmk__xe_next(xml_native_rsc)) {
54
55 if (pcmk__str_eq((const char *)xml_native_rsc->name,
56 XML_CIB_TAG_RESOURCE, pcmk__str_none)) {
57 pe_resource_t *new_rsc = NULL;
58
59 crm_xml_add(xml_native_rsc, XML_RSC_ATTR_INCARNATION, clone_id);
60 if (common_unpack(xml_native_rsc, &new_rsc, rsc, data_set) == FALSE) {
61 pe_err("Failed unpacking resource %s", crm_element_value(xml_obj, XML_ATTR_ID));
62 if (new_rsc != NULL && new_rsc->fns != NULL) {
63 new_rsc->fns->free(new_rsc);
64 }
65 continue;
66 }
67
68 group_data->num_children++;
69 rsc->children = g_list_append(rsc->children, new_rsc);
70
71 if (group_data->first_child == NULL) {
72 group_data->first_child = new_rsc;
73 }
74 group_data->last_child = new_rsc;
75 pe_rsc_trace(rsc, "Added %s member %s", rsc->id, new_rsc->id);
76 }
77 }
78
79 if (group_data->num_children == 0) {
80 pcmk__config_warn("Group %s does not have any children", rsc->id);
81 return TRUE;
82 }
83
84 pe_rsc_trace(rsc, "Added %d children to resource %s...", group_data->num_children, rsc->id);
85
86 return TRUE;
87 }
88
89 gboolean
90 group_active(pe_resource_t * rsc, gboolean all)
91 {
92 gboolean c_all = TRUE;
93 gboolean c_any = FALSE;
94 GListPtr gIter = rsc->children;
95
96 for (; gIter != NULL; gIter = gIter->next) {
97 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
98
99 if (child_rsc->fns->active(child_rsc, all)) {
100 c_any = TRUE;
101 } else {
102 c_all = FALSE;
103 }
104 }
105
106 if (c_any == FALSE) {
107 return FALSE;
108 } else if (all && c_all == FALSE) {
109 return FALSE;
110 }
111 return TRUE;
112 }
113
114 static void
115 group_print_xml(pe_resource_t * rsc, const char *pre_text, long options, void *print_data)
116 {
117 GListPtr gIter = rsc->children;
118 char *child_text = crm_strdup_printf("%s ", pre_text);
119
120 status_print("%s<group id=\"%s\" ", pre_text, rsc->id);
121 status_print("number_resources=\"%d\" ", g_list_length(rsc->children));
122 status_print(">\n");
123
124 for (; gIter != NULL; gIter = gIter->next) {
125 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
126
127 child_rsc->fns->print(child_rsc, child_text, options, print_data);
128 }
129
130 status_print("%s</group>\n", pre_text);
131 free(child_text);
132 }
133
134 void
135 group_print(pe_resource_t * rsc, const char *pre_text, long options, void *print_data)
136 {
137 char *child_text = NULL;
138 GListPtr gIter = rsc->children;
139
140 if (pre_text == NULL) {
141 pre_text = " ";
142 }
143
144 if (options & pe_print_xml) {
145 group_print_xml(rsc, pre_text, options, print_data);
146 return;
147 }
148
149 child_text = crm_strdup_printf("%s ", pre_text);
150
151 status_print("%sResource Group: %s", pre_text ? pre_text : "", rsc->id);
152
153 if (options & pe_print_html) {
154 status_print("\n<ul>\n");
155
156 } else if ((options & pe_print_log) == 0) {
157 status_print("\n");
158 }
159
160 if (options & pe_print_brief) {
161 print_rscs_brief(rsc->children, child_text, options, print_data, TRUE);
162
163 } else {
164 for (; gIter != NULL; gIter = gIter->next) {
165 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
166
167 if (options & pe_print_html) {
168 status_print("<li>\n");
169 }
170 child_rsc->fns->print(child_rsc, child_text, options, print_data);
171 if (options & pe_print_html) {
172 status_print("</li>\n");
173 }
174 }
175 }
176
177 if (options & pe_print_html) {
178 status_print("</ul>\n");
179 }
180 free(child_text);
181 }
182
183 PCMK__OUTPUT_ARGS("group", "unsigned int", "pe_resource_t *", "GListPtr", "GListPtr")
184 int
185 pe__group_xml(pcmk__output_t *out, va_list args)
186 {
187 unsigned int options = va_arg(args, unsigned int);
188 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
189 GListPtr only_node = va_arg(args, GListPtr);
190 GListPtr only_rsc = va_arg(args, GListPtr);
191
192 GListPtr gIter = rsc->children;
193 char *count = crm_itoa(g_list_length(gIter));
194
195 int rc = pcmk_rc_no_output;
196 gboolean print_everything = TRUE;
197
198 if (rsc->fns->is_filtered(rsc, only_rsc, TRUE)) {
199 free(count);
200 return rc;
201 }
202
203 print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
204 (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
205
206 for (; gIter != NULL; gIter = gIter->next) {
207 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
208
209 if (child_rsc->fns->is_filtered(child_rsc, only_rsc, print_everything)) {
210 continue;
211 }
212
213 if (rc == pcmk_rc_no_output) {
214 rc = pe__name_and_nvpairs_xml(out, true, "group", 4
215 , "id", rsc->id
216 , "number_resources", count
217 , "managed", pe__rsc_bool_str(rsc, pe_rsc_managed)
218 , "disabled", pcmk__btoa(pe__resource_is_disabled(rsc)));
219 free(count);
220 CRM_ASSERT(rc == pcmk_rc_ok);
221 }
222
223 out->message(out, crm_map_element_name(child_rsc->xml), options, child_rsc,
224 only_node, only_rsc);
225 }
226
227 if (rc == pcmk_rc_ok) {
228 pcmk__output_xml_pop_parent(out);
229 }
230
231 return rc;
232 }
233
234 PCMK__OUTPUT_ARGS("group", "unsigned int", "pe_resource_t *", "GListPtr", "GListPtr")
235 int
236 pe__group_html(pcmk__output_t *out, va_list args)
237 {
238 unsigned int options = va_arg(args, unsigned int);
239 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
240 GListPtr only_node = va_arg(args, GListPtr);
241 GListPtr only_rsc = va_arg(args, GListPtr);
242
243 int rc = pcmk_rc_no_output;
244 gboolean print_everything = TRUE;
245
246 if (rsc->fns->is_filtered(rsc, only_rsc, TRUE)) {
247 return rc;
248 }
249
250 print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
251 (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
252
253 if (options & pe_print_brief) {
254 GListPtr rscs = pe__filter_rsc_list(rsc->children, only_rsc);
255
256 if (rscs != NULL) {
257 out->begin_list(out, NULL, NULL, "Resource Group: %s%s%s", rsc->id,
258 pcmk_is_set(rsc->flags, pe_rsc_managed) ? "" : " (unmanaged)",
259 pe__resource_is_disabled(rsc) ? " (disabled)" : "");
260
261 pe__rscs_brief_output(out, rscs, options, TRUE);
262
263 rc = pcmk_rc_ok;
264 g_list_free(rscs);
265 }
266
267 } else {
268 for (GListPtr gIter = rsc->children; gIter; gIter = gIter->next) {
269 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
270
271 if (child_rsc->fns->is_filtered(child_rsc, only_rsc, print_everything)) {
272 continue;
273 }
274
275 PCMK__OUTPUT_LIST_HEADER(out, FALSE, rc, "Resource Group: %s%s%s", rsc->id,
276 pcmk_is_set(rsc->flags, pe_rsc_managed) ? "" : " (unmanaged)",
277 pe__resource_is_disabled(rsc) ? " (disabled)" : "");
278
279 out->message(out, crm_map_element_name(child_rsc->xml), options,
280 child_rsc, only_node, only_rsc);
281 }
282 }
283
284 PCMK__OUTPUT_LIST_FOOTER(out, rc);
285
286 return rc;
287 }
288
289 PCMK__OUTPUT_ARGS("group", "unsigned int", "pe_resource_t *", "GListPtr", "GListPtr")
290 int
291 pe__group_text(pcmk__output_t *out, va_list args)
292 {
293 unsigned int options = va_arg(args, unsigned int);
294 pe_resource_t *rsc = va_arg(args, pe_resource_t *);
295 GListPtr only_node = va_arg(args, GListPtr);
296 GListPtr only_rsc = va_arg(args, GListPtr);
297
298 int rc = pcmk_rc_no_output;
299 gboolean print_everything = TRUE;
300
301 if (rsc->fns->is_filtered(rsc, only_rsc, TRUE)) {
302 return rc;
303 }
304
305 print_everything = pcmk__str_in_list(only_rsc, rsc_printable_id(rsc)) ||
306 (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id));
307
308 if (options & pe_print_brief) {
309 GListPtr rscs = pe__filter_rsc_list(rsc->children, only_rsc);
310
311 if (rscs != NULL) {
312 out->begin_list(out, NULL, NULL, "Resource Group: %s%s%s", rsc->id,
313 pcmk_is_set(rsc->flags, pe_rsc_managed) ? "" : " (unmanaged)",
314 pe__resource_is_disabled(rsc) ? " (disabled)" : "");
315
316 pe__rscs_brief_output(out, rscs, options, TRUE);
317
318 rc = pcmk_rc_ok;
319 g_list_free(rscs);
320 }
321
322 } else {
323 for (GListPtr gIter = rsc->children; gIter; gIter = gIter->next) {
324 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
325
326 if (child_rsc->fns->is_filtered(child_rsc, only_rsc, print_everything)) {
327 continue;
328 }
329
330 PCMK__OUTPUT_LIST_HEADER(out, FALSE, rc, "Resource Group: %s%s%s", rsc->id,
331 pcmk_is_set(rsc->flags, pe_rsc_managed) ? "" : " (unmanaged)",
332 pe__resource_is_disabled(rsc) ? " (disabled)" : "");
333
334 out->message(out, crm_map_element_name(child_rsc->xml), options,
335 child_rsc, only_node, only_rsc);
336 }
337 }
338
339 PCMK__OUTPUT_LIST_FOOTER(out, rc);
340
341 return rc;
342 }
343
344 void
345 group_free(pe_resource_t * rsc)
346 {
347 CRM_CHECK(rsc != NULL, return);
348
349 pe_rsc_trace(rsc, "Freeing %s", rsc->id);
350
351 for (GListPtr gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
352 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
353
354 CRM_ASSERT(child_rsc);
355 pe_rsc_trace(child_rsc, "Freeing child %s", child_rsc->id);
356 child_rsc->fns->free(child_rsc);
357 }
358
359 pe_rsc_trace(rsc, "Freeing child list");
360 g_list_free(rsc->children);
361
362 common_free(rsc);
363 }
364
365 enum rsc_role_e
366 group_resource_state(const pe_resource_t * rsc, gboolean current)
367 {
368 enum rsc_role_e group_role = RSC_ROLE_UNKNOWN;
369 GListPtr gIter = rsc->children;
370
371 for (; gIter != NULL; gIter = gIter->next) {
372 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
373 enum rsc_role_e role = child_rsc->fns->state(child_rsc, current);
374
375 if (role > group_role) {
376 group_role = role;
377 }
378 }
379
380 pe_rsc_trace(rsc, "%s role: %s", rsc->id, role2text(group_role));
381 return group_role;
382 }
383
384 gboolean
385 pe__group_is_filtered(pe_resource_t *rsc, GListPtr only_rsc, gboolean check_parent)
386 {
387 gboolean passes = FALSE;
388
389 if (check_parent && pcmk__str_in_list(only_rsc, rsc_printable_id(uber_parent(rsc)))) {
390 passes = TRUE;
391 } else if (pcmk__str_in_list(only_rsc, rsc_printable_id(rsc))) {
392 passes = TRUE;
393 } else if (strstr(rsc->id, ":") != NULL && pcmk__str_in_list(only_rsc, rsc->id)) {
394 passes = TRUE;
395 } else {
396 for (GListPtr gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
397 pe_resource_t *child_rsc = (pe_resource_t *) gIter->data;
398
399 if (!child_rsc->fns->is_filtered(child_rsc, only_rsc, FALSE)) {
400 passes = TRUE;
401 break;
402 }
403 }
404 }
405
406 return !passes;
407 }