pacemaker  2.0.5-ba59be712
Scalable High-Availability cluster resource manager
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 
98  if (crm_is_true(value)) {
100  } else {
102  }
103 
105  data_set->input, LOG_NEVER);
107  data_set->input, LOG_NEVER);
108 
109  unpack_config(config, data_set);
110 
111  if (!pcmk_any_flags_set(data_set->flags,
113  && (data_set->no_quorum_policy != no_quorum_ignore)) {
114  crm_warn("Fencing and resource management disabled due to lack of quorum");
115  }
116 
117  unpack_nodes(cib_nodes, data_set);
118 
119  if (!pcmk_is_set(data_set->flags, pe_flag_quick_location)) {
120  unpack_remote_nodes(cib_resources, data_set);
121  }
122 
123  unpack_resources(cib_resources, data_set);
124  unpack_tags(cib_tags, data_set);
125 
126  if (!pcmk_is_set(data_set->flags, pe_flag_quick_location)) {
127  unpack_status(cib_status, data_set);
128  }
129 
130  if (!pcmk_is_set(data_set->flags, pe_flag_no_counts)) {
131  for (GList *item = data_set->resources; item != NULL;
132  item = item->next) {
133  ((pe_resource_t *) (item->data))->fns->count(item->data);
134  }
135  }
136 
138  return TRUE;
139 }
140 
152 static void
153 pe_free_resources(GListPtr resources)
154 {
155  pe_resource_t *rsc = NULL;
156  GListPtr iterator = resources;
157 
158  while (iterator != NULL) {
159  rsc = (pe_resource_t *) iterator->data;
160  iterator = iterator->next;
161  rsc->fns->free(rsc);
162  }
163  if (resources != NULL) {
164  g_list_free(resources);
165  }
166 }
167 
168 static void
169 pe_free_actions(GListPtr actions)
170 {
171  GListPtr iterator = actions;
172 
173  while (iterator != NULL) {
174  pe_free_action(iterator->data);
175  iterator = iterator->next;
176  }
177  if (actions != NULL) {
178  g_list_free(actions);
179  }
180 }
181 
182 static void
183 pe_free_nodes(GListPtr nodes)
184 {
185  for (GList *iterator = nodes; iterator != NULL; iterator = iterator->next) {
186  pe_node_t *node = (pe_node_t *) iterator->data;
187 
188  // Shouldn't be possible, but to be safe ...
189  if (node == NULL) {
190  continue;
191  }
192  if (node->details == NULL) {
193  free(node);
194  continue;
195  }
196 
197  /* This is called after pe_free_resources(), which means that we can't
198  * use node->details->uname for Pacemaker Remote nodes.
199  */
200  crm_trace("Freeing node %s", (pe__is_guest_or_remote_node(node)?
201  "(guest or remote)" : node->details->uname));
202 
203  if (node->details->attrs != NULL) {
204  g_hash_table_destroy(node->details->attrs);
205  }
206  if (node->details->utilization != NULL) {
207  g_hash_table_destroy(node->details->utilization);
208  }
209  if (node->details->digest_cache != NULL) {
210  g_hash_table_destroy(node->details->digest_cache);
211  }
212  g_list_free(node->details->running_rsc);
213  g_list_free(node->details->allocated_rsc);
214  free(node->details);
215  free(node);
216  }
217  if (nodes != NULL) {
218  g_list_free(nodes);
219  }
220 }
221 
222 static void
223 pe__free_ordering(GListPtr constraints)
224 {
225  GListPtr iterator = constraints;
226 
227  while (iterator != NULL) {
228  pe__ordering_t *order = iterator->data;
229 
230  iterator = iterator->next;
231 
232  free(order->lh_action_task);
233  free(order->rh_action_task);
234  free(order);
235  }
236  if (constraints != NULL) {
237  g_list_free(constraints);
238  }
239 }
240 
241 static void
242 pe__free_location(GListPtr constraints)
243 {
244  GListPtr iterator = constraints;
245 
246  while (iterator != NULL) {
247  pe__location_t *cons = iterator->data;
248 
249  iterator = iterator->next;
250 
251  g_list_free_full(cons->node_list_rh, free);
252  free(cons->id);
253  free(cons);
254  }
255  if (constraints != NULL) {
256  g_list_free(constraints);
257  }
258 }
259 
268 void
270 {
271  if (data_set == NULL) {
272  return;
273  }
274 
276  if (data_set->config_hash != NULL) {
277  g_hash_table_destroy(data_set->config_hash);
278  }
279 
280  if (data_set->singletons != NULL) {
281  g_hash_table_destroy(data_set->singletons);
282  }
283 
284  if (data_set->tickets) {
285  g_hash_table_destroy(data_set->tickets);
286  }
287 
288  if (data_set->template_rsc_sets) {
289  g_hash_table_destroy(data_set->template_rsc_sets);
290  }
291 
292  if (data_set->tags) {
293  g_hash_table_destroy(data_set->tags);
294  }
295 
296  free(data_set->dc_uuid);
297 
298  crm_trace("deleting resources");
299  pe_free_resources(data_set->resources);
300 
301  crm_trace("deleting actions");
302  pe_free_actions(data_set->actions);
303 
304  crm_trace("deleting nodes");
305  pe_free_nodes(data_set->nodes);
306 
307  pe__free_param_checks(data_set);
308  g_list_free(data_set->stop_needed);
309  free_xml(data_set->graph);
310  crm_time_free(data_set->now);
311  free_xml(data_set->input);
312  free_xml(data_set->failed);
313 
314  set_working_set_defaults(data_set);
315 
316  CRM_CHECK(data_set->ordering_constraints == NULL,;
317  );
318  CRM_CHECK(data_set->placement_constraints == NULL,;
319  );
320 }
321 
327 void
329 {
330  if (data_set == NULL) {
331  return;
332  }
333 
334  crm_trace("Deleting %d ordering constraints",
335  g_list_length(data_set->ordering_constraints));
336  pe__free_ordering(data_set->ordering_constraints);
337  data_set->ordering_constraints = NULL;
338 
339  crm_trace("Deleting %d location constraints",
340  g_list_length(data_set->placement_constraints));
341  pe__free_location(data_set->placement_constraints);
342  data_set->placement_constraints = NULL;
343 
344  crm_trace("Deleting %d colocation constraints",
345  g_list_length(data_set->colocation_constraints));
346  g_list_free_full(data_set->colocation_constraints, free);
347  data_set->colocation_constraints = NULL;
348 
349  crm_trace("Deleting %d ticket constraints",
350  g_list_length(data_set->ticket_constraints));
351  g_list_free_full(data_set->ticket_constraints, free);
352  data_set->ticket_constraints = NULL;
353 
354  cleanup_calculations(data_set);
355 }
356 
357 void
359 {
360  memset(data_set, 0, sizeof(pe_working_set_t));
361 
362  data_set->order_id = 1;
363  data_set->action_id = 1;
364  data_set->no_quorum_policy = no_quorum_stop;
365 
366  data_set->flags = 0x0ULL;
367 
368 #ifdef DEFAULT_CONCURRENT_FENCING_TRUE
369  pe__set_working_set_flags(data_set,
374 #else
375  pe__set_working_set_flags(data_set,
379 #endif
380 }
381 
383 pe_find_resource(GListPtr rsc_list, const char *id)
384 {
385  return pe_find_resource_with_flags(rsc_list, id, pe_find_renamed);
386 }
387 
389 pe_find_resource_with_flags(GListPtr rsc_list, const char *id, enum pe_find flags)
390 {
391  GListPtr rIter = NULL;
392 
393  for (rIter = rsc_list; id && rIter; rIter = rIter->next) {
394  pe_resource_t *parent = rIter->data;
395 
396  pe_resource_t *match =
397  parent->fns->find_rsc(parent, id, NULL, flags);
398  if (match != NULL) {
399  return match;
400  }
401  }
402  crm_trace("No match for %s", id);
403  return NULL;
404 }
405 
406 pe_node_t *
407 pe_find_node_any(GListPtr nodes, const char *id, const char *uname)
408 {
409  pe_node_t *match = pe_find_node_id(nodes, id);
410 
411  if (match) {
412  return match;
413  }
414  crm_trace("Looking up %s via its uname instead", uname);
415  return pe_find_node(nodes, uname);
416 }
417 
418 pe_node_t *
419 pe_find_node_id(GListPtr nodes, const char *id)
420 {
421  GListPtr gIter = nodes;
422 
423  for (; gIter != NULL; gIter = gIter->next) {
424  pe_node_t *node = (pe_node_t *) gIter->data;
425 
426  if (node && pcmk__str_eq(node->details->id, id, pcmk__str_casei)) {
427  return node;
428  }
429  }
430  /* error */
431  return NULL;
432 }
433 
434 pe_node_t *
435 pe_find_node(GListPtr nodes, const char *uname)
436 {
437  GListPtr gIter = nodes;
438 
439  for (; gIter != NULL; gIter = gIter->next) {
440  pe_node_t *node = (pe_node_t *) gIter->data;
441 
442  if (node && pcmk__str_eq(node->details->uname, uname, pcmk__str_casei)) {
443  return node;
444  }
445  }
446  /* error */
447  return NULL;
448 }
GHashTable * tags
Definition: pe_types.h:171
#define LOG_TRACE
Definition: logging.h:36
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:215
char uname[MAX_NAME]
Definition: internal.h:85
GListPtr nodes
Definition: pe_types.h:148
GListPtr allocated_rsc
Definition: pe_types.h:221
enum pe_quorum_policy no_quorum_policy
Definition: pe_types.h:140
A dumping ground.
xmlNode * failed
Definition: pe_types.h:156
#define pe_flag_stop_action_orphans
Definition: pe_types.h:103
bool pe__is_guest_or_remote_node(const pe_node_t *node)
Definition: remote.c:41
GHashTable * attrs
Definition: pe_types.h:223
void set_working_set_defaults(pe_working_set_t *data_set)
Definition: status.c:358
G_GNUC_INTERNAL gboolean unpack_remote_nodes(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:637
#define pe_flag_concurrent_fencing
Definition: pe_types.h:100
#define pe_flag_symmetric_cluster
Definition: pe_types.h:94
xmlNode * op_defaults
Definition: pe_types.h:157
resource_object_functions_t * fns
Definition: pe_types.h:319
pe_node_t * pe_find_node_id(GListPtr nodes, const char *id)
Definition: status.c:419
G_GNUC_INTERNAL gboolean unpack_status(xmlNode *status, pe_working_set_t *data_set)
Definition: unpack.c:1129
GListPtr resources
Definition: pe_types.h:149
#define XML_ATTR_DC_UUID
Definition: msg_xml.h:102
#define pe_flag_no_counts
Don't count total, disabled and blocked resource instances.
Definition: pe_types.h:120
#define pe_flag_have_status
Definition: pe_types.h:112
int order_id
Deprecated (will be removed in a future release)
Definition: pe_types.h:163
void cleanup_calculations(pe_working_set_t *data_set)
Reset working set to default state without freeing it or constraints.
Definition: status.c:269
pe_node_t * pe_find_node_any(GListPtr nodes, const char *id, const char *uname)
Definition: status.c:407
GHashTable * tickets
Definition: pe_types.h:143
#define XML_CIB_TAG_NODES
Definition: msg_xml.h:148
#define pe_flag_have_quorum
Definition: pe_types.h:93
#define LOG_NEVER
Definition: logging.h:46
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:213
char * dc_uuid
Definition: pe_types.h:132
GListPtr placement_constraints
Definition: pe_types.h:150
#define XML_CIB_TAG_RESOURCES
Definition: msg_xml.h:147
G_GNUC_INTERNAL gboolean unpack_tags(xmlNode *xml_tags, pe_working_set_t *data_set)
Definition: unpack.c:837
#define crm_warn(fmt, args...)
Definition: logging.h:348
pe_find
Determine behavior of pe_find_resource_with_flags()
Definition: pe_types.h:82
G_GNUC_INTERNAL gboolean unpack_nodes(xmlNode *xml_nodes, pe_working_set_t *data_set)
Definition: unpack.c:538
char * crm_element_value_copy(const xmlNode *data, const char *name)
Retrieve a copy of the value of an XML attribute.
Definition: nvpair.c:726
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:523
xmlNode * rsc_defaults
Definition: pe_types.h:158
#define crm_trace(fmt, args...)
Definition: logging.h:353
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:196
struct pe_node_shared_s * details
Definition: pe_types.h:233
G_GNUC_INTERNAL gboolean unpack_resources(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:774
pe_node_t * pe_find_node(GListPtr nodes, const char *uname)
Definition: status.c:435
#define XML_ATTR_HAVE_QUORUM
Definition: msg_xml.h:85
pe_resource_t * pe_find_resource(GListPtr rsc_list, const char *id)
Definition: status.c:383
const char * uname
Definition: pe_types.h:198
GListPtr actions
Definition: pe_types.h:155
Wrappers for and extensions to libxml2.
GHashTable * config_hash
Definition: pe_types.h:142
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:663
void(* free)(pe_resource_t *)
Definition: pe_types.h:54
void free_xml(xmlNode *child)
Definition: xml.c:790
xmlNode * input
Definition: pe_types.h:128
void pe__free_param_checks(pe_working_set_t *data_set)
Definition: remote.c:261
const char * id
Definition: pe_types.h:197
GListPtr ordering_constraints
Definition: pe_types.h:151
GListPtr colocation_constraints
Definition: pe_types.h:152
match resource ID or LRM history ID
Definition: pe_types.h:83
GListPtr running_rsc
Definition: pe_types.h:220
pe_resource_t * pe_find_resource_with_flags(GListPtr rsc_list, const char *id, enum pe_find flags)
Definition: status.c:389
#define pe_flag_quick_location
Definition: pe_types.h:115
void pe_free_working_set(pe_working_set_t *data_set)
Free a working set.
Definition: status.c:50
gboolean cluster_status(pe_working_set_t *data_set)
Definition: status.c:70
GListPtr ticket_constraints
Definition: pe_types.h:153
crm_time_t * crm_time_new(const char *string)
Definition: iso8601.c:93
#define XML_CIB_TAG_CRMCONFIG
Definition: msg_xml.h:151
#define XML_CIB_TAG_RSCCONFIG
Definition: msg_xml.h:153
GHashTable * utilization
Definition: pe_types.h:224
#define pe__set_working_set_flags(working_set, flags_to_set)
Definition: internal.h:35
GHashTable * digest_cache
cache of calculated resource digests
Definition: pe_types.h:225
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:146
#define XML_CIB_TAG_TAGS
Definition: msg_xml.h:398
gboolean crm_is_true(const char *s)
Definition: strings.c:392
GHashTable * singletons
Definition: pe_types.h:146
unsigned long long flags
Definition: pe_types.h:137
G_GNUC_INTERNAL gboolean unpack_config(xmlNode *config, pe_working_set_t *data_set)
Definition: unpack.c:198
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 XML_CIB_TAG_OPCONFIG
Definition: msg_xml.h:152
#define pe__clear_working_set_flags(working_set, flags_to_clear)
Definition: internal.h:41
GList * GListPtr
Definition: crm.h:214
crm_time_t * now
Definition: pe_types.h:129
GHashTable * template_rsc_sets
Definition: pe_types.h:169
uint64_t flags
Definition: remote.c:149
pe_working_set_t * pe_new_working_set()
Create a new working set.
Definition: status.c:34
GList * stop_needed
Definition: pe_types.h:177
void pe_reset_working_set(pe_working_set_t *data_set)
Reset a working set to default state without freeing it.
Definition: status.c:328
void pe_free_action(pe_action_t *action)
Definition: utils.c:1419
xmlNode * graph
Definition: pe_types.h:167
void crm_time_free(crm_time_t *dt)
Definition: iso8601.c:141
#define pe_flag_stop_rsc_orphans
Definition: pe_types.h:102