pacemaker  2.0.2-debe490
Scalable High-Availability cluster resource manager
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 
139 static void
140 pe_free_resources(GListPtr resources)
141 {
142  resource_t *rsc = NULL;
143  GListPtr iterator = resources;
144 
145  while (iterator != NULL) {
146  rsc = (resource_t *) iterator->data;
147  iterator = iterator->next;
148  rsc->fns->free(rsc);
149  }
150  if (resources != NULL) {
151  g_list_free(resources);
152  }
153 }
154 
155 static void
156 pe_free_actions(GListPtr actions)
157 {
158  GListPtr iterator = actions;
159 
160  while (iterator != NULL) {
161  pe_free_action(iterator->data);
162  iterator = iterator->next;
163  }
164  if (actions != NULL) {
165  g_list_free(actions);
166  }
167 }
168 
169 static void
170 pe_free_nodes(GListPtr nodes)
171 {
172  for (GList *iterator = nodes; iterator != NULL; iterator = iterator->next) {
173  pe_node_t *node = (pe_node_t *) iterator->data;
174 
175  // Shouldn't be possible, but to be safe ...
176  if (node == NULL) {
177  continue;
178  }
179  if (node->details == NULL) {
180  free(node);
181  continue;
182  }
183 
184  /* This is called after pe_free_resources(), which means that we can't
185  * use node->details->uname for Pacemaker Remote nodes.
186  */
187  crm_trace("Freeing node %s", (pe__is_guest_or_remote_node(node)?
188  "(guest or remote)" : node->details->uname));
189 
190  if (node->details->attrs != NULL) {
191  g_hash_table_destroy(node->details->attrs);
192  }
193  if (node->details->utilization != NULL) {
194  g_hash_table_destroy(node->details->utilization);
195  }
196  if (node->details->digest_cache != NULL) {
197  g_hash_table_destroy(node->details->digest_cache);
198  }
199  g_list_free(node->details->running_rsc);
200  g_list_free(node->details->allocated_rsc);
201  free(node->details);
202  free(node);
203  }
204  if (nodes != NULL) {
205  g_list_free(nodes);
206  }
207 }
208 
209 static void
210 pe__free_ordering(GListPtr constraints)
211 {
212  GListPtr iterator = constraints;
213 
214  while (iterator != NULL) {
215  pe__ordering_t *order = iterator->data;
216 
217  iterator = iterator->next;
218 
219  free(order->lh_action_task);
220  free(order->rh_action_task);
221  free(order);
222  }
223  if (constraints != NULL) {
224  g_list_free(constraints);
225  }
226 }
227 
228 static void
229 pe__free_location(GListPtr constraints)
230 {
231  GListPtr iterator = constraints;
232 
233  while (iterator != NULL) {
234  pe__location_t *cons = iterator->data;
235 
236  iterator = iterator->next;
237 
238  g_list_free_full(cons->node_list_rh, free);
239  free(cons->id);
240  free(cons);
241  }
242  if (constraints != NULL) {
243  g_list_free(constraints);
244  }
245 }
246 
255 void
257 {
258  if (data_set == NULL) {
259  return;
260  }
261 
262  clear_bit(data_set->flags, pe_flag_have_status);
263  if (data_set->config_hash != NULL) {
264  g_hash_table_destroy(data_set->config_hash);
265  }
266 
267  if (data_set->singletons != NULL) {
268  g_hash_table_destroy(data_set->singletons);
269  }
270 
271  if (data_set->tickets) {
272  g_hash_table_destroy(data_set->tickets);
273  }
274 
275  if (data_set->template_rsc_sets) {
276  g_hash_table_destroy(data_set->template_rsc_sets);
277  }
278 
279  if (data_set->tags) {
280  g_hash_table_destroy(data_set->tags);
281  }
282 
283  free(data_set->dc_uuid);
284 
285  crm_trace("deleting resources");
286  pe_free_resources(data_set->resources);
287 
288  crm_trace("deleting actions");
289  pe_free_actions(data_set->actions);
290 
291  crm_trace("deleting nodes");
292  pe_free_nodes(data_set->nodes);
293 
294  pe__free_param_checks(data_set);
295  g_list_free(data_set->stop_needed);
296  free_xml(data_set->graph);
297  crm_time_free(data_set->now);
298  free_xml(data_set->input);
299  free_xml(data_set->failed);
300 
301  set_working_set_defaults(data_set);
302 
303  CRM_CHECK(data_set->ordering_constraints == NULL,;
304  );
305  CRM_CHECK(data_set->placement_constraints == NULL,;
306  );
307 }
308 
314 void
316 {
317  if (data_set == NULL) {
318  return;
319  }
320 
321  crm_trace("Deleting %d ordering constraints",
322  g_list_length(data_set->ordering_constraints));
323  pe__free_ordering(data_set->ordering_constraints);
324  data_set->ordering_constraints = NULL;
325 
326  crm_trace("Deleting %d location constraints",
327  g_list_length(data_set->placement_constraints));
328  pe__free_location(data_set->placement_constraints);
329  data_set->placement_constraints = NULL;
330 
331  crm_trace("Deleting %d colocation constraints",
332  g_list_length(data_set->colocation_constraints));
333  g_list_free_full(data_set->colocation_constraints, free);
334  data_set->colocation_constraints = NULL;
335 
336  crm_trace("Deleting %d ticket constraints",
337  g_list_length(data_set->ticket_constraints));
338  g_list_free_full(data_set->ticket_constraints, free);
339  data_set->ticket_constraints = NULL;
340 
341  cleanup_calculations(data_set);
342 }
343 
344 void
346 {
347  memset(data_set, 0, sizeof(pe_working_set_t));
348 
349  data_set->order_id = 1;
350  data_set->action_id = 1;
352 
353  data_set->flags = 0x0ULL;
357 }
358 
359 resource_t *
360 pe_find_resource(GListPtr rsc_list, const char *id)
361 {
362  return pe_find_resource_with_flags(rsc_list, id, pe_find_renamed);
363 }
364 
365 resource_t *
366 pe_find_resource_with_flags(GListPtr rsc_list, const char *id, enum pe_find flags)
367 {
368  GListPtr rIter = NULL;
369 
370  for (rIter = rsc_list; id && rIter; rIter = rIter->next) {
371  resource_t *parent = rIter->data;
372 
373  resource_t *match =
374  parent->fns->find_rsc(parent, id, NULL, flags);
375  if (match != NULL) {
376  return match;
377  }
378  }
379  crm_trace("No match for %s", id);
380  return NULL;
381 }
382 
383 node_t *
384 pe_find_node_any(GListPtr nodes, const char *id, const char *uname)
385 {
386  node_t *match = pe_find_node_id(nodes, id);
387 
388  if (match) {
389  return match;
390  }
391  crm_trace("Looking up %s via its uname instead", uname);
392  return pe_find_node(nodes, uname);
393 }
394 
395 node_t *
396 pe_find_node_id(GListPtr nodes, const char *id)
397 {
398  GListPtr gIter = nodes;
399 
400  for (; gIter != NULL; gIter = gIter->next) {
401  node_t *node = (node_t *) gIter->data;
402 
403  if (node && safe_str_eq(node->details->id, id)) {
404  return node;
405  }
406  }
407  /* error */
408  return NULL;
409 }
410 
411 node_t *
412 pe_find_node(GListPtr nodes, const char *uname)
413 {
414  GListPtr gIter = nodes;
415 
416  for (; gIter != NULL; gIter = gIter->next) {
417  node_t *node = (node_t *) gIter->data;
418 
419  if (node && safe_str_eq(node->details->uname, uname)) {
420  return node;
421  }
422  }
423  /* error */
424  return NULL;
425 }
GHashTable * tags
Definition: pe_types.h:156
#define LOG_TRACE
Definition: logging.h:26
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:156
char uname[MAX_NAME]
Definition: internal.h:87
GListPtr nodes
Definition: pe_types.h:133
GListPtr allocated_rsc
Definition: pe_types.h:202
enum pe_quorum_policy no_quorum_policy
Definition: pe_types.h:125
A dumping ground.
xmlNode * failed
Definition: pe_types.h:141
#define pe_flag_stop_action_orphans
Definition: pe_types.h:97
GHashTable * attrs
Definition: pe_types.h:204
pe_resource_t * pe_find_resource_with_flags(GListPtr rsc_list, const char *id, enum pe_find flags)
Definition: status.c:366
void pe_free_working_set(pe_working_set_t *data_set)
Free a working set.
Definition: status.c:48
#define pe_flag_symmetric_cluster
Definition: pe_types.h:88
pe_working_set_t * pe_new_working_set(void)
Create a new working set.
Definition: status.c:32
xmlNode * op_defaults
Definition: pe_types.h:142
gboolean unpack_resources(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:721
resource_object_functions_t * fns
Definition: pe_types.h:295
gboolean pe__is_guest_or_remote_node(pe_node_t *node)
Definition: remote.c:58
gboolean unpack_tags(xmlNode *xml_tags, pe_working_set_t *data_set)
Definition: unpack.c:781
GListPtr resources
Definition: pe_types.h:134
#define XML_ATTR_DC_UUID
Definition: msg_xml.h:102
#define pe_flag_have_status
Definition: pe_types.h:105
pe_node_t * pe_find_node(GListPtr node_list, const char *uname)
Definition: status.c:412
gboolean unpack_remote_nodes(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:587
#define clear_bit(word, bit)
Definition: crm_internal.h:168
GHashTable * tickets
Definition: pe_types.h:128
#define XML_CIB_TAG_NODES
Definition: msg_xml.h:141
#define pe_flag_have_quorum
Definition: pe_types.h:87
gboolean unpack_config(xmlNode *config, pe_working_set_t *data_set)
Definition: unpack.c:169
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:220
pe_node_t * pe_find_node_id(GListPtr node_list, const char *id)
Definition: status.c:396
char * dc_uuid
Definition: pe_types.h:117
GListPtr placement_constraints
Definition: pe_types.h:135
#define XML_CIB_TAG_RESOURCES
Definition: msg_xml.h:140
void pe_reset_working_set(pe_working_set_t *data_set)
Reset a working set to default state without freeing it.
Definition: status.c:315
#define crm_warn(fmt, args...)
Definition: logging.h:241
void cleanup_calculations(pe_working_set_t *data_set)
Reset working set to default state without freeing it or constraints.
Definition: status.c:256
#define set_bit(word, bit)
Definition: crm_internal.h:167
pe_find
Determine behavior of pe_find_resource_with_flags()
Definition: pe_types.h:78
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition: nvpair.c:556
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:423
xmlNode * rsc_defaults
Definition: pe_types.h:143
pe_resource_t *(* find_rsc)(pe_resource_t *parent, const char *search, const pe_node_t *node, int flags)
Definition: pe_types.h:44
#define crm_trace(fmt, args...)
Definition: logging.h:246
void set_working_set_defaults(pe_working_set_t *data_set)
Definition: status.c:345
struct pe_node_shared_s * details
Definition: pe_types.h:213
#define XML_ATTR_HAVE_QUORUM
Definition: msg_xml.h:85
const char * uname
Definition: pe_types.h:179
GListPtr actions
Definition: pe_types.h:140
Wrappers for and extensions to libxml2.
GHashTable * config_hash
Definition: pe_types.h:127
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:1890
gboolean unpack_status(xmlNode *status, pe_working_set_t *data_set)
Definition: unpack.c:1063
void free_xml(xmlNode *child)
Definition: xml.c:2014
xmlNode * input
Definition: pe_types.h:113
pe_resource_t * pe_find_resource(GListPtr rsc_list, const char *id_rh)
Definition: status.c:360
void pe__free_param_checks(pe_working_set_t *data_set)
Definition: remote.c:256
const char * id
Definition: pe_types.h:178
GListPtr ordering_constraints
Definition: pe_types.h:136
GListPtr colocation_constraints
Definition: pe_types.h:137
match resource ID or LRM history ID
Definition: pe_types.h:79
GListPtr running_rsc
Definition: pe_types.h:201
#define pe_flag_quick_location
Definition: pe_types.h:108
GListPtr ticket_constraints
Definition: pe_types.h:138
gboolean cluster_status(pe_working_set_t *data_set)
Definition: status.c:68
crm_time_t * crm_time_new(const char *string)
Definition: iso8601.c:84
#define XML_CIB_TAG_CRMCONFIG
Definition: msg_xml.h:144
#define XML_CIB_TAG_RSCCONFIG
Definition: msg_xml.h:146
gboolean unpack_nodes(xmlNode *xml_nodes, pe_working_set_t *data_set)
Definition: unpack.c:501
void(* free)(pe_resource_t *)
Definition: pe_types.h:53
GHashTable * utilization
Definition: pe_types.h:205
GHashTable * digest_cache
cache of calculated resource digests
Definition: pe_types.h:206
void pe_free_action(action_t *action)
Definition: utils.c:1313
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:139
#define XML_CIB_TAG_TAGS
Definition: msg_xml.h:387
gboolean crm_is_true(const char *s)
Definition: strings.c:172
GHashTable * singletons
Definition: pe_types.h:131
unsigned long long flags
Definition: pe_types.h:122
#define safe_str_eq(a, b)
Definition: util.h:59
#define XML_CIB_TAG_OPCONFIG
Definition: msg_xml.h:145
GList * GListPtr
Definition: crm.h:192
crm_time_t * now
Definition: pe_types.h:114
GHashTable * template_rsc_sets
Definition: pe_types.h:154
pe_node_t * pe_find_node_any(GListPtr node_list, const char *id, const char *uname)
Definition: status.c:384
uint64_t flags
Definition: remote.c:148
GList * stop_needed
Definition: pe_types.h:162
xmlNode * graph
Definition: pe_types.h:152
void crm_time_free(crm_time_t *dt)
Definition: iso8601.c:101
#define pe_flag_stop_rsc_orphans
Definition: pe_types.h:96