pacemaker  2.0.1-15814c6c0d
Scalable High-Availability cluster resource manager
status.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2018 Andrew Beekhof <andrew@beekhof.net>
3  *
4  * This source code is licensed under the GNU Lesser General Public License
5  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
6  */
7 
8 #include <crm_internal.h>
9 
10 #include <sys/param.h>
11 
12 #include <crm/crm.h>
13 #include <crm/msg_xml.h>
14 #include <crm/common/xml.h>
15 
16 #include <glib.h>
17 
18 #include <crm/pengine/internal.h>
19 #include <unpack.h>
20 
33 {
34  pe_working_set_t *data_set = calloc(1, sizeof(pe_working_set_t));
35 
36  if (data_set != NULL) {
37  set_working_set_defaults(data_set);
38  }
39  return data_set;
40 }
41 
47 void
49 {
50  if (data_set != NULL) {
51  pe_reset_working_set(data_set);
52  free(data_set);
53  }
54 }
55 
56 /*
57  * Unpack everything
58  * At the end you'll have:
59  * - A list of nodes
60  * - A list of resources (each with any dependencies on other resources)
61  * - A list of constraints between resources and nodes
62  * - A list of constraints between start/stop actions
63  * - A list of nodes that need to be stonith'd
64  * - A list of nodes that need to be shutdown
65  * - A list of the possible stop/start actions (without dependencies)
66  */
67 gboolean
69 {
70  xmlNode *config = get_xpath_object("//"XML_CIB_TAG_CRMCONFIG, data_set->input, LOG_TRACE);
71  xmlNode *cib_nodes = get_xpath_object("//"XML_CIB_TAG_NODES, data_set->input, LOG_TRACE);
72  xmlNode *cib_resources = get_xpath_object("//"XML_CIB_TAG_RESOURCES, data_set->input, LOG_TRACE);
73  xmlNode *cib_status = get_xpath_object("//"XML_CIB_TAG_STATUS, data_set->input, LOG_TRACE);
74  xmlNode *cib_tags = get_xpath_object("//"XML_CIB_TAG_TAGS, data_set->input, LOG_TRACE);
75  const char *value = crm_element_value(data_set->input, XML_ATTR_HAVE_QUORUM);
76 
77  crm_trace("Beginning unpack");
78 
79  /* reset remaining global variables */
80  data_set->failed = create_xml_node(NULL, "failed-ops");
81 
82  if (data_set->input == NULL) {
83  return FALSE;
84  }
85 
86  if (data_set->now == NULL) {
87  data_set->now = crm_time_new(NULL);
88  }
89 
90  if (data_set->dc_uuid == NULL) {
91  data_set->dc_uuid = crm_element_value_copy(data_set->input,
93  }
94 
96  if (crm_is_true(value)) {
97  set_bit(data_set->flags, pe_flag_have_quorum);
98  }
99 
100  data_set->op_defaults = get_xpath_object("//"XML_CIB_TAG_OPCONFIG, data_set->input, LOG_TRACE);
102 
103  unpack_config(config, data_set);
104 
105  if (is_not_set(data_set->flags, pe_flag_quick_location)
106  && is_not_set(data_set->flags, pe_flag_have_quorum)
107  && data_set->no_quorum_policy != no_quorum_ignore) {
108  crm_warn("Fencing and resource management disabled due to lack of quorum");
109  }
110 
111  unpack_nodes(cib_nodes, data_set);
112 
113  if(is_not_set(data_set->flags, pe_flag_quick_location)) {
114  unpack_remote_nodes(cib_resources, data_set);
115  }
116 
117  unpack_resources(cib_resources, data_set);
118  unpack_tags(cib_tags, data_set);
119 
120  if(is_not_set(data_set->flags, pe_flag_quick_location)) {
121  unpack_status(cib_status, data_set);
122  }
123 
124  set_bit(data_set->flags, pe_flag_have_status);
125  return TRUE;
126 }
127 
128 static void
129 pe_free_resources(GListPtr resources)
130 {
131  resource_t *rsc = NULL;
132  GListPtr iterator = resources;
133 
134  while (iterator != NULL) {
135  rsc = (resource_t *) iterator->data;
136  iterator = iterator->next;
137  rsc->fns->free(rsc);
138  }
139  if (resources != NULL) {
140  g_list_free(resources);
141  }
142 }
143 
144 static void
145 pe_free_actions(GListPtr actions)
146 {
147  GListPtr iterator = actions;
148 
149  while (iterator != NULL) {
150  pe_free_action(iterator->data);
151  iterator = iterator->next;
152  }
153  if (actions != NULL) {
154  g_list_free(actions);
155  }
156 }
157 
158 static void
159 pe_free_nodes(GListPtr nodes)
160 {
161  GListPtr iterator = nodes;
162 
163  while (iterator != NULL) {
164  node_t *node = (node_t *) iterator->data;
165  struct pe_node_shared_s *details = node->details;
166 
167  iterator = iterator->next;
168 
169  crm_trace("deleting node");
170  print_node("delete", node, FALSE);
171 
172  if (details != NULL) {
173  crm_trace("%s is being deleted", details->uname);
174  if (details->attrs != NULL) {
175  g_hash_table_destroy(details->attrs);
176  }
177  if (details->utilization != NULL) {
178  g_hash_table_destroy(details->utilization);
179  }
180  if (details->digest_cache != NULL) {
181  g_hash_table_destroy(details->digest_cache);
182  }
183  g_list_free(details->running_rsc);
184  g_list_free(details->allocated_rsc);
185  free(details);
186  }
187  free(node);
188  }
189  if (nodes != NULL) {
190  g_list_free(nodes);
191  }
192 }
193 
194 static void
195 pe__free_ordering(GListPtr constraints)
196 {
197  GListPtr iterator = constraints;
198 
199  while (iterator != NULL) {
200  pe__ordering_t *order = iterator->data;
201 
202  iterator = iterator->next;
203 
204  free(order->lh_action_task);
205  free(order->rh_action_task);
206  free(order);
207  }
208  if (constraints != NULL) {
209  g_list_free(constraints);
210  }
211 }
212 
213 static void
214 pe__free_location(GListPtr constraints)
215 {
216  GListPtr iterator = constraints;
217 
218  while (iterator != NULL) {
219  pe__location_t *cons = iterator->data;
220 
221  iterator = iterator->next;
222 
223  g_list_free_full(cons->node_list_rh, free);
224  free(cons->id);
225  free(cons);
226  }
227  if (constraints != NULL) {
228  g_list_free(constraints);
229  }
230 }
231 
240 void
242 {
243  if (data_set == NULL) {
244  return;
245  }
246 
247  clear_bit(data_set->flags, pe_flag_have_status);
248  if (data_set->config_hash != NULL) {
249  g_hash_table_destroy(data_set->config_hash);
250  }
251 
252  if (data_set->singletons != NULL) {
253  g_hash_table_destroy(data_set->singletons);
254  }
255 
256  if (data_set->tickets) {
257  g_hash_table_destroy(data_set->tickets);
258  }
259 
260  if (data_set->template_rsc_sets) {
261  g_hash_table_destroy(data_set->template_rsc_sets);
262  }
263 
264  if (data_set->tags) {
265  g_hash_table_destroy(data_set->tags);
266  }
267 
268  free(data_set->dc_uuid);
269 
270  crm_trace("deleting resources");
271  pe_free_resources(data_set->resources);
272 
273  crm_trace("deleting actions");
274  pe_free_actions(data_set->actions);
275 
276  crm_trace("deleting nodes");
277  pe_free_nodes(data_set->nodes);
278 
279  pe__free_param_checks(data_set);
280  g_list_free(data_set->stop_needed);
281  free_xml(data_set->graph);
282  crm_time_free(data_set->now);
283  free_xml(data_set->input);
284  free_xml(data_set->failed);
285 
286  set_working_set_defaults(data_set);
287 
288  CRM_CHECK(data_set->ordering_constraints == NULL,;
289  );
290  CRM_CHECK(data_set->placement_constraints == NULL,;
291  );
292 }
293 
299 void
301 {
302  if (data_set == NULL) {
303  return;
304  }
305 
306  crm_trace("Deleting %d ordering constraints",
307  g_list_length(data_set->ordering_constraints));
308  pe__free_ordering(data_set->ordering_constraints);
309  data_set->ordering_constraints = NULL;
310 
311  crm_trace("Deleting %d location constraints",
312  g_list_length(data_set->placement_constraints));
313  pe__free_location(data_set->placement_constraints);
314  data_set->placement_constraints = NULL;
315 
316  crm_trace("Deleting %d colocation constraints",
317  g_list_length(data_set->colocation_constraints));
318  g_list_free_full(data_set->colocation_constraints, free);
319  data_set->colocation_constraints = NULL;
320 
321  crm_trace("Deleting %d ticket constraints",
322  g_list_length(data_set->ticket_constraints));
323  g_list_free_full(data_set->ticket_constraints, free);
324  data_set->ticket_constraints = NULL;
325 
326  cleanup_calculations(data_set);
327 }
328 
329 void
331 {
332  memset(data_set, 0, sizeof(pe_working_set_t));
333 
334  data_set->order_id = 1;
335  data_set->action_id = 1;
337 
338  data_set->flags = 0x0ULL;
342 }
343 
344 resource_t *
345 pe_find_resource(GListPtr rsc_list, const char *id)
346 {
347  return pe_find_resource_with_flags(rsc_list, id, pe_find_renamed);
348 }
349 
350 resource_t *
351 pe_find_resource_with_flags(GListPtr rsc_list, const char *id, enum pe_find flags)
352 {
353  GListPtr rIter = NULL;
354 
355  for (rIter = rsc_list; id && rIter; rIter = rIter->next) {
356  resource_t *parent = rIter->data;
357 
358  resource_t *match =
359  parent->fns->find_rsc(parent, id, NULL, flags);
360  if (match != NULL) {
361  return match;
362  }
363  }
364  crm_trace("No match for %s", id);
365  return NULL;
366 }
367 
368 node_t *
369 pe_find_node_any(GListPtr nodes, const char *id, const char *uname)
370 {
371  node_t *match = pe_find_node_id(nodes, id);
372 
373  if (match) {
374  return match;
375  }
376  crm_trace("Looking up %s via its uname instead", uname);
377  return pe_find_node(nodes, uname);
378 }
379 
380 node_t *
381 pe_find_node_id(GListPtr nodes, const char *id)
382 {
383  GListPtr gIter = nodes;
384 
385  for (; gIter != NULL; gIter = gIter->next) {
386  node_t *node = (node_t *) gIter->data;
387 
388  if (node && safe_str_eq(node->details->id, id)) {
389  return node;
390  }
391  }
392  /* error */
393  return NULL;
394 }
395 
396 node_t *
397 pe_find_node(GListPtr nodes, const char *uname)
398 {
399  GListPtr gIter = nodes;
400 
401  for (; gIter != NULL; gIter = gIter->next) {
402  node_t *node = (node_t *) gIter->data;
403 
404  if (node && safe_str_eq(node->details->uname, uname)) {
405  return node;
406  }
407  }
408  /* error */
409  return NULL;
410 }
GHashTable * tags
Definition: status.h:131
#define LOG_TRACE
Definition: logging.h:35
gboolean unpack_config(xmlNode *config, pe_working_set_t *data_set)
Definition: unpack.c:167
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:165
char uname[MAX_NAME]
Definition: internal.h:82
GListPtr nodes
Definition: status.h:108
enum pe_quorum_policy no_quorum_policy
Definition: status.h:100
A dumping ground.
xmlNode * failed
Definition: status.h:116
void set_working_set_defaults(pe_working_set_t *data_set)
Definition: status.c:330
xmlNode * op_defaults
Definition: status.h:117
resource_t * pe_find_resource_with_flags(GListPtr rsc_list, const char *id, enum pe_find flags)
Definition: status.c:351
resource_object_functions_t * fns
Definition: status.h:270
#define pe_flag_stop_rsc_orphans
Definition: status.h:71
node_t * pe_find_node_any(GListPtr nodes, const char *id, const char *uname)
Definition: status.c:369
match resource ID or LRM history ID
Definition: status.h:54
void print_node(const char *pre_text, node_t *node, gboolean details)
Definition: utils.c:1251
GListPtr resources
Definition: status.h:109
#define XML_ATTR_DC_UUID
Definition: msg_xml.h:100
void cleanup_calculations(pe_working_set_t *data_set)
Reset working set to default state without freeing it or constraints.
Definition: status.c:241
#define clear_bit(word, bit)
Definition: crm_internal.h:166
GHashTable * tickets
Definition: status.h:103
#define XML_CIB_TAG_NODES
Definition: msg_xml.h:139
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:220
char * dc_uuid
Definition: status.h:92
gboolean unpack_resources(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:711
GListPtr placement_constraints
Definition: status.h:110
#define XML_CIB_TAG_RESOURCES
Definition: msg_xml.h:138
gboolean unpack_status(xmlNode *status, pe_working_set_t *data_set)
Definition: unpack.c:1050
#define crm_warn(fmt, args...)
Definition: logging.h:250
#define set_bit(word, bit)
Definition: crm_internal.h:165
gboolean unpack_nodes(xmlNode *xml_nodes, pe_working_set_t *data_set)
Definition: unpack.c:499
xmlNode * rsc_defaults
Definition: status.h:118
#define crm_trace(fmt, args...)
Definition: logging.h:255
gboolean unpack_remote_nodes(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:585
struct pe_node_shared_s * details
Definition: status.h:188
pe_find
Determine behavior of pe_find_resource_with_flags()
Definition: status.h:53
#define XML_ATTR_HAVE_QUORUM
Definition: msg_xml.h:83
const char * uname
Definition: status.h:154
GListPtr actions
Definition: status.h:115
Wrappers for and extensions to libxml2.
GHashTable * config_hash
Definition: status.h:102
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:2015
char * crm_element_value_copy(const xmlNode *data, const char *name)
Definition: xml.c:3383
void(* free)(pe_resource_t *)
Definition: complex.h:34
node_t * pe_find_node(GListPtr nodes, const char *uname)
Definition: status.c:397
void free_xml(xmlNode *child)
Definition: xml.c:2139
xmlNode * input
Definition: status.h:88
const char * crm_element_value(const xmlNode *data, const char *name)
Definition: xml.c:4641
void pe__free_param_checks(pe_working_set_t *data_set)
Definition: remote.c:244
const char * id
Definition: status.h:153
GListPtr ordering_constraints
Definition: status.h:111
GListPtr colocation_constraints
Definition: status.h:112
resource_t * pe_find_resource(GListPtr rsc_list, const char *id)
Definition: status.c:345
node_t * pe_find_node_id(GListPtr nodes, const char *id)
Definition: status.c:381
void pe_free_working_set(pe_working_set_t *data_set)
Free a working set.
Definition: status.c:48
gboolean cluster_status(pe_working_set_t *data_set)
Definition: status.c:68
#define pe_flag_have_status
Definition: status.h:80
#define pe_flag_quick_location
Definition: status.h:83
GListPtr ticket_constraints
Definition: status.h:113
crm_time_t * crm_time_new(const char *string)
Definition: iso8601.c:88
#define XML_CIB_TAG_CRMCONFIG
Definition: msg_xml.h:142
#define XML_CIB_TAG_RSCCONFIG
Definition: msg_xml.h:144
void pe_free_action(action_t *action)
Definition: utils.c:1311
#define pe_flag_have_quorum
Definition: status.h:62
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:137
#define XML_CIB_TAG_TAGS
Definition: msg_xml.h:385
#define pe_flag_stop_action_orphans
Definition: status.h:72
gboolean crm_is_true(const char *s)
Definition: strings.c:156
#define pe_flag_symmetric_cluster
Definition: status.h:63
GHashTable * singletons
Definition: status.h:106
unsigned long long flags
Definition: status.h:97
gboolean unpack_tags(xmlNode *xml_tags, pe_working_set_t *data_set)
Definition: unpack.c:771
#define safe_str_eq(a, b)
Definition: util.h:54
pe_resource_t *(* find_rsc)(pe_resource_t *parent, const char *search, const pe_node_t *node, int flags)
Definition: complex.h:25
#define XML_CIB_TAG_OPCONFIG
Definition: msg_xml.h:143
GList * GListPtr
Definition: crm.h:190
crm_time_t * now
Definition: status.h:89
GHashTable * template_rsc_sets
Definition: status.h:129
uint64_t flags
Definition: remote.c:148
pe_working_set_t * pe_new_working_set()
Create a new working set.
Definition: status.c:32
GList * stop_needed
Definition: status.h:137
void pe_reset_working_set(pe_working_set_t *data_set)
Reset a working set to default state without freeing it.
Definition: status.c:300
xmlNode * graph
Definition: status.h:127
void crm_time_free(crm_time_t *dt)
Definition: iso8601.c:105