pacemaker  2.0.5-ba59be7122
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 }
pcmk__str_casei
@ pcmk__str_casei
Definition: strings_internal.h:26
GListPtr
GList * GListPtr
Definition: crm.h:214
pe_working_set_s::input
xmlNode * input
Definition: pe_types.h:128
pe_working_set_s::now
crm_time_t * now
Definition: pe_types.h:129
pe_working_set_s::resources
GListPtr resources
Definition: pe_types.h:149
flags
uint64_t flags
Definition: remote.c:3
pe_working_set_s::nodes
GListPtr nodes
Definition: pe_types.h:148
msg_xml.h
pe_free_action
void pe_free_action(pe_action_t *action)
Definition: utils.c:1419
pe_working_set_s::rsc_defaults
xmlNode * rsc_defaults
Definition: pe_types.h:158
XML_CIB_TAG_TAGS
#define XML_CIB_TAG_TAGS
Definition: msg_xml.h:398
LOG_TRACE
#define LOG_TRACE
Definition: logging.h:36
pcmk_is_set
#define pcmk_is_set(g, f)
Convenience alias for pcmk_all_flags_set(), to check single flag.
Definition: util.h:196
unpack_status
G_GNUC_INTERNAL gboolean unpack_status(xmlNode *status, pe_working_set_t *data_set)
Definition: unpack.c:1129
create_xml_node
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:663
pe_find_resource
pe_resource_t * pe_find_resource(GListPtr rsc_list, const char *id)
Definition: status.c:383
pe_node_shared_s::running_rsc
GListPtr running_rsc
Definition: pe_types.h:220
pe__location_constraint_s::id
char * id
Definition: internal.h:168
get_xpath_object
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:213
XML_CIB_TAG_OPCONFIG
#define XML_CIB_TAG_OPCONFIG
Definition: msg_xml.h:152
CRM_CHECK
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:215
pe_flag_have_status
#define pe_flag_have_status
Definition: pe_types.h:112
pe_node_shared_s::digest_cache
GHashTable * digest_cache
cache of calculated resource digests
Definition: pe_types.h:225
pe_node_s::details
struct pe_node_shared_s * details
Definition: pe_types.h:233
pe_node_shared_s::id
const char * id
Definition: pe_types.h:197
internal.h
pe_working_set_s::action_id
int action_id
Definition: pe_types.h:164
pe_free_working_set
void pe_free_working_set(pe_working_set_t *data_set)
Free a working set.
Definition: status.c:50
pe_working_set_s::stop_needed
GList * stop_needed
Definition: pe_types.h:177
unpack_remote_nodes
G_GNUC_INTERNAL gboolean unpack_remote_nodes(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:637
pe_flag_stop_action_orphans
#define pe_flag_stop_action_orphans
Definition: pe_types.h:103
crm_trace
#define crm_trace(fmt, args...)
Definition: logging.h:353
pe_working_set_s::dc_uuid
char * dc_uuid
Definition: pe_types.h:132
XML_CIB_TAG_RESOURCES
#define XML_CIB_TAG_RESOURCES
Definition: msg_xml.h:147
crm_warn
#define crm_warn(fmt, args...)
Definition: logging.h:348
pe_working_set_s::order_id
int order_id
Deprecated (will be removed in a future release)
Definition: pe_types.h:163
free_xml
void free_xml(xmlNode *child)
Definition: xml.c:790
pe_node_shared_s::utilization
GHashTable * utilization
Definition: pe_types.h:224
XML_CIB_TAG_RSCCONFIG
#define XML_CIB_TAG_RSCCONFIG
Definition: msg_xml.h:153
pe_flag_quick_location
#define pe_flag_quick_location
Definition: pe_types.h:115
xml.h
Wrappers for and extensions to libxml2.
unpack_tags
G_GNUC_INTERNAL gboolean unpack_tags(xmlNode *xml_tags, pe_working_set_t *data_set)
Definition: unpack.c:837
crm_is_true
gboolean crm_is_true(const char *s)
Definition: strings.c:392
XML_CIB_TAG_STATUS
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:146
pe__is_guest_or_remote_node
bool pe__is_guest_or_remote_node(const pe_node_t *node)
Definition: remote.c:41
resource_object_functions_s::free
void(* free)(pe_resource_t *)
Definition: pe_types.h:54
pe_find_node
pe_node_t * pe_find_node(GListPtr nodes, const char *uname)
Definition: status.c:435
pe_find_node_id
pe_node_t * pe_find_node_id(GListPtr nodes, const char *id)
Definition: status.c:419
pe_working_set_s::tags
GHashTable * tags
Definition: pe_types.h:171
XML_CIB_TAG_NODES
#define XML_CIB_TAG_NODES
Definition: msg_xml.h:148
pe_node_shared_s::allocated_rsc
GListPtr allocated_rsc
Definition: pe_types.h:221
pe__order_constraint_s::rh_action_task
char * rh_action_task
Definition: internal.h:187
pe__clear_working_set_flags
#define pe__clear_working_set_flags(working_set, flags_to_clear)
Definition: internal.h:41
cluster_status
gboolean cluster_status(pe_working_set_t *data_set)
Definition: status.c:70
set_working_set_defaults
void set_working_set_defaults(pe_working_set_t *data_set)
Definition: status.c:358
uname
char uname[MAX_NAME]
Definition: internal.h:5
pe_working_set_s::colocation_constraints
GListPtr colocation_constraints
Definition: pe_types.h:152
pe_working_set_s::config_hash
GHashTable * config_hash
Definition: pe_types.h:142
XML_ATTR_DC_UUID
#define XML_ATTR_DC_UUID
Definition: msg_xml.h:102
unpack_resources
G_GNUC_INTERNAL gboolean unpack_resources(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:774
pe__order_constraint_s::lh_action_task
char * lh_action_task
Definition: internal.h:182
pe_working_set_s::ordering_constraints
GListPtr ordering_constraints
Definition: pe_types.h:151
pe_working_set_s
Definition: pe_types.h:127
unpack_nodes
G_GNUC_INTERNAL gboolean unpack_nodes(xmlNode *xml_nodes, pe_working_set_t *data_set)
Definition: unpack.c:538
crm_element_value
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:523
no_quorum_ignore
@ no_quorum_ignore
Definition: pe_types.h:64
pe_status_private.h
pe_reset_working_set
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
pe_working_set_s::template_rsc_sets
GHashTable * template_rsc_sets
Definition: pe_types.h:169
pe_new_working_set
pe_working_set_t * pe_new_working_set()
Create a new working set.
Definition: status.c:34
pe_working_set_s::placement_constraints
GListPtr placement_constraints
Definition: pe_types.h:150
pe_find_renamed
@ pe_find_renamed
match resource ID or LRM history ID
Definition: pe_types.h:83
pe__location_constraint_s::node_list_rh
GListPtr node_list_rh
Definition: internal.h:172
XML_CIB_TAG_CRMCONFIG
#define XML_CIB_TAG_CRMCONFIG
Definition: msg_xml.h:151
pe_working_set_s::actions
GListPtr actions
Definition: pe_types.h:155
pe_flag_concurrent_fencing
#define pe_flag_concurrent_fencing
Definition: pe_types.h:100
pe__free_param_checks
void pe__free_param_checks(pe_working_set_t *data_set)
Definition: remote.c:261
LOG_NEVER
#define LOG_NEVER
Definition: logging.h:46
crm_element_value_copy
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
pe_working_set_s::graph
xmlNode * graph
Definition: pe_types.h:167
pe_working_set_s::singletons
GHashTable * singletons
Definition: pe_types.h:146
pe_working_set_s::ticket_constraints
GListPtr ticket_constraints
Definition: pe_types.h:153
pe_working_set_s::tickets
GHashTable * tickets
Definition: pe_types.h:143
pe_find
pe_find
Determine behavior of pe_find_resource_with_flags()
Definition: pe_types.h:82
crm_time_new
crm_time_t * crm_time_new(const char *string)
Definition: iso8601.c:93
crm_time_free
void crm_time_free(crm_time_t *dt)
Definition: iso8601.c:141
pe_find_resource_with_flags
pe_resource_t * pe_find_resource_with_flags(GListPtr rsc_list, const char *id, enum pe_find flags)
Definition: status.c:389
pe_resource_s
Definition: pe_types.h:307
pe_working_set_s::op_defaults
xmlNode * op_defaults
Definition: pe_types.h:157
pe_working_set_s::flags
unsigned long long flags
Definition: pe_types.h:137
pe__location_constraint_s
Definition: internal.h:167
pe_working_set_s::failed
xmlNode * failed
Definition: pe_types.h:156
pe_working_set_s::no_quorum_policy
enum pe_quorum_policy no_quorum_policy
Definition: pe_types.h:140
pe_flag_symmetric_cluster
#define pe_flag_symmetric_cluster
Definition: pe_types.h:94
pe__order_constraint_s
Definition: internal.h:175
pe_flag_no_counts
#define pe_flag_no_counts
Don't count total, disabled and blocked resource instances.
Definition: pe_types.h:120
pe_node_shared_s::uname
const char * uname
Definition: pe_types.h:198
no_quorum_stop
@ no_quorum_stop
Definition: pe_types.h:63
pe_find_node_any
pe_node_t * pe_find_node_any(GListPtr nodes, const char *id, const char *uname)
Definition: status.c:407
resource_object_functions_s::find_rsc
pe_resource_t *(* find_rsc)(pe_resource_t *parent, const char *search, const pe_node_t *node, int flags)
Definition: pe_types.h:45
pe_flag_stop_rsc_orphans
#define pe_flag_stop_rsc_orphans
Definition: pe_types.h:102
pe__set_working_set_flags
#define pe__set_working_set_flags(working_set, flags_to_set)
Definition: internal.h:35
crm_internal.h
pe_node_s
Definition: pe_types.h:229
pe_flag_have_quorum
#define pe_flag_have_quorum
Definition: pe_types.h:93
unpack_config
G_GNUC_INTERNAL gboolean unpack_config(xmlNode *config, pe_working_set_t *data_set)
Definition: unpack.c:198
crm.h
A dumping ground.
pe_resource_s::fns
resource_object_functions_t * fns
Definition: pe_types.h:319
pe_node_shared_s::attrs
GHashTable * attrs
Definition: pe_types.h:223
cleanup_calculations
void cleanup_calculations(pe_working_set_t *data_set)
Reset working set to default state without freeing it or constraints.
Definition: status.c:269
XML_ATTR_HAVE_QUORUM
#define XML_ATTR_HAVE_QUORUM
Definition: msg_xml.h:85