This source file includes following definitions.
- group_unpack
- group_active
- group_print_xml
- group_print
- group_free
- group_resource_state
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <crm_internal.h>
20
21 #include <crm/pengine/rules.h>
22 #include <crm/pengine/status.h>
23 #include <crm/pengine/internal.h>
24 #include <unpack.h>
25 #include <crm/msg_xml.h>
26
27 #define VARIANT_GROUP 1
28 #include "./variant.h"
29
30 gboolean
31 group_unpack(resource_t * rsc, pe_working_set_t * data_set)
32 {
33 xmlNode *xml_obj = rsc->xml;
34 xmlNode *xml_native_rsc = NULL;
35 group_variant_data_t *group_data = NULL;
36 const char *group_ordered = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_ORDERED);
37 const char *group_colocated = g_hash_table_lookup(rsc->meta, "collocated");
38 const char *clone_id = NULL;
39
40 pe_rsc_trace(rsc, "Processing resource %s...", rsc->id);
41
42 group_data = calloc(1, sizeof(group_variant_data_t));
43 group_data->num_children = 0;
44 group_data->first_child = NULL;
45 group_data->last_child = NULL;
46 rsc->variant_opaque = group_data;
47
48 group_data->ordered = TRUE;
49 group_data->colocated = TRUE;
50
51 if (group_ordered != NULL) {
52 crm_str_to_boolean(group_ordered, &(group_data->ordered));
53 }
54 if (group_colocated != NULL) {
55 crm_str_to_boolean(group_colocated, &(group_data->colocated));
56 }
57
58 clone_id = crm_element_value(rsc->xml, XML_RSC_ATTR_INCARNATION);
59
60 for (xml_native_rsc = __xml_first_child(xml_obj); xml_native_rsc != NULL;
61 xml_native_rsc = __xml_next_element(xml_native_rsc)) {
62 if (crm_str_eq((const char *)xml_native_rsc->name, XML_CIB_TAG_RESOURCE, TRUE)) {
63 resource_t *new_rsc = NULL;
64
65 crm_xml_add(xml_native_rsc, XML_RSC_ATTR_INCARNATION, clone_id);
66 if (common_unpack(xml_native_rsc, &new_rsc, rsc, data_set) == FALSE) {
67 pe_err("Failed unpacking resource %s", crm_element_value(xml_obj, XML_ATTR_ID));
68 if (new_rsc != NULL && new_rsc->fns != NULL) {
69 new_rsc->fns->free(new_rsc);
70 }
71 }
72
73 group_data->num_children++;
74 rsc->children = g_list_append(rsc->children, new_rsc);
75
76 if (group_data->first_child == NULL) {
77 group_data->first_child = new_rsc;
78 }
79 group_data->last_child = new_rsc;
80 print_resource(LOG_DEBUG_3, "Added ", new_rsc, FALSE);
81 }
82 }
83
84 if (group_data->num_children == 0) {
85 #if 0
86
87 crm_config_err("Group %s did not have any children", rsc->id);
88 return FALSE;
89 #else
90 crm_config_warn("Group %s did not have any children", rsc->id);
91 return TRUE;
92 #endif
93 }
94
95 pe_rsc_trace(rsc, "Added %d children to resource %s...", group_data->num_children, rsc->id);
96
97 return TRUE;
98 }
99
100 gboolean
101 group_active(resource_t * rsc, gboolean all)
102 {
103 gboolean c_all = TRUE;
104 gboolean c_any = FALSE;
105 GListPtr gIter = rsc->children;
106
107 for (; gIter != NULL; gIter = gIter->next) {
108 resource_t *child_rsc = (resource_t *) gIter->data;
109
110 if (child_rsc->fns->active(child_rsc, all)) {
111 c_any = TRUE;
112 } else {
113 c_all = FALSE;
114 }
115 }
116
117 if (c_any == FALSE) {
118 return FALSE;
119 } else if (all && c_all == FALSE) {
120 return FALSE;
121 }
122 return TRUE;
123 }
124
125 static void
126 group_print_xml(resource_t * rsc, const char *pre_text, long options, void *print_data)
127 {
128 GListPtr gIter = rsc->children;
129 char *child_text = crm_concat(pre_text, " ", ' ');
130
131 status_print("%s<group id=\"%s\" ", pre_text, rsc->id);
132 status_print("number_resources=\"%d\" ", g_list_length(rsc->children));
133 status_print(">\n");
134
135 for (; gIter != NULL; gIter = gIter->next) {
136 resource_t *child_rsc = (resource_t *) gIter->data;
137
138 child_rsc->fns->print(child_rsc, child_text, options, print_data);
139 }
140
141 status_print("%s</group>\n", pre_text);
142 free(child_text);
143 }
144
145 void
146 group_print(resource_t * rsc, const char *pre_text, long options, void *print_data)
147 {
148 char *child_text = NULL;
149 GListPtr gIter = rsc->children;
150
151 if (pre_text == NULL) {
152 pre_text = " ";
153 }
154
155 if (options & pe_print_xml) {
156 group_print_xml(rsc, pre_text, options, print_data);
157 return;
158 }
159
160 child_text = crm_concat(pre_text, " ", ' ');
161
162 status_print("%sResource Group: %s", pre_text ? pre_text : "", rsc->id);
163
164 if (options & pe_print_html) {
165 status_print("\n<ul>\n");
166
167 } else if ((options & pe_print_log) == 0) {
168 status_print("\n");
169 }
170
171 if (options & pe_print_brief) {
172 print_rscs_brief(rsc->children, child_text, options, print_data, TRUE);
173
174 } else {
175 for (; gIter != NULL; gIter = gIter->next) {
176 resource_t *child_rsc = (resource_t *) gIter->data;
177
178 if (options & pe_print_html) {
179 status_print("<li>\n");
180 }
181 child_rsc->fns->print(child_rsc, child_text, options, print_data);
182 if (options & pe_print_html) {
183 status_print("</li>\n");
184 }
185 }
186 }
187
188 if (options & pe_print_html) {
189 status_print("</ul>\n");
190 }
191 free(child_text);
192 }
193
194 void
195 group_free(resource_t * rsc)
196 {
197 GListPtr gIter = rsc->children;
198
199 CRM_CHECK(rsc != NULL, return);
200
201 pe_rsc_trace(rsc, "Freeing %s", rsc->id);
202
203 for (; gIter != NULL; gIter = gIter->next) {
204 resource_t *child_rsc = (resource_t *) gIter->data;
205
206 CRM_ASSERT(child_rsc);
207 pe_rsc_trace(child_rsc, "Freeing child %s", child_rsc->id);
208 child_rsc->fns->free(child_rsc);
209 }
210
211 pe_rsc_trace(rsc, "Freeing child list");
212 g_list_free(rsc->children);
213
214 common_free(rsc);
215 }
216
217 enum rsc_role_e
218 group_resource_state(const resource_t * rsc, gboolean current)
219 {
220 enum rsc_role_e group_role = RSC_ROLE_UNKNOWN;
221 GListPtr gIter = rsc->children;
222
223 for (; gIter != NULL; gIter = gIter->next) {
224 resource_t *child_rsc = (resource_t *) gIter->data;
225 enum rsc_role_e role = child_rsc->fns->state(child_rsc, current);
226
227 if (role > group_role) {
228 group_role = role;
229 }
230 }
231
232 pe_rsc_trace(rsc, "%s role: %s", rsc->id, role2text(group_role));
233 return group_role;
234 }