pacemaker  2.0.3-4b1f869f0f
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  if (is_not_set(data_set->flags, pe_flag_no_counts)) {
125  for (GList *item = data_set->resources; item != NULL;
126  item = item->next) {
127  ((pe_resource_t *) (item->data))->fns->count(item->data);
128  }
129  }
130 
131  set_bit(data_set->flags, pe_flag_have_status);
132  return TRUE;
133 }
134 
146 static void
147 pe_free_resources(GListPtr resources)
148 {
149  resource_t *rsc = NULL;
150  GListPtr iterator = resources;
151 
152  while (iterator != NULL) {
153  rsc = (resource_t *) iterator->data;
154  iterator = iterator->next;
155  rsc->fns->free(rsc);
156  }
157  if (resources != NULL) {
158  g_list_free(resources);
159  }
160 }
161 
162 static void
163 pe_free_actions(GListPtr actions)
164 {
165  GListPtr iterator = actions;
166 
167  while (iterator != NULL) {
168  pe_free_action(iterator->data);
169  iterator = iterator->next;
170  }
171  if (actions != NULL) {
172  g_list_free(actions);
173  }
174 }
175 
176 static void
177 pe_free_nodes(GListPtr nodes)
178 {
179  for (GList *iterator = nodes; iterator != NULL; iterator = iterator->next) {
180  pe_node_t *node = (pe_node_t *) iterator->data;
181 
182  // Shouldn't be possible, but to be safe ...
183  if (node == NULL) {
184  continue;
185  }
186  if (node->details == NULL) {
187  free(node);
188  continue;
189  }
190 
191  /* This is called after pe_free_resources(), which means that we can't
192  * use node->details->uname for Pacemaker Remote nodes.
193  */
194  crm_trace("Freeing node %s", (pe__is_guest_or_remote_node(node)?
195  "(guest or remote)" : node->details->uname));
196 
197  if (node->details->attrs != NULL) {
198  g_hash_table_destroy(node->details->attrs);
199  }
200  if (node->details->utilization != NULL) {
201  g_hash_table_destroy(node->details->utilization);
202  }
203  if (node->details->digest_cache != NULL) {
204  g_hash_table_destroy(node->details->digest_cache);
205  }
206  g_list_free(node->details->running_rsc);
207  g_list_free(node->details->allocated_rsc);
208  free(node->details);
209  free(node);
210  }
211  if (nodes != NULL) {
212  g_list_free(nodes);
213  }
214 }
215 
216 static void
217 pe__free_ordering(GListPtr constraints)
218 {
219  GListPtr iterator = constraints;
220 
221  while (iterator != NULL) {
222  pe__ordering_t *order = iterator->data;
223 
224  iterator = iterator->next;
225 
226  free(order->lh_action_task);
227  free(order->rh_action_task);
228  free(order);
229  }
230  if (constraints != NULL) {
231  g_list_free(constraints);
232  }
233 }
234 
235 static void
236 pe__free_location(GListPtr constraints)
237 {
238  GListPtr iterator = constraints;
239 
240  while (iterator != NULL) {
241  pe__location_t *cons = iterator->data;
242 
243  iterator = iterator->next;
244 
245  g_list_free_full(cons->node_list_rh, free);
246  free(cons->id);
247  free(cons);
248  }
249  if (constraints != NULL) {
250  g_list_free(constraints);
251  }
252 }
253 
262 void
264 {
265  if (data_set == NULL) {
266  return;
267  }
268 
269  clear_bit(data_set->flags, pe_flag_have_status);
270  if (data_set->config_hash != NULL) {
271  g_hash_table_destroy(data_set->config_hash);
272  }
273 
274  if (data_set->singletons != NULL) {
275  g_hash_table_destroy(data_set->singletons);
276  }
277 
278  if (data_set->tickets) {
279  g_hash_table_destroy(data_set->tickets);
280  }
281 
282  if (data_set->template_rsc_sets) {
283  g_hash_table_destroy(data_set->template_rsc_sets);
284  }
285 
286  if (data_set->tags) {
287  g_hash_table_destroy(data_set->tags);
288  }
289 
290  free(data_set->dc_uuid);
291 
292  crm_trace("deleting resources");
293  pe_free_resources(data_set->resources);
294 
295  crm_trace("deleting actions");
296  pe_free_actions(data_set->actions);
297 
298  crm_trace("deleting nodes");
299  pe_free_nodes(data_set->nodes);
300 
301  pe__free_param_checks(data_set);
302  g_list_free(data_set->stop_needed);
303  free_xml(data_set->graph);
304  crm_time_free(data_set->now);
305  free_xml(data_set->input);
306  free_xml(data_set->failed);
307 
308  set_working_set_defaults(data_set);
309 
310  CRM_CHECK(data_set->ordering_constraints == NULL,;
311  );
312  CRM_CHECK(data_set->placement_constraints == NULL,;
313  );
314 }
315 
321 void
323 {
324  if (data_set == NULL) {
325  return;
326  }
327 
328  crm_trace("Deleting %d ordering constraints",
329  g_list_length(data_set->ordering_constraints));
330  pe__free_ordering(data_set->ordering_constraints);
331  data_set->ordering_constraints = NULL;
332 
333  crm_trace("Deleting %d location constraints",
334  g_list_length(data_set->placement_constraints));
335  pe__free_location(data_set->placement_constraints);
336  data_set->placement_constraints = NULL;
337 
338  crm_trace("Deleting %d colocation constraints",
339  g_list_length(data_set->colocation_constraints));
340  g_list_free_full(data_set->colocation_constraints, free);
341  data_set->colocation_constraints = NULL;
342 
343  crm_trace("Deleting %d ticket constraints",
344  g_list_length(data_set->ticket_constraints));
345  g_list_free_full(data_set->ticket_constraints, free);
346  data_set->ticket_constraints = NULL;
347 
348  cleanup_calculations(data_set);
349 }
350 
351 void
353 {
354  memset(data_set, 0, sizeof(pe_working_set_t));
355 
356  data_set->order_id = 1;
357  data_set->action_id = 1;
359 
360  data_set->flags = 0x0ULL;
364 #ifdef DEFAULT_CONCURRENT_FENCING_TRUE
366 #endif
367 }
368 
369 resource_t *
370 pe_find_resource(GListPtr rsc_list, const char *id)
371 {
372  return pe_find_resource_with_flags(rsc_list, id, pe_find_renamed);
373 }
374 
375 resource_t *
376 pe_find_resource_with_flags(GListPtr rsc_list, const char *id, enum pe_find flags)
377 {
378  GListPtr rIter = NULL;
379 
380  for (rIter = rsc_list; id && rIter; rIter = rIter->next) {
381  resource_t *parent = rIter->data;
382 
383  resource_t *match =
384  parent->fns->find_rsc(parent, id, NULL, flags);
385  if (match != NULL) {
386  return match;
387  }
388  }
389  crm_trace("No match for %s", id);
390  return NULL;
391 }
392 
393 node_t *
394 pe_find_node_any(GListPtr nodes, const char *id, const char *uname)
395 {
396  node_t *match = pe_find_node_id(nodes, id);
397 
398  if (match) {
399  return match;
400  }
401  crm_trace("Looking up %s via its uname instead", uname);
402  return pe_find_node(nodes, uname);
403 }
404 
405 node_t *
406 pe_find_node_id(GListPtr nodes, const char *id)
407 {
408  GListPtr gIter = nodes;
409 
410  for (; gIter != NULL; gIter = gIter->next) {
411  node_t *node = (node_t *) gIter->data;
412 
413  if (node && safe_str_eq(node->details->id, id)) {
414  return node;
415  }
416  }
417  /* error */
418  return NULL;
419 }
420 
421 node_t *
422 pe_find_node(GListPtr nodes, const char *uname)
423 {
424  GListPtr gIter = nodes;
425 
426  for (; gIter != NULL; gIter = gIter->next) {
427  node_t *node = (node_t *) gIter->data;
428 
429  if (node && safe_str_eq(node->details->uname, uname)) {
430  return node;
431  }
432  }
433  /* error */
434  return NULL;
435 }
GListPtr
GList * GListPtr
Definition: crm.h:214
pe_working_set_s::input
xmlNode * input
Definition: pe_types.h:118
pe_working_set_s::now
crm_time_t * now
Definition: pe_types.h:119
pe_find_node_any
node_t * pe_find_node_any(GListPtr nodes, const char *id, const char *uname)
Definition: status.c:394
pe_working_set_s::resources
GListPtr resources
Definition: pe_types.h:139
no_quorum_freeze
Definition: pe_types.h:61
flags
uint64_t flags
Definition: remote.c:148
pe_working_set_s::nodes
GListPtr nodes
Definition: pe_types.h:138
msg_xml.h
pe_working_set_s::rsc_defaults
xmlNode * rsc_defaults
Definition: pe_types.h:148
XML_CIB_TAG_TAGS
#define XML_CIB_TAG_TAGS
Definition: msg_xml.h:388
LOG_TRACE
#define LOG_TRACE
Definition: logging.h:26
create_xml_node
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:1970
unpack_tags
gboolean unpack_tags(xmlNode *xml_tags, pe_working_set_t *data_set)
Definition: unpack.c:802
pe_node_shared_s::running_rsc
GListPtr running_rsc
Definition: pe_types.h:208
pe__location_constraint_s::id
char * id
Definition: internal.h:29
get_xpath_object
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:220
XML_CIB_TAG_OPCONFIG
#define XML_CIB_TAG_OPCONFIG
Definition: msg_xml.h:145
CRM_CHECK
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:157
pe_flag_have_status
#define pe_flag_have_status
Definition: pe_types.h:107
clear_bit
#define clear_bit(word, bit)
Definition: crm_internal.h:168
pe_node_shared_s::digest_cache
GHashTable * digest_cache
cache of calculated resource digests
Definition: pe_types.h:213
pe_node_s::details
struct pe_node_shared_s * details
Definition: pe_types.h:220
pe_node_shared_s::id
const char * id
Definition: pe_types.h:185
internal.h
pe_working_set_s::action_id
int action_id
Definition: pe_types.h:154
pe_free_working_set
void pe_free_working_set(pe_working_set_t *data_set)
Free a working set.
Definition: status.c:48
pe_find_node_id
node_t * pe_find_node_id(GListPtr nodes, const char *id)
Definition: status.c:406
pe_working_set_s::stop_needed
GList * stop_needed
Definition: pe_types.h:167
pe_flag_stop_action_orphans
#define pe_flag_stop_action_orphans
Definition: pe_types.h:99
crm_trace
#define crm_trace(fmt, args...)
Definition: logging.h:247
pe_working_set_s::dc_uuid
char * dc_uuid
Definition: pe_types.h:122
unpack_remote_nodes
gboolean unpack_remote_nodes(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:603
safe_str_eq
#define safe_str_eq(a, b)
Definition: util.h:61
XML_CIB_TAG_RESOURCES
#define XML_CIB_TAG_RESOURCES
Definition: msg_xml.h:140
pe__is_guest_or_remote_node
gboolean pe__is_guest_or_remote_node(pe_node_t *node)
Definition: remote.c:58
crm_warn
#define crm_warn(fmt, args...)
Definition: logging.h:242
pe_working_set_s::order_id
int order_id
Definition: pe_types.h:153
free_xml
void free_xml(xmlNode *child)
Definition: xml.c:2130
pe_node_shared_s::utilization
GHashTable * utilization
Definition: pe_types.h:212
XML_CIB_TAG_RSCCONFIG
#define XML_CIB_TAG_RSCCONFIG
Definition: msg_xml.h:146
pe_flag_quick_location
#define pe_flag_quick_location
Definition: pe_types.h:110
xml.h
Wrappers for and extensions to libxml2.
pe_find_node
node_t * pe_find_node(GListPtr nodes, const char *uname)
Definition: status.c:422
pe_find_resource
resource_t * pe_find_resource(GListPtr rsc_list, const char *id)
Definition: status.c:370
crm_is_true
gboolean crm_is_true(const char *s)
Definition: strings.c:176
XML_CIB_TAG_STATUS
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:139
set_bit
#define set_bit(word, bit)
Definition: crm_internal.h:167
resource_object_functions_s::free
void(* free)(pe_resource_t *)
Definition: pe_types.h:54
pe_working_set_s::tags
GHashTable * tags
Definition: pe_types.h:161
XML_CIB_TAG_NODES
#define XML_CIB_TAG_NODES
Definition: msg_xml.h:141
pe_node_shared_s::allocated_rsc
GListPtr allocated_rsc
Definition: pe_types.h:209
pe__order_constraint_s::rh_action_task
char * rh_action_task
Definition: internal.h:48
cluster_status
gboolean cluster_status(pe_working_set_t *data_set)
Definition: status.c:68
set_working_set_defaults
void set_working_set_defaults(pe_working_set_t *data_set)
Definition: status.c:352
uname
char uname[MAX_NAME]
Definition: internal.h:85
pe_working_set_s::colocation_constraints
GListPtr colocation_constraints
Definition: pe_types.h:142
pe_working_set_s::config_hash
GHashTable * config_hash
Definition: pe_types.h:132
XML_ATTR_DC_UUID
#define XML_ATTR_DC_UUID
Definition: msg_xml.h:102
pe__order_constraint_s::lh_action_task
char * lh_action_task
Definition: internal.h:43
pe_working_set_s::ordering_constraints
GListPtr ordering_constraints
Definition: pe_types.h:141
pe_working_set_s
Definition: pe_types.h:117
crm_element_value
const char * crm_element_value(const xmlNode *data, const char *name)
Retrieve the value of an XML attribute.
Definition: nvpair.c:519
no_quorum_ignore
Definition: pe_types.h:63
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:322
pe_working_set_s::template_rsc_sets
GHashTable * template_rsc_sets
Definition: pe_types.h:159
pe_new_working_set
pe_working_set_t * pe_new_working_set()
Create a new working set.
Definition: status.c:32
pe_working_set_s::placement_constraints
GListPtr placement_constraints
Definition: pe_types.h:140
pe_find_renamed
match resource ID or LRM history ID
Definition: pe_types.h:81
pe__location_constraint_s::node_list_rh
GListPtr node_list_rh
Definition: internal.h:33
XML_CIB_TAG_CRMCONFIG
#define XML_CIB_TAG_CRMCONFIG
Definition: msg_xml.h:144
pe_working_set_s::actions
GListPtr actions
Definition: pe_types.h:145
pe_flag_concurrent_fencing
#define pe_flag_concurrent_fencing
Definition: pe_types.h:96
pe__free_param_checks
void pe__free_param_checks(pe_working_set_t *data_set)
Definition: remote.c:256
unpack_nodes
gboolean unpack_nodes(xmlNode *xml_nodes, pe_working_set_t *data_set)
Definition: unpack.c:514
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:709
pe_working_set_s::graph
xmlNode * graph
Definition: pe_types.h:157
pe_working_set_s::singletons
GHashTable * singletons
Definition: pe_types.h:136
pe_working_set_s::ticket_constraints
GListPtr ticket_constraints
Definition: pe_types.h:143
pe_working_set_s::tickets
GHashTable * tickets
Definition: pe_types.h:133
pe_find
pe_find
Determine behavior of pe_find_resource_with_flags()
Definition: pe_types.h:80
pe_find_resource_with_flags
resource_t * pe_find_resource_with_flags(GListPtr rsc_list, const char *id, enum pe_find flags)
Definition: status.c:376
crm_time_new
crm_time_t * crm_time_new(const char *string)
Definition: iso8601.c:96
unpack.h
unpack_resources
gboolean unpack_resources(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:740
crm_time_free
void crm_time_free(crm_time_t *dt)
Definition: iso8601.c:144
pe_resource_s
Definition: pe_types.h:291
pe_working_set_s::op_defaults
xmlNode * op_defaults
Definition: pe_types.h:147
pe_working_set_s::flags
unsigned long long flags
Definition: pe_types.h:127
pe__location_constraint_s
Definition: internal.h:28
unpack_config
gboolean unpack_config(xmlNode *config, pe_working_set_t *data_set)
Definition: unpack.c:177
pe_working_set_s::failed
xmlNode * failed
Definition: pe_types.h:146
pe_working_set_s::no_quorum_policy
enum pe_quorum_policy no_quorum_policy
Definition: pe_types.h:130
pe_flag_symmetric_cluster
#define pe_flag_symmetric_cluster
Definition: pe_types.h:90
pe__order_constraint_s
Definition: internal.h:36
pe_flag_no_counts
#define pe_flag_no_counts
Don't count total, disabled and blocked resource instances.
Definition: pe_types.h:115
pe_node_shared_s::uname
const char * uname
Definition: pe_types.h:186
pe_free_action
void pe_free_action(action_t *action)
Definition: utils.c:1314
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:98
crm_internal.h
pe_node_s
Definition: pe_types.h:216
pe_flag_have_quorum
#define pe_flag_have_quorum
Definition: pe_types.h:89
crm.h
A dumping ground.
pe_resource_s::fns
resource_object_functions_t * fns
Definition: pe_types.h:303
unpack_status
gboolean unpack_status(xmlNode *status, pe_working_set_t *data_set)
Definition: unpack.c:1090
pe_node_shared_s::attrs
GHashTable * attrs
Definition: pe_types.h:211
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:263
XML_ATTR_HAVE_QUORUM
#define XML_ATTR_HAVE_QUORUM
Definition: msg_xml.h:85