pacemaker  2.0.4-2deceaa
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-2020 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 <sys/param.h>
13 
14 #include <crm/crm.h>
15 #include <crm/msg_xml.h>
16 #include <crm/common/xml.h>
17 
18 #include <glib.h>
19 
20 #include <crm/pengine/internal.h>
21 #include <pe_status_private.h>
22 
35 {
36  pe_working_set_t *data_set = calloc(1, sizeof(pe_working_set_t));
37 
38  if (data_set != NULL) {
39  set_working_set_defaults(data_set);
40  }
41  return data_set;
42 }
43 
49 void
51 {
52  if (data_set != NULL) {
53  pe_reset_working_set(data_set);
54  free(data_set);
55  }
56 }
57 
58 /*
59  * Unpack everything
60  * At the end you'll have:
61  * - A list of nodes
62  * - A list of resources (each with any dependencies on other resources)
63  * - A list of constraints between resources and nodes
64  * - A list of constraints between start/stop actions
65  * - A list of nodes that need to be stonith'd
66  * - A list of nodes that need to be shutdown
67  * - A list of the possible stop/start actions (without dependencies)
68  */
69 gboolean
71 {
72  xmlNode *config = get_xpath_object("//"XML_CIB_TAG_CRMCONFIG, data_set->input, LOG_TRACE);
73  xmlNode *cib_nodes = get_xpath_object("//"XML_CIB_TAG_NODES, data_set->input, LOG_TRACE);
74  xmlNode *cib_resources = get_xpath_object("//"XML_CIB_TAG_RESOURCES, data_set->input, LOG_TRACE);
75  xmlNode *cib_status = get_xpath_object("//"XML_CIB_TAG_STATUS, data_set->input, LOG_TRACE);
76  xmlNode *cib_tags = get_xpath_object("//" XML_CIB_TAG_TAGS, data_set->input,
77  LOG_NEVER);
78  const char *value = crm_element_value(data_set->input, XML_ATTR_HAVE_QUORUM);
79 
80  crm_trace("Beginning unpack");
81 
82  /* reset remaining global variables */
83  data_set->failed = create_xml_node(NULL, "failed-ops");
84 
85  if (data_set->input == NULL) {
86  return FALSE;
87  }
88 
89  if (data_set->now == NULL) {
90  data_set->now = crm_time_new(NULL);
91  }
92 
93  if (data_set->dc_uuid == NULL) {
94  data_set->dc_uuid = crm_element_value_copy(data_set->input,
96  }
97 
99  if (crm_is_true(value)) {
100  set_bit(data_set->flags, pe_flag_have_quorum);
101  }
102 
104  data_set->input, LOG_NEVER);
106  data_set->input, LOG_NEVER);
107 
108  unpack_config(config, data_set);
109 
110  if (is_not_set(data_set->flags, pe_flag_quick_location)
111  && is_not_set(data_set->flags, pe_flag_have_quorum)
112  && data_set->no_quorum_policy != no_quorum_ignore) {
113  crm_warn("Fencing and resource management disabled due to lack of quorum");
114  }
115 
116  unpack_nodes(cib_nodes, data_set);
117 
118  if(is_not_set(data_set->flags, pe_flag_quick_location)) {
119  unpack_remote_nodes(cib_resources, data_set);
120  }
121 
122  unpack_resources(cib_resources, data_set);
123  unpack_tags(cib_tags, data_set);
124 
125  if(is_not_set(data_set->flags, pe_flag_quick_location)) {
126  unpack_status(cib_status, data_set);
127  }
128 
129  if (is_not_set(data_set->flags, pe_flag_no_counts)) {
130  for (GList *item = data_set->resources; item != NULL;
131  item = item->next) {
132  ((pe_resource_t *) (item->data))->fns->count(item->data);
133  }
134  }
135 
136  set_bit(data_set->flags, pe_flag_have_status);
137  return TRUE;
138 }
139 
151 static void
152 pe_free_resources(GListPtr resources)
153 {
154  pe_resource_t *rsc = NULL;
155  GListPtr iterator = resources;
156 
157  while (iterator != NULL) {
158  rsc = (pe_resource_t *) iterator->data;
159  iterator = iterator->next;
160  rsc->fns->free(rsc);
161  }
162  if (resources != NULL) {
163  g_list_free(resources);
164  }
165 }
166 
167 static void
168 pe_free_actions(GListPtr actions)
169 {
170  GListPtr iterator = actions;
171 
172  while (iterator != NULL) {
173  pe_free_action(iterator->data);
174  iterator = iterator->next;
175  }
176  if (actions != NULL) {
177  g_list_free(actions);
178  }
179 }
180 
181 static void
182 pe_free_nodes(GListPtr nodes)
183 {
184  for (GList *iterator = nodes; iterator != NULL; iterator = iterator->next) {
185  pe_node_t *node = (pe_node_t *) iterator->data;
186 
187  // Shouldn't be possible, but to be safe ...
188  if (node == NULL) {
189  continue;
190  }
191  if (node->details == NULL) {
192  free(node);
193  continue;
194  }
195 
196  /* This is called after pe_free_resources(), which means that we can't
197  * use node->details->uname for Pacemaker Remote nodes.
198  */
199  crm_trace("Freeing node %s", (pe__is_guest_or_remote_node(node)?
200  "(guest or remote)" : node->details->uname));
201 
202  if (node->details->attrs != NULL) {
203  g_hash_table_destroy(node->details->attrs);
204  }
205  if (node->details->utilization != NULL) {
206  g_hash_table_destroy(node->details->utilization);
207  }
208  if (node->details->digest_cache != NULL) {
209  g_hash_table_destroy(node->details->digest_cache);
210  }
211  g_list_free(node->details->running_rsc);
212  g_list_free(node->details->allocated_rsc);
213  free(node->details);
214  free(node);
215  }
216  if (nodes != NULL) {
217  g_list_free(nodes);
218  }
219 }
220 
221 static void
222 pe__free_ordering(GListPtr constraints)
223 {
224  GListPtr iterator = constraints;
225 
226  while (iterator != NULL) {
227  pe__ordering_t *order = iterator->data;
228 
229  iterator = iterator->next;
230 
231  free(order->lh_action_task);
232  free(order->rh_action_task);
233  free(order);
234  }
235  if (constraints != NULL) {
236  g_list_free(constraints);
237  }
238 }
239 
240 static void
241 pe__free_location(GListPtr constraints)
242 {
243  GListPtr iterator = constraints;
244 
245  while (iterator != NULL) {
246  pe__location_t *cons = iterator->data;
247 
248  iterator = iterator->next;
249 
250  g_list_free_full(cons->node_list_rh, free);
251  free(cons->id);
252  free(cons);
253  }
254  if (constraints != NULL) {
255  g_list_free(constraints);
256  }
257 }
258 
267 void
269 {
270  if (data_set == NULL) {
271  return;
272  }
273 
274  clear_bit(data_set->flags, pe_flag_have_status);
275  if (data_set->config_hash != NULL) {
276  g_hash_table_destroy(data_set->config_hash);
277  }
278 
279  if (data_set->singletons != NULL) {
280  g_hash_table_destroy(data_set->singletons);
281  }
282 
283  if (data_set->tickets) {
284  g_hash_table_destroy(data_set->tickets);
285  }
286 
287  if (data_set->template_rsc_sets) {
288  g_hash_table_destroy(data_set->template_rsc_sets);
289  }
290 
291  if (data_set->tags) {
292  g_hash_table_destroy(data_set->tags);
293  }
294 
295  free(data_set->dc_uuid);
296 
297  crm_trace("deleting resources");
298  pe_free_resources(data_set->resources);
299 
300  crm_trace("deleting actions");
301  pe_free_actions(data_set->actions);
302 
303  crm_trace("deleting nodes");
304  pe_free_nodes(data_set->nodes);
305 
306  pe__free_param_checks(data_set);
307  g_list_free(data_set->stop_needed);
308  free_xml(data_set->graph);
309  crm_time_free(data_set->now);
310  free_xml(data_set->input);
311  free_xml(data_set->failed);
312 
313  set_working_set_defaults(data_set);
314 
315  CRM_CHECK(data_set->ordering_constraints == NULL,;
316  );
317  CRM_CHECK(data_set->placement_constraints == NULL,;
318  );
319 }
320 
326 void
328 {
329  if (data_set == NULL) {
330  return;
331  }
332 
333  crm_trace("Deleting %d ordering constraints",
334  g_list_length(data_set->ordering_constraints));
335  pe__free_ordering(data_set->ordering_constraints);
336  data_set->ordering_constraints = NULL;
337 
338  crm_trace("Deleting %d location constraints",
339  g_list_length(data_set->placement_constraints));
340  pe__free_location(data_set->placement_constraints);
341  data_set->placement_constraints = NULL;
342 
343  crm_trace("Deleting %d colocation constraints",
344  g_list_length(data_set->colocation_constraints));
345  g_list_free_full(data_set->colocation_constraints, free);
346  data_set->colocation_constraints = NULL;
347 
348  crm_trace("Deleting %d ticket constraints",
349  g_list_length(data_set->ticket_constraints));
350  g_list_free_full(data_set->ticket_constraints, free);
351  data_set->ticket_constraints = NULL;
352 
353  cleanup_calculations(data_set);
354 }
355 
356 void
358 {
359  memset(data_set, 0, sizeof(pe_working_set_t));
360 
361  data_set->order_id = 1;
362  data_set->action_id = 1;
364 
365  data_set->flags = 0x0ULL;
369 #ifdef DEFAULT_CONCURRENT_FENCING_TRUE
371 #endif
372 }
373 
375 pe_find_resource(GListPtr rsc_list, const char *id)
376 {
377  return pe_find_resource_with_flags(rsc_list, id, pe_find_renamed);
378 }
379 
381 pe_find_resource_with_flags(GListPtr rsc_list, const char *id, enum pe_find flags)
382 {
383  GListPtr rIter = NULL;
384 
385  for (rIter = rsc_list; id && rIter; rIter = rIter->next) {
386  pe_resource_t *parent = rIter->data;
387 
388  pe_resource_t *match =
389  parent->fns->find_rsc(parent, id, NULL, flags);
390  if (match != NULL) {
391  return match;
392  }
393  }
394  crm_trace("No match for %s", id);
395  return NULL;
396 }
397 
398 pe_node_t *
399 pe_find_node_any(GListPtr nodes, const char *id, const char *uname)
400 {
401  pe_node_t *match = pe_find_node_id(nodes, id);
402 
403  if (match) {
404  return match;
405  }
406  crm_trace("Looking up %s via its uname instead", uname);
407  return pe_find_node(nodes, uname);
408 }
409 
410 pe_node_t *
411 pe_find_node_id(GListPtr nodes, const char *id)
412 {
413  GListPtr gIter = nodes;
414 
415  for (; gIter != NULL; gIter = gIter->next) {
416  pe_node_t *node = (pe_node_t *) gIter->data;
417 
418  if (node && safe_str_eq(node->details->id, id)) {
419  return node;
420  }
421  }
422  /* error */
423  return NULL;
424 }
425 
426 pe_node_t *
427 pe_find_node(GListPtr nodes, const char *uname)
428 {
429  GListPtr gIter = nodes;
430 
431  for (; gIter != NULL; gIter = gIter->next) {
432  pe_node_t *node = (pe_node_t *) gIter->data;
433 
434  if (node && safe_str_eq(node->details->uname, uname)) {
435  return node;
436  }
437  }
438  /* error */
439  return NULL;
440 }
GHashTable * tags
Definition: pe_types.h:169
#define LOG_TRACE
Definition: logging.h:36
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:233
char uname[MAX_NAME]
Definition: internal.h:85
GListPtr nodes
Definition: pe_types.h:146
GListPtr allocated_rsc
Definition: pe_types.h:219
enum pe_quorum_policy no_quorum_policy
Definition: pe_types.h:138
A dumping ground.
xmlNode * failed
Definition: pe_types.h:154
#define pe_flag_stop_action_orphans
Definition: pe_types.h:101
GHashTable * attrs
Definition: pe_types.h:221
G_GNUC_INTERNAL gboolean unpack_remote_nodes(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:599
pe_resource_t * pe_find_resource_with_flags(GListPtr rsc_list, const char *id, enum pe_find flags)
Definition: status.c:381
#define pe_flag_concurrent_fencing
Definition: pe_types.h:98
void pe_free_working_set(pe_working_set_t *data_set)
Free a working set.
Definition: status.c:50
#define pe_flag_symmetric_cluster
Definition: pe_types.h:92
pe_working_set_t * pe_new_working_set(void)
Create a new working set.
Definition: status.c:34
xmlNode * op_defaults
Definition: pe_types.h:155
resource_object_functions_t * fns
Definition: pe_types.h:316
gboolean pe__is_guest_or_remote_node(pe_node_t *node)
Definition: remote.c:58
G_GNUC_INTERNAL gboolean unpack_status(xmlNode *status, pe_working_set_t *data_set)
Definition: unpack.c:1091
GListPtr resources
Definition: pe_types.h:147
#define XML_ATTR_DC_UUID
Definition: msg_xml.h:102
#define pe_flag_no_counts
Don&#39;t count total, disabled and blocked resource instances.
Definition: pe_types.h:118
#define pe_flag_have_status
Definition: pe_types.h:110
pe_node_t * pe_find_node(GListPtr node_list, const char *uname)
Definition: status.c:427
int order_id
Deprecated (will be removed in a future release)
Definition: pe_types.h:161
#define clear_bit(word, bit)
Definition: crm_internal.h:69
GHashTable * tickets
Definition: pe_types.h:141
#define XML_CIB_TAG_NODES
Definition: msg_xml.h:141
#define pe_flag_have_quorum
Definition: pe_types.h:91
#define LOG_NEVER
Definition: logging.h:46
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:211
pe_node_t * pe_find_node_id(GListPtr node_list, const char *id)
Definition: status.c:411
char * dc_uuid
Definition: pe_types.h:130
GListPtr placement_constraints
Definition: pe_types.h:148
#define XML_CIB_TAG_RESOURCES
Definition: msg_xml.h:140
G_GNUC_INTERNAL gboolean unpack_tags(xmlNode *xml_tags, pe_working_set_t *data_set)
Definition: unpack.c:799
void pe_reset_working_set(pe_working_set_t *data_set)
Reset a working set to default state without freeing it.
Definition: status.c:327
#define crm_warn(fmt, args...)
Definition: logging.h:364
void cleanup_calculations(pe_working_set_t *data_set)
Reset working set to default state without freeing it or constraints.
Definition: status.c:268
#define set_bit(word, bit)
Definition: crm_internal.h:68
pe_find
Determine behavior of pe_find_resource_with_flags()
Definition: pe_types.h:80
G_GNUC_INTERNAL gboolean unpack_nodes(xmlNode *xml_nodes, pe_working_set_t *data_set)
Definition: unpack.c:509
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition: nvpair.c:725
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:522
xmlNode * rsc_defaults
Definition: pe_types.h:156
pe_resource_t *(* find_rsc)(pe_resource_t *parent, const char *search, const pe_node_t *node, int flags)
Definition: pe_types.h:45
#define crm_trace(fmt, args...)
Definition: logging.h:369
void set_working_set_defaults(pe_working_set_t *data_set)
Definition: status.c:357
struct pe_node_shared_s * details
Definition: pe_types.h:231
G_GNUC_INTERNAL gboolean unpack_resources(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:736
#define XML_ATTR_HAVE_QUORUM
Definition: msg_xml.h:85
const char * uname
Definition: pe_types.h:196
GListPtr actions
Definition: pe_types.h:153
Wrappers for and extensions to libxml2.
GHashTable * config_hash
Definition: pe_types.h:140
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:1976
void free_xml(xmlNode *child)
Definition: xml.c:2136
xmlNode * input
Definition: pe_types.h:126
pe_resource_t * pe_find_resource(GListPtr rsc_list, const char *id_rh)
Definition: status.c:375
void pe__free_param_checks(pe_working_set_t *data_set)
Definition: remote.c:263
const char * id
Definition: pe_types.h:195
GListPtr ordering_constraints
Definition: pe_types.h:149
GListPtr colocation_constraints
Definition: pe_types.h:150
match resource ID or LRM history ID
Definition: pe_types.h:81
GListPtr running_rsc
Definition: pe_types.h:218
#define pe_flag_quick_location
Definition: pe_types.h:113
GListPtr ticket_constraints
Definition: pe_types.h:151
gboolean cluster_status(pe_working_set_t *data_set)
Definition: status.c:70
crm_time_t * crm_time_new(const char *string)
Definition: iso8601.c:93
#define XML_CIB_TAG_CRMCONFIG
Definition: msg_xml.h:144
#define XML_CIB_TAG_RSCCONFIG
Definition: msg_xml.h:146
void(* free)(pe_resource_t *)
Definition: pe_types.h:54
GHashTable * utilization
Definition: pe_types.h:222
GHashTable * digest_cache
cache of calculated resource digests
Definition: pe_types.h:223
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:139
#define XML_CIB_TAG_TAGS
Definition: msg_xml.h:391
gboolean crm_is_true(const char *s)
Definition: strings.c:278
GHashTable * singletons
Definition: pe_types.h:144
unsigned long long flags
Definition: pe_types.h:135
#define safe_str_eq(a, b)
Definition: util.h:65
G_GNUC_INTERNAL gboolean unpack_config(xmlNode *config, pe_working_set_t *data_set)
Definition: unpack.c:186
#define XML_CIB_TAG_OPCONFIG
Definition: msg_xml.h:145
GList * GListPtr
Definition: crm.h:214
crm_time_t * now
Definition: pe_types.h:127
GHashTable * template_rsc_sets
Definition: pe_types.h:167
pe_node_t * pe_find_node_any(GListPtr node_list, const char *id, const char *uname)
Definition: status.c:399
uint64_t flags
Definition: remote.c:149
GList * stop_needed
Definition: pe_types.h:175
void pe_free_action(pe_action_t *action)
Definition: utils.c:1357
xmlNode * graph
Definition: pe_types.h:165
void crm_time_free(crm_time_t *dt)
Definition: iso8601.c:141
#define pe_flag_stop_rsc_orphans
Definition: pe_types.h:100