pacemaker  1.1.24-3850484742
Scalable High-Availability cluster resource manager
group.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2019 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 <crm/pengine/rules.h>
13 #include <crm/pengine/status.h>
14 #include <crm/pengine/internal.h>
15 #include <unpack.h>
16 #include <crm/msg_xml.h>
17 
18 #define VARIANT_GROUP 1
19 #include "./variant.h"
20 
21 gboolean
23 {
24  xmlNode *xml_obj = rsc->xml;
25  xmlNode *xml_native_rsc = NULL;
26  group_variant_data_t *group_data = NULL;
27  const char *group_ordered = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_ORDERED);
28  const char *group_colocated = g_hash_table_lookup(rsc->meta, "collocated");
29  const char *clone_id = NULL;
30 
31  pe_rsc_trace(rsc, "Processing resource %s...", rsc->id);
32 
33  group_data = calloc(1, sizeof(group_variant_data_t));
34  group_data->num_children = 0;
35  group_data->first_child = NULL;
36  group_data->last_child = NULL;
37  rsc->variant_opaque = group_data;
38 
39  group_data->ordered = TRUE;
40  group_data->colocated = TRUE;
41 
42  if (group_ordered != NULL) {
43  crm_str_to_boolean(group_ordered, &(group_data->ordered));
44  }
45  if (group_colocated != NULL) {
46  crm_str_to_boolean(group_colocated, &(group_data->colocated));
47  }
48 
50 
51  for (xml_native_rsc = __xml_first_child_element(xml_obj); xml_native_rsc != NULL;
52  xml_native_rsc = __xml_next_element(xml_native_rsc)) {
53  if (crm_str_eq((const char *)xml_native_rsc->name, XML_CIB_TAG_RESOURCE, TRUE)) {
54  resource_t *new_rsc = NULL;
55 
56  crm_xml_add(xml_native_rsc, XML_RSC_ATTR_INCARNATION, clone_id);
57  if (common_unpack(xml_native_rsc, &new_rsc, rsc, data_set) == FALSE) {
58  pe_err("Failed unpacking resource %s", crm_element_value(xml_obj, XML_ATTR_ID));
59  if (new_rsc != NULL && new_rsc->fns != NULL) {
60  new_rsc->fns->free(new_rsc);
61  }
62  continue;
63  }
64 
65  group_data->num_children++;
66  rsc->children = g_list_append(rsc->children, new_rsc);
67 
68  if (group_data->first_child == NULL) {
69  group_data->first_child = new_rsc;
70  }
71  group_data->last_child = new_rsc;
72  pe_rsc_trace(rsc, "Added %s member %s", rsc->id, new_rsc->id);
73  }
74  }
75 
76  if (group_data->num_children == 0) {
77 #if 0
78  /* Bug #1287 */
79  crm_config_err("Group %s did not have any children", rsc->id);
80  return FALSE;
81 #else
82  crm_config_warn("Group %s did not have any children", rsc->id);
83  return TRUE;
84 #endif
85  }
86 
87  pe_rsc_trace(rsc, "Added %d children to resource %s...", group_data->num_children, rsc->id);
88 
89  return TRUE;
90 }
91 
92 gboolean
93 group_active(resource_t * rsc, gboolean all)
94 {
95  gboolean c_all = TRUE;
96  gboolean c_any = FALSE;
97  GListPtr gIter = rsc->children;
98 
99  for (; gIter != NULL; gIter = gIter->next) {
100  resource_t *child_rsc = (resource_t *) gIter->data;
101 
102  if (child_rsc->fns->active(child_rsc, all)) {
103  c_any = TRUE;
104  } else {
105  c_all = FALSE;
106  }
107  }
108 
109  if (c_any == FALSE) {
110  return FALSE;
111  } else if (all && c_all == FALSE) {
112  return FALSE;
113  }
114  return TRUE;
115 }
116 
117 static void
118 group_print_xml(resource_t * rsc, const char *pre_text, long options, void *print_data)
119 {
120  GListPtr gIter = rsc->children;
121  char *child_text = crm_concat(pre_text, " ", ' ');
122 
123  status_print("%s<group id=\"%s\" ", pre_text, rsc->id);
124  status_print("number_resources=\"%d\" ", g_list_length(rsc->children));
125  status_print(">\n");
126 
127  for (; gIter != NULL; gIter = gIter->next) {
128  resource_t *child_rsc = (resource_t *) gIter->data;
129 
130  child_rsc->fns->print(child_rsc, child_text, options, print_data);
131  }
132 
133  status_print("%s</group>\n", pre_text);
134  free(child_text);
135 }
136 
137 void
138 group_print(resource_t * rsc, const char *pre_text, long options, void *print_data)
139 {
140  char *child_text = NULL;
141  GListPtr gIter = rsc->children;
142 
143  if (pre_text == NULL) {
144  pre_text = " ";
145  }
146 
147  if (options & pe_print_xml) {
148  group_print_xml(rsc, pre_text, options, print_data);
149  return;
150  }
151 
152  child_text = crm_concat(pre_text, " ", ' ');
153 
154  status_print("%sResource Group: %s", pre_text ? pre_text : "", rsc->id);
155 
156  if (options & pe_print_html) {
157  status_print("\n<ul>\n");
158 
159  } else if ((options & pe_print_log) == 0) {
160  status_print("\n");
161  }
162 
163  if (options & pe_print_brief) {
164  print_rscs_brief(rsc->children, child_text, options, print_data, TRUE);
165 
166  } else {
167  for (; gIter != NULL; gIter = gIter->next) {
168  resource_t *child_rsc = (resource_t *) gIter->data;
169 
170  if (options & pe_print_html) {
171  status_print("<li>\n");
172  }
173  child_rsc->fns->print(child_rsc, child_text, options, print_data);
174  if (options & pe_print_html) {
175  status_print("</li>\n");
176  }
177  }
178  }
179 
180  if (options & pe_print_html) {
181  status_print("</ul>\n");
182  }
183  free(child_text);
184 }
185 
186 void
188 {
189  CRM_CHECK(rsc != NULL, return);
190 
191  pe_rsc_trace(rsc, "Freeing %s", rsc->id);
192 
193  for (GListPtr gIter = rsc->children; gIter != NULL; gIter = gIter->next) {
194  resource_t *child_rsc = (resource_t *) gIter->data;
195 
196  CRM_ASSERT(child_rsc);
197  pe_rsc_trace(child_rsc, "Freeing child %s", child_rsc->id);
198  child_rsc->fns->free(child_rsc);
199  }
200 
201  pe_rsc_trace(rsc, "Freeing child list");
202  g_list_free(rsc->children);
203 
204  common_free(rsc);
205 }
206 
207 enum rsc_role_e
208 group_resource_state(const resource_t * rsc, gboolean current)
209 {
210  enum rsc_role_e group_role = RSC_ROLE_UNKNOWN;
211  GListPtr gIter = rsc->children;
212 
213  for (; gIter != NULL; gIter = gIter->next) {
214  resource_t *child_rsc = (resource_t *) gIter->data;
215  enum rsc_role_e role = child_rsc->fns->state(child_rsc, current);
216 
217  if (role > group_role) {
218  group_role = role;
219  }
220  }
221 
222  pe_rsc_trace(rsc, "%s role: %s", rsc->id, role2text(group_role));
223  return group_role;
224 }
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:190
xmlNode * xml
Definition: status.h:294
void group_free(resource_t *rsc)
Definition: group.c:187
gboolean group_active(resource_t *rsc, gboolean all)
Definition: group.c:93
void(* free)(resource_t *)
Definition: complex.h:41
#define crm_config_err(fmt...)
Definition: crm_internal.h:225
#define XML_RSC_ATTR_INCARNATION
Definition: msg_xml.h:212
gboolean common_unpack(xmlNode *xml_obj, resource_t **rsc, resource_t *parent, pe_working_set_t *data_set)
Definition: complex.c:463
void common_free(resource_t *rsc)
Definition: complex.c:918
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition: nvpair.c:216
#define status_print(fmt, args...)
Definition: unpack.h:79
enum rsc_role_e(* state)(const resource_t *, gboolean)
Definition: complex.h:39
void print_rscs_brief(GListPtr rsc_list, const char *pre_text, long options, void *print_data, gboolean print_all)
Definition: native.c:976
GListPtr children
Definition: status.h:337
char * id
Definition: status.h:292
const char * role2text(enum rsc_role_e role)
Definition: common.c:365
gboolean group_unpack(resource_t *rsc, pe_working_set_t *data_set)
Definition: group.c:22
#define XML_ATTR_ID
Definition: msg_xml.h:102
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:393
#define XML_CIB_TAG_RESOURCE
Definition: msg_xml.h:196
resource_object_functions_t * fns
Definition: status.h:301
void * variant_opaque
Definition: status.h:299
#define XML_RSC_ATTR_ORDERED
Definition: msg_xml.h:210
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
Definition: strings.c:245
gboolean(* active)(resource_t *, gboolean)
Definition: complex.h:38
#define crm_config_warn(fmt...)
Definition: crm_internal.h:226
enum rsc_role_e group_resource_state(const resource_t *rsc, gboolean current)
Definition: group.c:208
void(* print)(resource_t *, const char *, long, void *)
Definition: complex.h:37
int crm_str_to_boolean(const char *s, int *ret)
Definition: strings.c:208
GHashTable * meta
Definition: status.h:333
Cluster status and scheduling.
#define CRM_ASSERT(expr)
Definition: error.h:20
rsc_role_e
Definition: common.h:81
void group_print(resource_t *rsc, const char *pre_text, long options, void *print_data)
Definition: group.c:138
#define pe_rsc_trace(rsc, fmt, args...)
Definition: internal.h:16
char * crm_concat(const char *prefix, const char *suffix, char join)
Definition: strings.c:33
#define pe_err(fmt...)
Definition: internal.h:18
GList * GListPtr
Definition: crm.h:210