pacemaker  2.0.3-4b1f869f0f
Scalable High-Availability cluster resource manager
unpack.c
Go to the documentation of this file.
1 /*
2  * Copyright 2004-2019 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 <stdio.h>
13 #include <string.h>
14 #include <glib.h>
15 
16 #include <crm/crm.h>
17 #include <crm/services.h>
18 #include <crm/msg_xml.h>
19 #include <crm/common/xml.h>
20 
21 #include <crm/common/util.h>
22 #include <crm/pengine/rules.h>
23 #include <crm/pengine/internal.h>
25 #include <unpack.h>
26 #include <pe_status_private.h>
27 
28 CRM_TRACE_INIT_DATA(pe_status);
29 
30 #define set_config_flag(data_set, option, flag) do { \
31  const char *tmp = pe_pref(data_set->config_hash, option); \
32  if(tmp) { \
33  if(crm_is_true(tmp)) { \
34  set_bit(data_set->flags, flag); \
35  } else { \
36  clear_bit(data_set->flags, flag); \
37  } \
38  } \
39  } while(0)
40 
41 static void unpack_rsc_op(pe_resource_t *rsc, pe_node_t *node, xmlNode *xml_op,
42  xmlNode **last_failure,
43  enum action_fail_response *failed,
44  pe_working_set_t *data_set);
45 static gboolean determine_remote_online_status(pe_working_set_t * data_set, node_t * this_node);
46 static void add_node_attrs(xmlNode *attrs, pe_node_t *node, bool overwrite,
47  pe_working_set_t *data_set);
48 
49 
50 // Bitmask for warnings we only want to print once
51 uint32_t pe_wo = 0;
52 
53 static gboolean
54 is_dangling_guest_node(node_t *node)
55 {
56  /* we are looking for a remote-node that was supposed to be mapped to a
57  * container resource, but all traces of that container have disappeared
58  * from both the config and the status section. */
59  if (pe__is_guest_or_remote_node(node) &&
60  node->details->remote_rsc &&
61  node->details->remote_rsc->container == NULL &&
63  return TRUE;
64  }
65 
66  return FALSE;
67 }
68 
69 
77 void
78 pe_fence_node(pe_working_set_t * data_set, node_t * node, const char *reason)
79 {
80  CRM_CHECK(node, return);
81 
82  /* A guest node is fenced by marking its container as failed */
83  if (pe__is_guest_node(node)) {
84  resource_t *rsc = node->details->remote_rsc->container;
85 
86  if (is_set(rsc->flags, pe_rsc_failed) == FALSE) {
87  if (!is_set(rsc->flags, pe_rsc_managed)) {
88  crm_notice("Not fencing guest node %s "
89  "(otherwise would because %s): "
90  "its guest resource %s is unmanaged",
91  node->details->uname, reason, rsc->id);
92  } else {
93  crm_warn("Guest node %s will be fenced "
94  "(by recovering its guest resource %s): %s",
95  node->details->uname, rsc->id, reason);
96 
97  /* We don't mark the node as unclean because that would prevent the
98  * node from running resources. We want to allow it to run resources
99  * in this transition if the recovery succeeds.
100  */
101  node->details->remote_requires_reset = TRUE;
102  set_bit(rsc->flags, pe_rsc_failed);
103  }
104  }
105 
106  } else if (is_dangling_guest_node(node)) {
107  crm_info("Cleaning up dangling connection for guest node %s: "
108  "fencing was already done because %s, "
109  "and guest resource no longer exists",
110  node->details->uname, reason);
112 
113  } else if (pe__is_remote_node(node)) {
114  resource_t *rsc = node->details->remote_rsc;
115 
116  if (rsc && (!is_set(rsc->flags, pe_rsc_managed))) {
117  crm_notice("Not fencing remote node %s "
118  "(otherwise would because %s): connection is unmanaged",
119  node->details->uname, reason);
120  } else if(node->details->remote_requires_reset == FALSE) {
121  node->details->remote_requires_reset = TRUE;
122  crm_warn("Remote node %s %s: %s",
123  node->details->uname,
124  pe_can_fence(data_set, node)? "will be fenced" : "is unclean",
125  reason);
126  }
127  node->details->unclean = TRUE;
128  pe_fence_op(node, NULL, TRUE, reason, data_set);
129 
130  } else if (node->details->unclean) {
131  crm_trace("Cluster node %s %s because %s",
132  node->details->uname,
133  pe_can_fence(data_set, node)? "would also be fenced" : "also is unclean",
134  reason);
135 
136  } else {
137  crm_warn("Cluster node %s %s: %s",
138  node->details->uname,
139  pe_can_fence(data_set, node)? "will be fenced" : "is unclean",
140  reason);
141  node->details->unclean = TRUE;
142  pe_fence_op(node, NULL, TRUE, reason, data_set);
143  }
144 }
145 
146 // @TODO xpaths can't handle templates, rules, or id-refs
147 
148 // nvpair with provides or requires set to unfencing
149 #define XPATH_UNFENCING_NVPAIR XML_CIB_TAG_NVPAIR \
150  "[(@" XML_NVPAIR_ATTR_NAME "='" XML_RSC_ATTR_PROVIDES "'" \
151  "or @" XML_NVPAIR_ATTR_NAME "='" XML_RSC_ATTR_REQUIRES "') " \
152  "and @" XML_NVPAIR_ATTR_VALUE "='unfencing']"
153 
154 // unfencing in rsc_defaults or any resource
155 #define XPATH_ENABLE_UNFENCING \
156  "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RESOURCES \
157  "//" XML_TAG_META_SETS "/" XPATH_UNFENCING_NVPAIR \
158  "|/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RSCCONFIG \
159  "/" XML_TAG_META_SETS "/" XPATH_UNFENCING_NVPAIR
160 
161 static
162 void set_if_xpath(unsigned long long flag, const char *xpath,
163  pe_working_set_t *data_set)
164 {
165  xmlXPathObjectPtr result = NULL;
166 
167  if (is_not_set(data_set->flags, flag)) {
168  result = xpath_search(data_set->input, xpath);
169  if (result && (numXpathResults(result) > 0)) {
170  set_bit(data_set->flags, flag);
171  }
172  freeXpathObject(result);
173  }
174 }
175 
176 gboolean
177 unpack_config(xmlNode * config, pe_working_set_t * data_set)
178 {
179  const char *value = NULL;
180  GHashTable *config_hash = crm_str_table_new();
181 
182  data_set->config_hash = config_hash;
183 
184  pe__unpack_dataset_nvpairs(config, XML_CIB_TAG_PROPSET, NULL, config_hash,
185  CIB_OPTIONS_FIRST, FALSE, data_set);
186 
187  verify_pe_options(data_set->config_hash);
188 
189  set_config_flag(data_set, "enable-startup-probes", pe_flag_startup_probes);
190  if(is_not_set(data_set->flags, pe_flag_startup_probes)) {
191  crm_info("Startup probes: disabled (dangerous)");
192  }
193 
194  value = pe_pref(data_set->config_hash, XML_ATTR_HAVE_WATCHDOG);
195  if (value && crm_is_true(value)) {
196  crm_notice("Watchdog will be used via SBD if fencing is required "
197  "and stonith-watchdog-timeout is nonzero");
199  }
200 
201  /* Set certain flags via xpath here, so they can be used before the relevant
202  * configuration sections are unpacked.
203  */
204  set_if_xpath(pe_flag_enable_unfencing, XPATH_ENABLE_UNFENCING, data_set);
205 
206  value = pe_pref(data_set->config_hash, "stonith-timeout");
207  data_set->stonith_timeout = (int) crm_parse_interval_spec(value);
208  crm_debug("STONITH timeout: %d", data_set->stonith_timeout);
209 
210  set_config_flag(data_set, "stonith-enabled", pe_flag_stonith_enabled);
211  crm_debug("STONITH of failed nodes is %s",
212  is_set(data_set->flags, pe_flag_stonith_enabled) ? "enabled" : "disabled");
213 
214  data_set->stonith_action = pe_pref(data_set->config_hash, "stonith-action");
215  if (!strcmp(data_set->stonith_action, "poweroff")) {
217  "Support for stonith-action of 'poweroff' is deprecated "
218  "and will be removed in a future release (use 'off' instead)");
219  data_set->stonith_action = "off";
220  }
221  crm_trace("STONITH will %s nodes", data_set->stonith_action);
222 
223  set_config_flag(data_set, "concurrent-fencing", pe_flag_concurrent_fencing);
224  crm_debug("Concurrent fencing is %s",
225  is_set(data_set->flags, pe_flag_concurrent_fencing) ? "enabled" : "disabled");
226 
227  set_config_flag(data_set, "stop-all-resources", pe_flag_stop_everything);
228  crm_debug("Stop all active resources: %s",
229  is_set(data_set->flags, pe_flag_stop_everything) ? "true" : "false");
230 
231  set_config_flag(data_set, "symmetric-cluster", pe_flag_symmetric_cluster);
232  if (is_set(data_set->flags, pe_flag_symmetric_cluster)) {
233  crm_debug("Cluster is symmetric" " - resources can run anywhere by default");
234  }
235 
236  value = pe_pref(data_set->config_hash, "no-quorum-policy");
237 
238  if (safe_str_eq(value, "ignore")) {
240 
241  } else if (safe_str_eq(value, "freeze")) {
243 
244  } else if (safe_str_eq(value, "suicide")) {
245  if (is_set(data_set->flags, pe_flag_stonith_enabled)) {
246  int do_panic = 0;
247 
249  &do_panic);
250  if (do_panic || is_set(data_set->flags, pe_flag_have_quorum)) {
252  } else {
253  crm_notice("Resetting no-quorum-policy to 'stop': cluster has never had quorum");
254  data_set->no_quorum_policy = no_quorum_stop;
255  }
256  } else {
257  crm_config_err("Resetting no-quorum-policy to 'stop': stonith is not configured");
258  data_set->no_quorum_policy = no_quorum_stop;
259  }
260 
261  } else {
262  data_set->no_quorum_policy = no_quorum_stop;
263  }
264 
265  switch (data_set->no_quorum_policy) {
266  case no_quorum_freeze:
267  crm_debug("On loss of quorum: Freeze resources");
268  break;
269  case no_quorum_stop:
270  crm_debug("On loss of quorum: Stop ALL resources");
271  break;
272  case no_quorum_suicide:
273  crm_notice("On loss of quorum: Fence all remaining nodes");
274  break;
275  case no_quorum_ignore:
276  crm_notice("On loss of quorum: Ignore");
277  break;
278  }
279 
280  set_config_flag(data_set, "stop-orphan-resources", pe_flag_stop_rsc_orphans);
281  crm_trace("Orphan resources are %s",
282  is_set(data_set->flags, pe_flag_stop_rsc_orphans) ? "stopped" : "ignored");
283 
284  set_config_flag(data_set, "stop-orphan-actions", pe_flag_stop_action_orphans);
285  crm_trace("Orphan resource actions are %s",
286  is_set(data_set->flags, pe_flag_stop_action_orphans) ? "stopped" : "ignored");
287 
288  set_config_flag(data_set, "remove-after-stop", pe_flag_remove_after_stop);
289  crm_trace("Stopped resources are removed from the status section: %s",
290  is_set(data_set->flags, pe_flag_remove_after_stop) ? "true" : "false");
291 
292  set_config_flag(data_set, "maintenance-mode", pe_flag_maintenance_mode);
293  crm_trace("Maintenance mode: %s",
294  is_set(data_set->flags, pe_flag_maintenance_mode) ? "true" : "false");
295 
296  set_config_flag(data_set, "start-failure-is-fatal", pe_flag_start_failure_fatal);
297  crm_trace("Start failures are %s",
298  is_set(data_set->flags,
299  pe_flag_start_failure_fatal) ? "always fatal" : "handled by failcount");
300 
301  if (is_set(data_set->flags, pe_flag_stonith_enabled)) {
302  set_config_flag(data_set, "startup-fencing", pe_flag_startup_fencing);
303  }
304  if (is_set(data_set->flags, pe_flag_startup_fencing)) {
305  crm_trace("Unseen nodes will be fenced");
306  } else {
307  pe_warn_once(pe_wo_blind, "Blind faith: not fencing unseen nodes");
308  }
309 
310  node_score_red = char2score(pe_pref(data_set->config_hash, "node-health-red"));
311  node_score_green = char2score(pe_pref(data_set->config_hash, "node-health-green"));
312  node_score_yellow = char2score(pe_pref(data_set->config_hash, "node-health-yellow"));
313 
314  crm_debug("Node scores: 'red' = %s, 'yellow' = %s, 'green' = %s",
315  pe_pref(data_set->config_hash, "node-health-red"),
316  pe_pref(data_set->config_hash, "node-health-yellow"),
317  pe_pref(data_set->config_hash, "node-health-green"));
318 
319  data_set->placement_strategy = pe_pref(data_set->config_hash, "placement-strategy");
320  crm_trace("Placement strategy: %s", data_set->placement_strategy);
321 
322  return TRUE;
323 }
324 
325 static void
326 destroy_digest_cache(gpointer ptr)
327 {
328  op_digest_cache_t *data = ptr;
329 
330  free_xml(data->params_all);
331  free_xml(data->params_secure);
332  free_xml(data->params_restart);
333 
334  free(data->digest_all_calc);
335  free(data->digest_restart_calc);
336  free(data->digest_secure_calc);
337 
338  free(data);
339 }
340 
341 node_t *
342 pe_create_node(const char *id, const char *uname, const char *type,
343  const char *score, pe_working_set_t * data_set)
344 {
345  node_t *new_node = NULL;
346 
347  if (pe_find_node(data_set->nodes, uname) != NULL) {
348  crm_config_warn("Detected multiple node entries with uname=%s"
349  " - this is rarely intended", uname);
350  }
351 
352  new_node = calloc(1, sizeof(node_t));
353  if (new_node == NULL) {
354  return NULL;
355  }
356 
357  new_node->weight = char2score(score);
358  new_node->fixed = FALSE;
359  new_node->details = calloc(1, sizeof(struct pe_node_shared_s));
360 
361  if (new_node->details == NULL) {
362  free(new_node);
363  return NULL;
364  }
365 
366  crm_trace("Creating node for entry %s/%s", uname, id);
367  new_node->details->id = id;
368  new_node->details->uname = uname;
369  new_node->details->online = FALSE;
370  new_node->details->shutdown = FALSE;
371  new_node->details->rsc_discovery_enabled = TRUE;
372  new_node->details->running_rsc = NULL;
373  new_node->details->type = node_ping;
374 
375  if (safe_str_eq(type, "remote")) {
376  new_node->details->type = node_remote;
378  } else if ((type == NULL) || safe_str_eq(type, "member")) {
379  new_node->details->type = node_member;
380  }
381 
382  new_node->details->attrs = crm_str_table_new();
383 
384  if (pe__is_guest_or_remote_node(new_node)) {
385  g_hash_table_insert(new_node->details->attrs, strdup(CRM_ATTR_KIND),
386  strdup("remote"));
387  } else {
388  g_hash_table_insert(new_node->details->attrs, strdup(CRM_ATTR_KIND),
389  strdup("cluster"));
390  }
391 
392  new_node->details->utilization = crm_str_table_new();
393 
394  new_node->details->digest_cache = g_hash_table_new_full(crm_str_hash,
395  g_str_equal, free,
396  destroy_digest_cache);
397 
398  data_set->nodes = g_list_insert_sorted(data_set->nodes, new_node, sort_node_uname);
399  return new_node;
400 }
401 
402 bool
403 remote_id_conflict(const char *remote_name, pe_working_set_t *data)
404 {
405  bool match = FALSE;
406 #if 1
407  pe_find_resource(data->resources, remote_name);
408 #else
409  if (data->name_check == NULL) {
410  data->name_check = g_hash_table_new(crm_str_hash, g_str_equal);
411  for (xml_rsc = __xml_first_child_element(parent); xml_rsc != NULL;
412  xml_rsc = __xml_next_element(xml_rsc)) {
413 
414  const char *id = ID(xml_rsc);
415 
416  /* avoiding heap allocation here because we know the duration of this hashtable allows us to */
417  g_hash_table_insert(data->name_check, (char *) id, (char *) id);
418  }
419  }
420  if (g_hash_table_lookup(data->name_check, remote_name)) {
421  match = TRUE;
422  }
423 #endif
424  if (match) {
425  crm_err("Invalid remote-node name, a resource called '%s' already exists.", remote_name);
426  return NULL;
427  }
428 
429  return match;
430 }
431 
432 
433 static const char *
434 expand_remote_rsc_meta(xmlNode *xml_obj, xmlNode *parent, pe_working_set_t *data)
435 {
436  xmlNode *attr_set = NULL;
437  xmlNode *attr = NULL;
438 
439  const char *container_id = ID(xml_obj);
440  const char *remote_name = NULL;
441  const char *remote_server = NULL;
442  const char *remote_port = NULL;
443  const char *connect_timeout = "60s";
444  const char *remote_allow_migrate=NULL;
445  const char *is_managed = NULL;
446 
447  for (attr_set = __xml_first_child_element(xml_obj); attr_set != NULL;
448  attr_set = __xml_next_element(attr_set)) {
449  if (safe_str_neq((const char *)attr_set->name, XML_TAG_META_SETS)) {
450  continue;
451  }
452 
453  for (attr = __xml_first_child_element(attr_set); attr != NULL;
454  attr = __xml_next_element(attr)) {
455  const char *value = crm_element_value(attr, XML_NVPAIR_ATTR_VALUE);
456  const char *name = crm_element_value(attr, XML_NVPAIR_ATTR_NAME);
457 
459  remote_name = value;
460  } else if (safe_str_eq(name, "remote-addr")) {
461  remote_server = value;
462  } else if (safe_str_eq(name, "remote-port")) {
463  remote_port = value;
464  } else if (safe_str_eq(name, "remote-connect-timeout")) {
465  connect_timeout = value;
466  } else if (safe_str_eq(name, "remote-allow-migrate")) {
467  remote_allow_migrate=value;
468  } else if (safe_str_eq(name, XML_RSC_ATTR_MANAGED)) {
469  is_managed = value;
470  }
471  }
472  }
473 
474  if (remote_name == NULL) {
475  return NULL;
476  }
477 
478  if (remote_id_conflict(remote_name, data)) {
479  return NULL;
480  }
481 
482  pe_create_remote_xml(parent, remote_name, container_id,
483  remote_allow_migrate, is_managed,
484  connect_timeout, remote_server, remote_port);
485  return remote_name;
486 }
487 
488 static void
489 handle_startup_fencing(pe_working_set_t *data_set, node_t *new_node)
490 {
491  if ((new_node->details->type == node_remote) && (new_node->details->remote_rsc == NULL)) {
492  /* Ignore fencing for remote nodes that don't have a connection resource
493  * associated with them. This happens when remote node entries get left
494  * in the nodes section after the connection resource is removed.
495  */
496  return;
497  }
498 
499  if (is_set(data_set->flags, pe_flag_startup_fencing)) {
500  // All nodes are unclean until we've seen their status entry
501  new_node->details->unclean = TRUE;
502 
503  } else {
504  // Blind faith ...
505  new_node->details->unclean = FALSE;
506  }
507 
508  /* We need to be able to determine if a node's status section
509  * exists or not separate from whether the node is unclean. */
510  new_node->details->unseen = TRUE;
511 }
512 
513 gboolean
514 unpack_nodes(xmlNode * xml_nodes, pe_working_set_t * data_set)
515 {
516  xmlNode *xml_obj = NULL;
517  node_t *new_node = NULL;
518  const char *id = NULL;
519  const char *uname = NULL;
520  const char *type = NULL;
521  const char *score = NULL;
522 
523  for (xml_obj = __xml_first_child_element(xml_nodes); xml_obj != NULL;
524  xml_obj = __xml_next_element(xml_obj)) {
525 
526  if (crm_str_eq((const char *)xml_obj->name, XML_CIB_TAG_NODE, TRUE)) {
527  new_node = NULL;
528 
529  id = crm_element_value(xml_obj, XML_ATTR_ID);
532  score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE);
533  crm_trace("Processing node %s/%s", uname, id);
534 
535  if (id == NULL) {
536  crm_config_err("Must specify id tag in <node>");
537  continue;
538  }
539  new_node = pe_create_node(id, uname, type, score, data_set);
540 
541  if (new_node == NULL) {
542  return FALSE;
543  }
544 
545 /* if(data_set->have_quorum == FALSE */
546 /* && data_set->no_quorum_policy == no_quorum_stop) { */
547 /* /\* start shutting resources down *\/ */
548 /* new_node->weight = -INFINITY; */
549 /* } */
550 
551  handle_startup_fencing(data_set, new_node);
552 
553  add_node_attrs(xml_obj, new_node, FALSE, data_set);
555  new_node->details->utilization, NULL,
556  FALSE, data_set);
557 
558  crm_trace("Done with node %s", crm_element_value(xml_obj, XML_ATTR_UNAME));
559  }
560  }
561 
562  if (data_set->localhost && pe_find_node(data_set->nodes, data_set->localhost) == NULL) {
563  crm_info("Creating a fake local node");
564  pe_create_node(data_set->localhost, data_set->localhost, NULL, 0,
565  data_set);
566  }
567 
568  return TRUE;
569 }
570 
571 static void
572 setup_container(resource_t * rsc, pe_working_set_t * data_set)
573 {
574  const char *container_id = NULL;
575 
576  if (rsc->children) {
577  GListPtr gIter = rsc->children;
578 
579  for (; gIter != NULL; gIter = gIter->next) {
580  resource_t *child_rsc = (resource_t *) gIter->data;
581 
582  setup_container(child_rsc, data_set);
583  }
584  return;
585  }
586 
587  container_id = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_CONTAINER);
588  if (container_id && safe_str_neq(container_id, rsc->id)) {
589  resource_t *container = pe_find_resource(data_set->resources, container_id);
590 
591  if (container) {
592  rsc->container = container;
593  set_bit(container->flags, pe_rsc_is_container);
594  container->fillers = g_list_append(container->fillers, rsc);
595  pe_rsc_trace(rsc, "Resource %s's container is %s", rsc->id, container_id);
596  } else {
597  pe_err("Resource %s: Unknown resource container (%s)", rsc->id, container_id);
598  }
599  }
600 }
601 
602 gboolean
603 unpack_remote_nodes(xmlNode * xml_resources, pe_working_set_t * data_set)
604 {
605  xmlNode *xml_obj = NULL;
606 
607  /* Create remote nodes and guest nodes from the resource configuration
608  * before unpacking resources.
609  */
610  for (xml_obj = __xml_first_child_element(xml_resources); xml_obj != NULL;
611  xml_obj = __xml_next_element(xml_obj)) {
612 
613  const char *new_node_id = NULL;
614 
615  /* Check for remote nodes, which are defined by ocf:pacemaker:remote
616  * primitives.
617  */
618  if (xml_contains_remote_node(xml_obj)) {
619  new_node_id = ID(xml_obj);
620  /* The "pe_find_node" check is here to make sure we don't iterate over
621  * an expanded node that has already been added to the node list. */
622  if (new_node_id && pe_find_node(data_set->nodes, new_node_id) == NULL) {
623  crm_trace("Found remote node %s defined by resource %s",
624  new_node_id, ID(xml_obj));
625  pe_create_node(new_node_id, new_node_id, "remote", NULL,
626  data_set);
627  }
628  continue;
629  }
630 
631  /* Check for guest nodes, which are defined by special meta-attributes
632  * of a primitive of any type (for example, VirtualDomain or Xen).
633  */
634  if (crm_str_eq((const char *)xml_obj->name, XML_CIB_TAG_RESOURCE, TRUE)) {
635  /* This will add an ocf:pacemaker:remote primitive to the
636  * configuration for the guest node's connection, to be unpacked
637  * later.
638  */
639  new_node_id = expand_remote_rsc_meta(xml_obj, xml_resources, data_set);
640  if (new_node_id && pe_find_node(data_set->nodes, new_node_id) == NULL) {
641  crm_trace("Found guest node %s in resource %s",
642  new_node_id, ID(xml_obj));
643  pe_create_node(new_node_id, new_node_id, "remote", NULL,
644  data_set);
645  }
646  continue;
647  }
648 
649  /* Check for guest nodes inside a group. Clones are currently not
650  * supported as guest nodes.
651  */
652  if (crm_str_eq((const char *)xml_obj->name, XML_CIB_TAG_GROUP, TRUE)) {
653  xmlNode *xml_obj2 = NULL;
654  for (xml_obj2 = __xml_first_child_element(xml_obj); xml_obj2 != NULL;
655  xml_obj2 = __xml_next_element(xml_obj2)) {
656 
657  new_node_id = expand_remote_rsc_meta(xml_obj2, xml_resources, data_set);
658 
659  if (new_node_id && pe_find_node(data_set->nodes, new_node_id) == NULL) {
660  crm_trace("Found guest node %s in resource %s inside group %s",
661  new_node_id, ID(xml_obj2), ID(xml_obj));
662  pe_create_node(new_node_id, new_node_id, "remote", NULL,
663  data_set);
664  }
665  }
666  }
667  }
668  return TRUE;
669 }
670 
671 /* Call this after all the nodes and resources have been
672  * unpacked, but before the status section is read.
673  *
674  * A remote node's online status is reflected by the state
675  * of the remote node's connection resource. We need to link
676  * the remote node to this connection resource so we can have
677  * easy access to the connection resource during the PE calculations.
678  */
679 static void
680 link_rsc2remotenode(pe_working_set_t *data_set, resource_t *new_rsc)
681 {
682  node_t *remote_node = NULL;
683 
684  if (new_rsc->is_remote_node == FALSE) {
685  return;
686  }
687 
688  if (is_set(data_set->flags, pe_flag_quick_location)) {
689  /* remote_nodes and remote_resources are not linked in quick location calculations */
690  return;
691  }
692 
693  remote_node = pe_find_node(data_set->nodes, new_rsc->id);
694  CRM_CHECK(remote_node != NULL, return;);
695 
696  pe_rsc_trace(new_rsc, "Linking remote connection resource %s to node %s",
697  new_rsc->id, remote_node->details->uname);
698  remote_node->details->remote_rsc = new_rsc;
699 
700  if (new_rsc->container == NULL) {
701  /* Handle start-up fencing for remote nodes (as opposed to guest nodes)
702  * the same as is done for cluster nodes.
703  */
704  handle_startup_fencing(data_set, remote_node);
705 
706  } else {
707  /* pe_create_node() marks the new node as "remote" or "cluster"; now
708  * that we know the node is a guest node, update it correctly.
709  */
710  g_hash_table_replace(remote_node->details->attrs, strdup(CRM_ATTR_KIND),
711  strdup("container"));
712  }
713 }
714 
715 static void
716 destroy_tag(gpointer data)
717 {
718  tag_t *tag = data;
719 
720  if (tag) {
721  free(tag->id);
722  g_list_free_full(tag->refs, free);
723  free(tag);
724  }
725 }
726 
739 gboolean
740 unpack_resources(xmlNode * xml_resources, pe_working_set_t * data_set)
741 {
742  xmlNode *xml_obj = NULL;
743  GListPtr gIter = NULL;
744 
745  data_set->template_rsc_sets = g_hash_table_new_full(crm_str_hash,
746  g_str_equal, free,
747  destroy_tag);
748 
749  for (xml_obj = __xml_first_child_element(xml_resources); xml_obj != NULL;
750  xml_obj = __xml_next_element(xml_obj)) {
751 
752  resource_t *new_rsc = NULL;
753 
754  if (crm_str_eq((const char *)xml_obj->name, XML_CIB_TAG_RSC_TEMPLATE, TRUE)) {
755  const char *template_id = ID(xml_obj);
756 
757  if (template_id && g_hash_table_lookup_extended(data_set->template_rsc_sets,
758  template_id, NULL, NULL) == FALSE) {
759  /* Record the template's ID for the knowledge of its existence anyway. */
760  g_hash_table_insert(data_set->template_rsc_sets, strdup(template_id), NULL);
761  }
762  continue;
763  }
764 
765  crm_trace("Beginning unpack... <%s id=%s... >", crm_element_name(xml_obj), ID(xml_obj));
766  if (common_unpack(xml_obj, &new_rsc, NULL, data_set)) {
767  data_set->resources = g_list_append(data_set->resources, new_rsc);
768  pe_rsc_trace(new_rsc, "Added resource %s", new_rsc->id);
769 
770  } else {
771  crm_config_err("Failed unpacking %s %s",
772  crm_element_name(xml_obj), crm_element_value(xml_obj, XML_ATTR_ID));
773  if (new_rsc != NULL && new_rsc->fns != NULL) {
774  new_rsc->fns->free(new_rsc);
775  }
776  }
777  }
778 
779  for (gIter = data_set->resources; gIter != NULL; gIter = gIter->next) {
780  resource_t *rsc = (resource_t *) gIter->data;
781 
782  setup_container(rsc, data_set);
783  link_rsc2remotenode(data_set, rsc);
784  }
785 
786  data_set->resources = g_list_sort(data_set->resources, sort_rsc_priority);
787  if (is_set(data_set->flags, pe_flag_quick_location)) {
788  /* Ignore */
789 
790  } else if (is_set(data_set->flags, pe_flag_stonith_enabled)
791  && is_set(data_set->flags, pe_flag_have_stonith_resource) == FALSE) {
792 
793  crm_config_err("Resource start-up disabled since no STONITH resources have been defined");
794  crm_config_err("Either configure some or disable STONITH with the stonith-enabled option");
795  crm_config_err("NOTE: Clusters with shared data need STONITH to ensure data integrity");
796  }
797 
798  return TRUE;
799 }
800 
801 gboolean
802 unpack_tags(xmlNode * xml_tags, pe_working_set_t * data_set)
803 {
804  xmlNode *xml_tag = NULL;
805 
806  data_set->tags = g_hash_table_new_full(crm_str_hash, g_str_equal, free,
807  destroy_tag);
808 
809  for (xml_tag = __xml_first_child_element(xml_tags); xml_tag != NULL;
810  xml_tag = __xml_next_element(xml_tag)) {
811 
812  xmlNode *xml_obj_ref = NULL;
813  const char *tag_id = ID(xml_tag);
814 
815  if (crm_str_eq((const char *)xml_tag->name, XML_CIB_TAG_TAG, TRUE) == FALSE) {
816  continue;
817  }
818 
819  if (tag_id == NULL) {
820  crm_config_err("Failed unpacking %s: %s should be specified",
821  crm_element_name(xml_tag), XML_ATTR_ID);
822  continue;
823  }
824 
825  for (xml_obj_ref = __xml_first_child_element(xml_tag); xml_obj_ref != NULL;
826  xml_obj_ref = __xml_next_element(xml_obj_ref)) {
827 
828  const char *obj_ref = ID(xml_obj_ref);
829 
830  if (crm_str_eq((const char *)xml_obj_ref->name, XML_CIB_TAG_OBJ_REF, TRUE) == FALSE) {
831  continue;
832  }
833 
834  if (obj_ref == NULL) {
835  crm_config_err("Failed unpacking %s for tag %s: %s should be specified",
836  crm_element_name(xml_obj_ref), tag_id, XML_ATTR_ID);
837  continue;
838  }
839 
840  if (add_tag_ref(data_set->tags, tag_id, obj_ref) == FALSE) {
841  return FALSE;
842  }
843  }
844  }
845 
846  return TRUE;
847 }
848 
849 /* The ticket state section:
850  * "/cib/status/tickets/ticket_state" */
851 static gboolean
852 unpack_ticket_state(xmlNode * xml_ticket, pe_working_set_t * data_set)
853 {
854  const char *ticket_id = NULL;
855  const char *granted = NULL;
856  const char *last_granted = NULL;
857  const char *standby = NULL;
858  xmlAttrPtr xIter = NULL;
859 
860  ticket_t *ticket = NULL;
861 
862  ticket_id = ID(xml_ticket);
863  if (ticket_id == NULL || strlen(ticket_id) == 0) {
864  return FALSE;
865  }
866 
867  crm_trace("Processing ticket state for %s", ticket_id);
868 
869  ticket = g_hash_table_lookup(data_set->tickets, ticket_id);
870  if (ticket == NULL) {
871  ticket = ticket_new(ticket_id, data_set);
872  if (ticket == NULL) {
873  return FALSE;
874  }
875  }
876 
877  for (xIter = xml_ticket->properties; xIter; xIter = xIter->next) {
878  const char *prop_name = (const char *)xIter->name;
879  const char *prop_value = crm_element_value(xml_ticket, prop_name);
880 
881  if (crm_str_eq(prop_name, XML_ATTR_ID, TRUE)) {
882  continue;
883  }
884  g_hash_table_replace(ticket->state, strdup(prop_name), strdup(prop_value));
885  }
886 
887  granted = g_hash_table_lookup(ticket->state, "granted");
888  if (granted && crm_is_true(granted)) {
889  ticket->granted = TRUE;
890  crm_info("We have ticket '%s'", ticket->id);
891  } else {
892  ticket->granted = FALSE;
893  crm_info("We do not have ticket '%s'", ticket->id);
894  }
895 
896  last_granted = g_hash_table_lookup(ticket->state, "last-granted");
897  if (last_granted) {
898  ticket->last_granted = crm_parse_int(last_granted, 0);
899  }
900 
901  standby = g_hash_table_lookup(ticket->state, "standby");
902  if (standby && crm_is_true(standby)) {
903  ticket->standby = TRUE;
904  if (ticket->granted) {
905  crm_info("Granted ticket '%s' is in standby-mode", ticket->id);
906  }
907  } else {
908  ticket->standby = FALSE;
909  }
910 
911  crm_trace("Done with ticket state for %s", ticket_id);
912 
913  return TRUE;
914 }
915 
916 static gboolean
917 unpack_tickets_state(xmlNode * xml_tickets, pe_working_set_t * data_set)
918 {
919  xmlNode *xml_obj = NULL;
920 
921  for (xml_obj = __xml_first_child_element(xml_tickets); xml_obj != NULL;
922  xml_obj = __xml_next_element(xml_obj)) {
923 
924  if (crm_str_eq((const char *)xml_obj->name, XML_CIB_TAG_TICKET_STATE, TRUE) == FALSE) {
925  continue;
926  }
927  unpack_ticket_state(xml_obj, data_set);
928  }
929 
930  return TRUE;
931 }
932 
933 static void
934 unpack_handle_remote_attrs(node_t *this_node, xmlNode *state, pe_working_set_t * data_set)
935 {
936  const char *resource_discovery_enabled = NULL;
937  xmlNode *attrs = NULL;
938  resource_t *rsc = NULL;
939 
940  if (crm_str_eq((const char *)state->name, XML_CIB_TAG_STATE, TRUE) == FALSE) {
941  return;
942  }
943 
944  if ((this_node == NULL) || !pe__is_guest_or_remote_node(this_node)) {
945  return;
946  }
947  crm_trace("Processing remote node id=%s, uname=%s", this_node->details->id, this_node->details->uname);
948 
949  this_node->details->remote_maintenance =
951 
952  rsc = this_node->details->remote_rsc;
953  if (this_node->details->remote_requires_reset == FALSE) {
954  this_node->details->unclean = FALSE;
955  this_node->details->unseen = FALSE;
956  }
957  attrs = find_xml_node(state, XML_TAG_TRANSIENT_NODEATTRS, FALSE);
958  add_node_attrs(attrs, this_node, TRUE, data_set);
959 
960  if (pe__shutdown_requested(this_node)) {
961  crm_info("Node %s is shutting down", this_node->details->uname);
962  this_node->details->shutdown = TRUE;
963  if (rsc) {
965  }
966  }
967 
968  if (crm_is_true(pe_node_attribute_raw(this_node, "standby"))) {
969  crm_info("Node %s is in standby-mode", this_node->details->uname);
970  this_node->details->standby = TRUE;
971  }
972 
973  if (crm_is_true(pe_node_attribute_raw(this_node, "maintenance")) ||
974  (rsc && !is_set(rsc->flags, pe_rsc_managed))) {
975  crm_info("Node %s is in maintenance-mode", this_node->details->uname);
976  this_node->details->maintenance = TRUE;
977  }
978 
979  resource_discovery_enabled = pe_node_attribute_raw(this_node, XML_NODE_ATTR_RSC_DISCOVERY);
980  if (resource_discovery_enabled && !crm_is_true(resource_discovery_enabled)) {
981  if (pe__is_remote_node(this_node)
982  && is_not_set(data_set->flags, pe_flag_stonith_enabled)) {
983  crm_warn("Ignoring %s attribute on remote node %s because stonith is disabled",
985  } else {
986  /* This is either a remote node with fencing enabled, or a guest
987  * node. We don't care whether fencing is enabled when fencing guest
988  * nodes, because they are "fenced" by recovering their containing
989  * resource.
990  */
991  crm_info("Node %s has resource discovery disabled", this_node->details->uname);
992  this_node->details->rsc_discovery_enabled = FALSE;
993  }
994  }
995 }
996 
997 static bool
998 unpack_node_loop(xmlNode * status, bool fence, pe_working_set_t * data_set)
999 {
1000  bool changed = false;
1001  xmlNode *lrm_rsc = NULL;
1002 
1003  for (xmlNode *state = __xml_first_child_element(status); state != NULL;
1004  state = __xml_next_element(state)) {
1005 
1006  const char *id = NULL;
1007  const char *uname = NULL;
1008  node_t *this_node = NULL;
1009  bool process = FALSE;
1010 
1011  if (crm_str_eq((const char *)state->name, XML_CIB_TAG_STATE, TRUE) == FALSE) {
1012  continue;
1013  }
1014 
1015  id = crm_element_value(state, XML_ATTR_ID);
1017  this_node = pe_find_node_any(data_set->nodes, id, uname);
1018 
1019  if (this_node == NULL) {
1020  crm_info("Node %s is unknown", id);
1021  continue;
1022 
1023  } else if (this_node->details->unpacked) {
1024  crm_info("Node %s is already processed", id);
1025  continue;
1026 
1027  } else if (!pe__is_guest_or_remote_node(this_node)
1028  && is_set(data_set->flags, pe_flag_stonith_enabled)) {
1029  // A redundant test, but preserves the order for regression tests
1030  process = TRUE;
1031 
1032  } else if (pe__is_guest_or_remote_node(this_node)) {
1033  bool check = FALSE;
1034  resource_t *rsc = this_node->details->remote_rsc;
1035 
1036  if(fence) {
1037  check = TRUE;
1038 
1039  } else if(rsc == NULL) {
1040  /* Not ready yet */
1041 
1042  } else if (pe__is_guest_node(this_node)
1043  && rsc->role == RSC_ROLE_STARTED
1044  && rsc->container->role == RSC_ROLE_STARTED) {
1045  /* Both the connection and its containing resource need to be
1046  * known to be up before we process resources running in it.
1047  */
1048  check = TRUE;
1049  crm_trace("Checking node %s/%s/%s status %d/%d/%d", id, rsc->id, rsc->container->id, fence, rsc->role, RSC_ROLE_STARTED);
1050 
1051  } else if (!pe__is_guest_node(this_node)
1052  && rsc->role == RSC_ROLE_STARTED) {
1053  check = TRUE;
1054  crm_trace("Checking node %s/%s status %d/%d/%d", id, rsc->id, fence, rsc->role, RSC_ROLE_STARTED);
1055  }
1056 
1057  if (check) {
1058  determine_remote_online_status(data_set, this_node);
1059  unpack_handle_remote_attrs(this_node, state, data_set);
1060  process = TRUE;
1061  }
1062 
1063  } else if (this_node->details->online) {
1064  process = TRUE;
1065 
1066  } else if (fence) {
1067  process = TRUE;
1068  }
1069 
1070  if(process) {
1071  crm_trace("Processing lrm resource entries on %shealthy%s node: %s",
1072  fence?"un":"",
1073  (pe__is_guest_or_remote_node(this_node)? " remote" : ""),
1074  this_node->details->uname);
1075  changed = TRUE;
1076  this_node->details->unpacked = TRUE;
1077 
1078  lrm_rsc = find_xml_node(state, XML_CIB_TAG_LRM, FALSE);
1079  lrm_rsc = find_xml_node(lrm_rsc, XML_LRM_TAG_RESOURCES, FALSE);
1080  unpack_lrm_resources(this_node, lrm_rsc, data_set);
1081  }
1082  }
1083  return changed;
1084 }
1085 
1086 /* remove nodes that are down, stopping */
1087 /* create positive rsc_to_node constraints between resources and the nodes they are running on */
1088 /* anything else? */
1089 gboolean
1090 unpack_status(xmlNode * status, pe_working_set_t * data_set)
1091 {
1092  const char *id = NULL;
1093  const char *uname = NULL;
1094 
1095  xmlNode *state = NULL;
1096  node_t *this_node = NULL;
1097 
1098  crm_trace("Beginning unpack");
1099 
1100  if (data_set->tickets == NULL) {
1101  data_set->tickets = g_hash_table_new_full(crm_str_hash, g_str_equal,
1102  free, destroy_ticket);
1103  }
1104 
1105  for (state = __xml_first_child_element(status); state != NULL;
1106  state = __xml_next_element(state)) {
1107 
1108  if (crm_str_eq((const char *)state->name, XML_CIB_TAG_TICKETS, TRUE)) {
1109  unpack_tickets_state((xmlNode *) state, data_set);
1110 
1111  } else if (crm_str_eq((const char *)state->name, XML_CIB_TAG_STATE, TRUE)) {
1112  xmlNode *attrs = NULL;
1113  const char *resource_discovery_enabled = NULL;
1114 
1115  id = crm_element_value(state, XML_ATTR_ID);
1117  this_node = pe_find_node_any(data_set->nodes, id, uname);
1118 
1119  if (uname == NULL) {
1120  /* error */
1121  continue;
1122 
1123  } else if (this_node == NULL) {
1124  crm_config_warn("Node %s in status section no longer exists", uname);
1125  continue;
1126 
1127  } else if (pe__is_guest_or_remote_node(this_node)) {
1128  /* online state for remote nodes is determined by the
1129  * rsc state after all the unpacking is done. we do however
1130  * need to mark whether or not the node has been fenced as this plays
1131  * a role during unpacking cluster node resource state */
1132  this_node->details->remote_was_fenced =
1134  continue;
1135  }
1136 
1137  crm_trace("Processing node id=%s, uname=%s", id, uname);
1138 
1139  /* Mark the node as provisionally clean
1140  * - at least we have seen it in the current cluster's lifetime
1141  */
1142  this_node->details->unclean = FALSE;
1143  this_node->details->unseen = FALSE;
1144  attrs = find_xml_node(state, XML_TAG_TRANSIENT_NODEATTRS, FALSE);
1145  add_node_attrs(attrs, this_node, TRUE, data_set);
1146 
1147  if (crm_is_true(pe_node_attribute_raw(this_node, "standby"))) {
1148  crm_info("Node %s is in standby-mode", this_node->details->uname);
1149  this_node->details->standby = TRUE;
1150  }
1151 
1152  if (crm_is_true(pe_node_attribute_raw(this_node, "maintenance"))) {
1153  crm_info("Node %s is in maintenance-mode", this_node->details->uname);
1154  this_node->details->maintenance = TRUE;
1155  }
1156 
1157  resource_discovery_enabled = pe_node_attribute_raw(this_node, XML_NODE_ATTR_RSC_DISCOVERY);
1158  if (resource_discovery_enabled && !crm_is_true(resource_discovery_enabled)) {
1159  crm_warn("ignoring %s attribute on node %s, disabling resource discovery is not allowed on cluster nodes",
1161  }
1162 
1163  crm_trace("determining node state");
1164  determine_online_status(state, this_node, data_set);
1165 
1166  if (is_not_set(data_set->flags, pe_flag_have_quorum)
1167  && this_node->details->online
1168  && (data_set->no_quorum_policy == no_quorum_suicide)) {
1169  /* Everything else should flow from this automatically
1170  * At least until the PE becomes able to migrate off healthy resources
1171  */
1172  pe_fence_node(data_set, this_node, "cluster does not have quorum");
1173  }
1174  }
1175  }
1176 
1177 
1178  while(unpack_node_loop(status, FALSE, data_set)) {
1179  crm_trace("Start another loop");
1180  }
1181 
1182  // Now catch any nodes we didn't see
1183  unpack_node_loop(status, is_set(data_set->flags, pe_flag_stonith_enabled), data_set);
1184 
1185  /* Now that we know where resources are, we can schedule stops of containers
1186  * with failed bundle connections
1187  */
1188  if (data_set->stop_needed != NULL) {
1189  for (GList *item = data_set->stop_needed; item; item = item->next) {
1190  pe_resource_t *container = item->data;
1191  pe_node_t *node = pe__current_node(container);
1192 
1193  if (node) {
1194  stop_action(container, node, FALSE);
1195  }
1196  }
1197  g_list_free(data_set->stop_needed);
1198  data_set->stop_needed = NULL;
1199  }
1200 
1201  for (GListPtr gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) {
1202  node_t *this_node = gIter->data;
1203 
1204  if (this_node == NULL) {
1205  continue;
1206  } else if (!pe__is_guest_or_remote_node(this_node)) {
1207  continue;
1208  } else if(this_node->details->unpacked) {
1209  continue;
1210  }
1211  determine_remote_online_status(data_set, this_node);
1212  }
1213 
1214  return TRUE;
1215 }
1216 
1217 static gboolean
1218 determine_online_status_no_fencing(pe_working_set_t * data_set, xmlNode * node_state,
1219  node_t * this_node)
1220 {
1221  gboolean online = FALSE;
1222  const char *join = crm_element_value(node_state, XML_NODE_JOIN_STATE);
1223  const char *is_peer = crm_element_value(node_state, XML_NODE_IS_PEER);
1224  const char *in_cluster = crm_element_value(node_state, XML_NODE_IN_CLUSTER);
1225  const char *exp_state = crm_element_value(node_state, XML_NODE_EXPECTED);
1226 
1227  if (!crm_is_true(in_cluster)) {
1228  crm_trace("Node is down: in_cluster=%s", crm_str(in_cluster));
1229 
1230  } else if (safe_str_eq(is_peer, ONLINESTATUS)) {
1231  if (safe_str_eq(join, CRMD_JOINSTATE_MEMBER)) {
1232  online = TRUE;
1233  } else {
1234  crm_debug("Node is not ready to run resources: %s", join);
1235  }
1236 
1237  } else if (this_node->details->expected_up == FALSE) {
1238  crm_trace("Controller is down: in_cluster=%s", crm_str(in_cluster));
1239  crm_trace("\tis_peer=%s, join=%s, expected=%s",
1240  crm_str(is_peer), crm_str(join), crm_str(exp_state));
1241 
1242  } else {
1243  /* mark it unclean */
1244  pe_fence_node(data_set, this_node, "peer is unexpectedly down");
1245  crm_info("\tin_cluster=%s, is_peer=%s, join=%s, expected=%s",
1246  crm_str(in_cluster), crm_str(is_peer), crm_str(join), crm_str(exp_state));
1247  }
1248  return online;
1249 }
1250 
1251 static gboolean
1252 determine_online_status_fencing(pe_working_set_t * data_set, xmlNode * node_state,
1253  node_t * this_node)
1254 {
1255  gboolean online = FALSE;
1256  gboolean do_terminate = FALSE;
1257  bool crmd_online = FALSE;
1258  const char *join = crm_element_value(node_state, XML_NODE_JOIN_STATE);
1259  const char *is_peer = crm_element_value(node_state, XML_NODE_IS_PEER);
1260  const char *in_cluster = crm_element_value(node_state, XML_NODE_IN_CLUSTER);
1261  const char *exp_state = crm_element_value(node_state, XML_NODE_EXPECTED);
1262  const char *terminate = pe_node_attribute_raw(this_node, "terminate");
1263 
1264 /*
1265  - XML_NODE_IN_CLUSTER ::= true|false
1266  - XML_NODE_IS_PEER ::= online|offline
1267  - XML_NODE_JOIN_STATE ::= member|down|pending|banned
1268  - XML_NODE_EXPECTED ::= member|down
1269 */
1270 
1271  if (crm_is_true(terminate)) {
1272  do_terminate = TRUE;
1273 
1274  } else if (terminate != NULL && strlen(terminate) > 0) {
1275  /* could be a time() value */
1276  char t = terminate[0];
1277 
1278  if (t != '0' && isdigit(t)) {
1279  do_terminate = TRUE;
1280  }
1281  }
1282 
1283  crm_trace("%s: in_cluster=%s, is_peer=%s, join=%s, expected=%s, term=%d",
1284  this_node->details->uname, crm_str(in_cluster), crm_str(is_peer),
1285  crm_str(join), crm_str(exp_state), do_terminate);
1286 
1287  online = crm_is_true(in_cluster);
1288  crmd_online = safe_str_eq(is_peer, ONLINESTATUS);
1289  if (exp_state == NULL) {
1290  exp_state = CRMD_JOINSTATE_DOWN;
1291  }
1292 
1293  if (this_node->details->shutdown) {
1294  crm_debug("%s is shutting down", this_node->details->uname);
1295 
1296  /* Slightly different criteria since we can't shut down a dead peer */
1297  online = crmd_online;
1298 
1299  } else if (in_cluster == NULL) {
1300  pe_fence_node(data_set, this_node, "peer has not been seen by the cluster");
1301 
1302  } else if (safe_str_eq(join, CRMD_JOINSTATE_NACK)) {
1303  pe_fence_node(data_set, this_node, "peer failed the pacemaker membership criteria");
1304 
1305  } else if (do_terminate == FALSE && safe_str_eq(exp_state, CRMD_JOINSTATE_DOWN)) {
1306 
1307  if (crm_is_true(in_cluster) || crmd_online) {
1308  crm_info("- Node %s is not ready to run resources", this_node->details->uname);
1309  this_node->details->standby = TRUE;
1310  this_node->details->pending = TRUE;
1311 
1312  } else {
1313  crm_trace("%s is down or still coming up", this_node->details->uname);
1314  }
1315 
1316  } else if (do_terminate && safe_str_eq(join, CRMD_JOINSTATE_DOWN)
1317  && crm_is_true(in_cluster) == FALSE && !crmd_online) {
1318  crm_info("Node %s was just shot", this_node->details->uname);
1319  online = FALSE;
1320 
1321  } else if (crm_is_true(in_cluster) == FALSE) {
1322  pe_fence_node(data_set, this_node, "peer is no longer part of the cluster");
1323 
1324  } else if (!crmd_online) {
1325  pe_fence_node(data_set, this_node, "peer process is no longer available");
1326 
1327  /* Everything is running at this point, now check join state */
1328  } else if (do_terminate) {
1329  pe_fence_node(data_set, this_node, "termination was requested");
1330 
1331  } else if (safe_str_eq(join, CRMD_JOINSTATE_MEMBER)) {
1332  crm_info("Node %s is active", this_node->details->uname);
1333 
1334  } else if (safe_str_eq(join, CRMD_JOINSTATE_PENDING)
1335  || safe_str_eq(join, CRMD_JOINSTATE_DOWN)) {
1336  crm_info("Node %s is not ready to run resources", this_node->details->uname);
1337  this_node->details->standby = TRUE;
1338  this_node->details->pending = TRUE;
1339 
1340  } else {
1341  pe_fence_node(data_set, this_node, "peer was in an unknown state");
1342  crm_warn("%s: in-cluster=%s, is-peer=%s, join=%s, expected=%s, term=%d, shutdown=%d",
1343  this_node->details->uname, crm_str(in_cluster), crm_str(is_peer),
1344  crm_str(join), crm_str(exp_state), do_terminate, this_node->details->shutdown);
1345  }
1346 
1347  return online;
1348 }
1349 
1350 static gboolean
1351 determine_remote_online_status(pe_working_set_t * data_set, node_t * this_node)
1352 {
1353  resource_t *rsc = this_node->details->remote_rsc;
1354  resource_t *container = NULL;
1355  pe_node_t *host = NULL;
1356 
1357  /* If there is a node state entry for a (former) Pacemaker Remote node
1358  * but no resource creating that node, the node's connection resource will
1359  * be NULL. Consider it an offline remote node in that case.
1360  */
1361  if (rsc == NULL) {
1362  this_node->details->online = FALSE;
1363  goto remote_online_done;
1364  }
1365 
1366  container = rsc->container;
1367 
1368  if (container && (g_list_length(rsc->running_on) == 1)) {
1369  host = rsc->running_on->data;
1370  }
1371 
1372  /* If the resource is currently started, mark it online. */
1373  if (rsc->role == RSC_ROLE_STARTED) {
1374  crm_trace("%s node %s presumed ONLINE because connection resource is started",
1375  (container? "Guest" : "Remote"), this_node->details->id);
1376  this_node->details->online = TRUE;
1377  }
1378 
1379  /* consider this node shutting down if transitioning start->stop */
1380  if (rsc->role == RSC_ROLE_STARTED && rsc->next_role == RSC_ROLE_STOPPED) {
1381  crm_trace("%s node %s shutting down because connection resource is stopping",
1382  (container? "Guest" : "Remote"), this_node->details->id);
1383  this_node->details->shutdown = TRUE;
1384  }
1385 
1386  /* Now check all the failure conditions. */
1387  if(container && is_set(container->flags, pe_rsc_failed)) {
1388  crm_trace("Guest node %s UNCLEAN because guest resource failed",
1389  this_node->details->id);
1390  this_node->details->online = FALSE;
1391  this_node->details->remote_requires_reset = TRUE;
1392 
1393  } else if(is_set(rsc->flags, pe_rsc_failed)) {
1394  crm_trace("%s node %s OFFLINE because connection resource failed",
1395  (container? "Guest" : "Remote"), this_node->details->id);
1396  this_node->details->online = FALSE;
1397 
1398  } else if (rsc->role == RSC_ROLE_STOPPED
1399  || (container && container->role == RSC_ROLE_STOPPED)) {
1400 
1401  crm_trace("%s node %s OFFLINE because its resource is stopped",
1402  (container? "Guest" : "Remote"), this_node->details->id);
1403  this_node->details->online = FALSE;
1404  this_node->details->remote_requires_reset = FALSE;
1405 
1406  } else if (host && (host->details->online == FALSE)
1407  && host->details->unclean) {
1408  crm_trace("Guest node %s UNCLEAN because host is unclean",
1409  this_node->details->id);
1410  this_node->details->online = FALSE;
1411  this_node->details->remote_requires_reset = TRUE;
1412  }
1413 
1414 remote_online_done:
1415  crm_trace("Remote node %s online=%s",
1416  this_node->details->id, this_node->details->online ? "TRUE" : "FALSE");
1417  return this_node->details->online;
1418 }
1419 
1420 gboolean
1421 determine_online_status(xmlNode * node_state, node_t * this_node, pe_working_set_t * data_set)
1422 {
1423  gboolean online = FALSE;
1424  const char *exp_state = crm_element_value(node_state, XML_NODE_EXPECTED);
1425 
1426  if (this_node == NULL) {
1427  crm_config_err("No node to check");
1428  return online;
1429  }
1430 
1431  this_node->details->shutdown = FALSE;
1432  this_node->details->expected_up = FALSE;
1433 
1434  if (pe__shutdown_requested(this_node)) {
1435  this_node->details->shutdown = TRUE;
1436 
1437  } else if (safe_str_eq(exp_state, CRMD_JOINSTATE_MEMBER)) {
1438  this_node->details->expected_up = TRUE;
1439  }
1440 
1441  if (this_node->details->type == node_ping) {
1442  this_node->details->unclean = FALSE;
1443  online = FALSE; /* As far as resource management is concerned,
1444  * the node is safely offline.
1445  * Anyone caught abusing this logic will be shot
1446  */
1447 
1448  } else if (is_set(data_set->flags, pe_flag_stonith_enabled) == FALSE) {
1449  online = determine_online_status_no_fencing(data_set, node_state, this_node);
1450 
1451  } else {
1452  online = determine_online_status_fencing(data_set, node_state, this_node);
1453  }
1454 
1455  if (online) {
1456  this_node->details->online = TRUE;
1457 
1458  } else {
1459  /* remove node from contention */
1460  this_node->fixed = TRUE;
1461  this_node->weight = -INFINITY;
1462  }
1463 
1464  if (online && this_node->details->shutdown) {
1465  /* don't run resources here */
1466  this_node->fixed = TRUE;
1467  this_node->weight = -INFINITY;
1468  }
1469 
1470  if (this_node->details->type == node_ping) {
1471  crm_info("Node %s is not a pacemaker node", this_node->details->uname);
1472 
1473  } else if (this_node->details->unclean) {
1474  pe_proc_warn("Node %s is unclean", this_node->details->uname);
1475 
1476  } else if (this_node->details->online) {
1477  crm_info("Node %s is %s", this_node->details->uname,
1478  this_node->details->shutdown ? "shutting down" :
1479  this_node->details->pending ? "pending" :
1480  this_node->details->standby ? "standby" :
1481  this_node->details->maintenance ? "maintenance" : "online");
1482 
1483  } else {
1484  crm_trace("Node %s is offline", this_node->details->uname);
1485  }
1486 
1487  return online;
1488 }
1489 
1498 const char *
1499 pe_base_name_end(const char *id)
1500 {
1501  if (!crm_strlen_zero(id)) {
1502  const char *end = id + strlen(id) - 1;
1503 
1504  for (const char *s = end; s > id; --s) {
1505  switch (*s) {
1506  case '0':
1507  case '1':
1508  case '2':
1509  case '3':
1510  case '4':
1511  case '5':
1512  case '6':
1513  case '7':
1514  case '8':
1515  case '9':
1516  break;
1517  case ':':
1518  return (s == end)? s : (s - 1);
1519  default:
1520  return end;
1521  }
1522  }
1523  return end;
1524  }
1525  return NULL;
1526 }
1527 
1538 char *
1539 clone_strip(const char *last_rsc_id)
1540 {
1541  const char *end = pe_base_name_end(last_rsc_id);
1542  char *basename = NULL;
1543 
1544  CRM_ASSERT(end);
1545  basename = strndup(last_rsc_id, end - last_rsc_id + 1);
1546  CRM_ASSERT(basename);
1547  return basename;
1548 }
1549 
1560 char *
1561 clone_zero(const char *last_rsc_id)
1562 {
1563  const char *end = pe_base_name_end(last_rsc_id);
1564  size_t base_name_len = end - last_rsc_id + 1;
1565  char *zero = NULL;
1566 
1567  CRM_ASSERT(end);
1568  zero = calloc(base_name_len + 3, sizeof(char));
1569  CRM_ASSERT(zero);
1570  memcpy(zero, last_rsc_id, base_name_len);
1571  zero[base_name_len] = ':';
1572  zero[base_name_len + 1] = '0';
1573  return zero;
1574 }
1575 
1576 static resource_t *
1577 create_fake_resource(const char *rsc_id, xmlNode * rsc_entry, pe_working_set_t * data_set)
1578 {
1579  resource_t *rsc = NULL;
1580  xmlNode *xml_rsc = create_xml_node(NULL, XML_CIB_TAG_RESOURCE);
1581 
1582  copy_in_properties(xml_rsc, rsc_entry);
1583  crm_xml_add(xml_rsc, XML_ATTR_ID, rsc_id);
1584  crm_log_xml_debug(xml_rsc, "Orphan resource");
1585 
1586  if (!common_unpack(xml_rsc, &rsc, NULL, data_set)) {
1587  return NULL;
1588  }
1589 
1590  if (xml_contains_remote_node(xml_rsc)) {
1591  node_t *node;
1592 
1593  crm_debug("Detected orphaned remote node %s", rsc_id);
1594  node = pe_find_node(data_set->nodes, rsc_id);
1595  if (node == NULL) {
1596  node = pe_create_node(rsc_id, rsc_id, "remote", NULL, data_set);
1597  }
1598  link_rsc2remotenode(data_set, rsc);
1599 
1600  if (node) {
1601  crm_trace("Setting node %s as shutting down due to orphaned connection resource", rsc_id);
1602  node->details->shutdown = TRUE;
1603  }
1604  }
1605 
1606  if (crm_element_value(rsc_entry, XML_RSC_ATTR_CONTAINER)) {
1607  /* This orphaned rsc needs to be mapped to a container. */
1608  crm_trace("Detected orphaned container filler %s", rsc_id);
1610  }
1611  set_bit(rsc->flags, pe_rsc_orphan);
1612  data_set->resources = g_list_append(data_set->resources, rsc);
1613  return rsc;
1614 }
1615 
1620 static pe_resource_t *
1621 create_anonymous_orphan(pe_resource_t *parent, const char *rsc_id,
1622  pe_node_t *node, pe_working_set_t *data_set)
1623 {
1624  pe_resource_t *top = pe__create_clone_child(parent, data_set);
1625 
1626  // find_rsc() because we might be a cloned group
1627  pe_resource_t *orphan = top->fns->find_rsc(top, rsc_id, NULL, pe_find_clone);
1628 
1629  pe_rsc_debug(parent, "Created orphan %s for %s: %s on %s",
1630  top->id, parent->id, rsc_id, node->details->uname);
1631  return orphan;
1632 }
1633 
1648 static resource_t *
1649 find_anonymous_clone(pe_working_set_t * data_set, node_t * node, resource_t * parent,
1650  const char *rsc_id)
1651 {
1652  GListPtr rIter = NULL;
1653  pe_resource_t *rsc = NULL;
1654  pe_resource_t *inactive_instance = NULL;
1655  gboolean skip_inactive = FALSE;
1656 
1657  CRM_ASSERT(parent != NULL);
1658  CRM_ASSERT(pe_rsc_is_clone(parent));
1659  CRM_ASSERT(is_not_set(parent->flags, pe_rsc_unique));
1660 
1661  // Check for active (or partially active, for cloned groups) instance
1662  pe_rsc_trace(parent, "Looking for %s on %s in %s", rsc_id, node->details->uname, parent->id);
1663  for (rIter = parent->children; rsc == NULL && rIter; rIter = rIter->next) {
1664  GListPtr locations = NULL;
1665  resource_t *child = rIter->data;
1666 
1667  /* Check whether this instance is already known to be active or pending
1668  * anywhere, at this stage of unpacking. Because this function is called
1669  * for a resource before the resource's individual operation history
1670  * entries are unpacked, locations will generally not contain the
1671  * desired node.
1672  *
1673  * However, there are three exceptions:
1674  * (1) when child is a cloned group and we have already unpacked the
1675  * history of another member of the group on the same node;
1676  * (2) when we've already unpacked the history of another numbered
1677  * instance on the same node (which can happen if globally-unique
1678  * was flipped from true to false); and
1679  * (3) when we re-run calculations on the same data set as part of a
1680  * simulation.
1681  */
1682  child->fns->location(child, &locations, 2);
1683  if (locations) {
1684  /* We should never associate the same numbered anonymous clone
1685  * instance with multiple nodes, and clone instances can't migrate,
1686  * so there must be only one location, regardless of history.
1687  */
1688  CRM_LOG_ASSERT(locations->next == NULL);
1689 
1690  if (((pe_node_t *)locations->data)->details == node->details) {
1691  /* This child instance is active on the requested node, so check
1692  * for a corresponding configured resource. We use find_rsc()
1693  * instead of child because child may be a cloned group, and we
1694  * need the particular member corresponding to rsc_id.
1695  *
1696  * If the history entry is orphaned, rsc will be NULL.
1697  */
1698  rsc = parent->fns->find_rsc(child, rsc_id, NULL, pe_find_clone);
1699  if (rsc) {
1700  /* If there are multiple instance history entries for an
1701  * anonymous clone in a single node's history (which can
1702  * happen if globally-unique is switched from true to
1703  * false), we want to consider the instances beyond the
1704  * first as orphans, even if there are inactive instance
1705  * numbers available.
1706  */
1707  if (rsc->running_on) {
1708  crm_notice("Active (now-)anonymous clone %s has "
1709  "multiple (orphan) instance histories on %s",
1710  parent->id, node->details->uname);
1711  skip_inactive = TRUE;
1712  rsc = NULL;
1713  } else {
1714  pe_rsc_trace(parent, "Resource %s, active", rsc->id);
1715  }
1716  }
1717  }
1718  g_list_free(locations);
1719 
1720  } else {
1721  pe_rsc_trace(parent, "Resource %s, skip inactive", child->id);
1722  if (!skip_inactive && !inactive_instance
1723  && is_not_set(child->flags, pe_rsc_block)) {
1724  // Remember one inactive instance in case we don't find active
1725  inactive_instance = parent->fns->find_rsc(child, rsc_id, NULL,
1726  pe_find_clone);
1727 
1728  /* ... but don't use it if it was already associated with a
1729  * pending action on another node
1730  */
1731  if (inactive_instance && inactive_instance->pending_node
1732  && (inactive_instance->pending_node->details != node->details)) {
1733  inactive_instance = NULL;
1734  }
1735  }
1736  }
1737  }
1738 
1739  if ((rsc == NULL) && !skip_inactive && (inactive_instance != NULL)) {
1740  pe_rsc_trace(parent, "Resource %s, empty slot", inactive_instance->id);
1741  rsc = inactive_instance;
1742  }
1743 
1744  /* If the resource has "requires" set to "quorum" or "nothing", and we don't
1745  * have a clone instance for every node, we don't want to consume a valid
1746  * instance number for unclean nodes. Such instances may appear to be active
1747  * according to the history, but should be considered inactive, so we can
1748  * start an instance elsewhere. Treat such instances as orphans.
1749  *
1750  * An exception is instances running on guest nodes -- since guest node
1751  * "fencing" is actually just a resource stop, requires shouldn't apply.
1752  *
1753  * @TODO Ideally, we'd use an inactive instance number if it is not needed
1754  * for any clean instances. However, we don't know that at this point.
1755  */
1756  if ((rsc != NULL) && is_not_set(rsc->flags, pe_rsc_needs_fencing)
1757  && (!node->details->online || node->details->unclean)
1758  && !pe__is_guest_node(node)
1759  && !pe__is_universal_clone(parent, data_set)) {
1760 
1761  rsc = NULL;
1762  }
1763 
1764  if (rsc == NULL) {
1765  rsc = create_anonymous_orphan(parent, rsc_id, node, data_set);
1766  pe_rsc_trace(parent, "Resource %s, orphan", rsc->id);
1767  }
1768  return rsc;
1769 }
1770 
1771 static resource_t *
1772 unpack_find_resource(pe_working_set_t * data_set, node_t * node, const char *rsc_id,
1773  xmlNode * rsc_entry)
1774 {
1775  resource_t *rsc = NULL;
1776  resource_t *parent = NULL;
1777 
1778  crm_trace("looking for %s", rsc_id);
1779  rsc = pe_find_resource(data_set->resources, rsc_id);
1780 
1781  if (rsc == NULL) {
1782  /* If we didn't find the resource by its name in the operation history,
1783  * check it again as a clone instance. Even when clone-max=0, we create
1784  * a single :0 orphan to match against here.
1785  */
1786  char *clone0_id = clone_zero(rsc_id);
1787  resource_t *clone0 = pe_find_resource(data_set->resources, clone0_id);
1788 
1789  if (clone0 && is_not_set(clone0->flags, pe_rsc_unique)) {
1790  rsc = clone0;
1791  parent = uber_parent(clone0);
1792  crm_trace("%s found as %s (%s)", rsc_id, clone0_id, parent->id);
1793  } else {
1794  crm_trace("%s is not known as %s either (orphan)",
1795  rsc_id, clone0_id);
1796  }
1797  free(clone0_id);
1798 
1799  } else if (rsc->variant > pe_native) {
1800  crm_trace("Resource history for %s is orphaned because it is no longer primitive",
1801  rsc_id);
1802  return NULL;
1803 
1804  } else {
1805  parent = uber_parent(rsc);
1806  }
1807 
1808  if (pe_rsc_is_anon_clone(parent)) {
1809 
1810  if (pe_rsc_is_bundled(parent)) {
1811  rsc = pe__find_bundle_replica(parent->parent, node);
1812  } else {
1813  char *base = clone_strip(rsc_id);
1814 
1815  rsc = find_anonymous_clone(data_set, node, parent, base);
1816  free(base);
1817  CRM_ASSERT(rsc != NULL);
1818  }
1819  }
1820 
1821  if (rsc && safe_str_neq(rsc_id, rsc->id)
1822  && safe_str_neq(rsc_id, rsc->clone_name)) {
1823 
1824  free(rsc->clone_name);
1825  rsc->clone_name = strdup(rsc_id);
1826  pe_rsc_debug(rsc, "Internally renamed %s on %s to %s%s",
1827  rsc_id, node->details->uname, rsc->id,
1828  (is_set(rsc->flags, pe_rsc_orphan)? " (ORPHAN)" : ""));
1829  }
1830  return rsc;
1831 }
1832 
1833 static resource_t *
1834 process_orphan_resource(xmlNode * rsc_entry, node_t * node, pe_working_set_t * data_set)
1835 {
1836  resource_t *rsc = NULL;
1837  const char *rsc_id = crm_element_value(rsc_entry, XML_ATTR_ID);
1838 
1839  crm_debug("Detected orphan resource %s on %s", rsc_id, node->details->uname);
1840  rsc = create_fake_resource(rsc_id, rsc_entry, data_set);
1841 
1842  if (is_set(data_set->flags, pe_flag_stop_rsc_orphans) == FALSE) {
1844 
1845  } else {
1846  CRM_CHECK(rsc != NULL, return NULL);
1847  pe_rsc_trace(rsc, "Added orphan %s", rsc->id);
1848  resource_location(rsc, NULL, -INFINITY, "__orphan_do_not_run__", data_set);
1849  }
1850  return rsc;
1851 }
1852 
1853 static void
1854 process_rsc_state(resource_t * rsc, node_t * node,
1855  enum action_fail_response on_fail,
1856  xmlNode * migrate_op, pe_working_set_t * data_set)
1857 {
1858  node_t *tmpnode = NULL;
1859  char *reason = NULL;
1860 
1861  CRM_ASSERT(rsc);
1862  pe_rsc_trace(rsc, "Resource %s is %s on %s: on_fail=%s",
1863  rsc->id, role2text(rsc->role), node->details->uname, fail2text(on_fail));
1864 
1865  /* process current state */
1866  if (rsc->role != RSC_ROLE_UNKNOWN) {
1867  resource_t *iter = rsc;
1868 
1869  while (iter) {
1870  if (g_hash_table_lookup(iter->known_on, node->details->id) == NULL) {
1871  node_t *n = node_copy(node);
1872 
1873  pe_rsc_trace(rsc, "%s (aka. %s) known on %s", rsc->id, rsc->clone_name,
1874  n->details->uname);
1875  g_hash_table_insert(iter->known_on, (gpointer) n->details->id, n);
1876  }
1877  if (is_set(iter->flags, pe_rsc_unique)) {
1878  break;
1879  }
1880  iter = iter->parent;
1881  }
1882  }
1883 
1884  /* If a managed resource is believed to be running, but node is down ... */
1885  if (rsc->role > RSC_ROLE_STOPPED
1886  && node->details->online == FALSE
1887  && node->details->maintenance == FALSE
1888  && is_set(rsc->flags, pe_rsc_managed)) {
1889 
1890  gboolean should_fence = FALSE;
1891 
1892  /* If this is a guest node, fence it (regardless of whether fencing is
1893  * enabled, because guest node fencing is done by recovery of the
1894  * container resource rather than by the fencer). Mark the resource
1895  * we're processing as failed. When the guest comes back up, its
1896  * operation history in the CIB will be cleared, freeing the affected
1897  * resource to run again once we are sure we know its state.
1898  */
1899  if (pe__is_guest_node(node)) {
1900  set_bit(rsc->flags, pe_rsc_failed);
1901  should_fence = TRUE;
1902 
1903  } else if (is_set(data_set->flags, pe_flag_stonith_enabled)) {
1904  if (pe__is_remote_node(node) && node->details->remote_rsc
1905  && is_not_set(node->details->remote_rsc->flags, pe_rsc_failed)) {
1906 
1907  /* Setting unseen means that fencing of the remote node will
1908  * occur only if the connection resource is not going to start
1909  * somewhere. This allows connection resources on a failed
1910  * cluster node to move to another node without requiring the
1911  * remote nodes to be fenced as well.
1912  */
1913  node->details->unseen = TRUE;
1914  reason = crm_strdup_printf("%s is active there (fencing will be"
1915  " revoked if remote connection can "
1916  "be re-established elsewhere)",
1917  rsc->id);
1918  }
1919  should_fence = TRUE;
1920  }
1921 
1922  if (should_fence) {
1923  if (reason == NULL) {
1924  reason = crm_strdup_printf("%s is thought to be active there", rsc->id);
1925  }
1926  pe_fence_node(data_set, node, reason);
1927  }
1928  free(reason);
1929  }
1930 
1931  if (node->details->unclean) {
1932  /* No extra processing needed
1933  * Also allows resources to be started again after a node is shot
1934  */
1935  on_fail = action_fail_ignore;
1936  }
1937 
1938  switch (on_fail) {
1939  case action_fail_ignore:
1940  /* nothing to do */
1941  break;
1942 
1943  case action_fail_fence:
1944  /* treat it as if it is still running
1945  * but also mark the node as unclean
1946  */
1947  reason = crm_strdup_printf("%s failed there", rsc->id);
1948  pe_fence_node(data_set, node, reason);
1949  free(reason);
1950  break;
1951 
1952  case action_fail_standby:
1953  node->details->standby = TRUE;
1954  node->details->standby_onfail = TRUE;
1955  break;
1956 
1957  case action_fail_block:
1958  /* is_managed == FALSE will prevent any
1959  * actions being sent for the resource
1960  */
1962  set_bit(rsc->flags, pe_rsc_block);
1963  break;
1964 
1965  case action_fail_migrate:
1966  /* make sure it comes up somewhere else
1967  * or not at all
1968  */
1969  resource_location(rsc, node, -INFINITY, "__action_migration_auto__", data_set);
1970  break;
1971 
1972  case action_fail_stop:
1973  rsc->next_role = RSC_ROLE_STOPPED;
1974  break;
1975 
1976  case action_fail_recover:
1977  if (rsc->role != RSC_ROLE_STOPPED && rsc->role != RSC_ROLE_UNKNOWN) {
1978  set_bit(rsc->flags, pe_rsc_failed);
1979  stop_action(rsc, node, FALSE);
1980  }
1981  break;
1982 
1984  set_bit(rsc->flags, pe_rsc_failed);
1985 
1986  if (rsc->container && pe_rsc_is_bundled(rsc)) {
1987  /* A bundle's remote connection can run on a different node than
1988  * the bundle's container. We don't necessarily know where the
1989  * container is running yet, so remember it and add a stop
1990  * action for it later.
1991  */
1992  data_set->stop_needed = g_list_prepend(data_set->stop_needed,
1993  rsc->container);
1994  } else if (rsc->container) {
1995  stop_action(rsc->container, node, FALSE);
1996  } else if (rsc->role != RSC_ROLE_STOPPED && rsc->role != RSC_ROLE_UNKNOWN) {
1997  stop_action(rsc, node, FALSE);
1998  }
1999  break;
2000 
2002  set_bit(rsc->flags, pe_rsc_failed);
2003  if (is_set(data_set->flags, pe_flag_stonith_enabled)) {
2004  tmpnode = NULL;
2005  if (rsc->is_remote_node) {
2006  tmpnode = pe_find_node(data_set->nodes, rsc->id);
2007  }
2008  if (tmpnode &&
2009  pe__is_remote_node(tmpnode) &&
2010  tmpnode->details->remote_was_fenced == 0) {
2011 
2012  /* The remote connection resource failed in a way that
2013  * should result in fencing the remote node.
2014  */
2015  pe_fence_node(data_set, tmpnode,
2016  "remote connection is unrecoverable");
2017  }
2018  }
2019 
2020  /* require the stop action regardless if fencing is occurring or not. */
2021  if (rsc->role > RSC_ROLE_STOPPED) {
2022  stop_action(rsc, node, FALSE);
2023  }
2024 
2025  /* if reconnect delay is in use, prevent the connection from exiting the
2026  * "STOPPED" role until the failure is cleared by the delay timeout. */
2027  if (rsc->remote_reconnect_ms) {
2028  rsc->next_role = RSC_ROLE_STOPPED;
2029  }
2030  break;
2031  }
2032 
2033  /* ensure a remote-node connection failure forces an unclean remote-node
2034  * to be fenced. By setting unseen = FALSE, the remote-node failure will
2035  * result in a fencing operation regardless if we're going to attempt to
2036  * reconnect to the remote-node in this transition or not. */
2037  if (is_set(rsc->flags, pe_rsc_failed) && rsc->is_remote_node) {
2038  tmpnode = pe_find_node(data_set->nodes, rsc->id);
2039  if (tmpnode && tmpnode->details->unclean) {
2040  tmpnode->details->unseen = FALSE;
2041  }
2042  }
2043 
2044  if (rsc->role != RSC_ROLE_STOPPED && rsc->role != RSC_ROLE_UNKNOWN) {
2045  if (is_set(rsc->flags, pe_rsc_orphan)) {
2046  if (is_set(rsc->flags, pe_rsc_managed)) {
2047  crm_config_warn("Detected active orphan %s running on %s",
2048  rsc->id, node->details->uname);
2049  } else {
2050  crm_config_warn("Cluster configured not to stop active orphans."
2051  " %s must be stopped manually on %s",
2052  rsc->id, node->details->uname);
2053  }
2054  }
2055 
2056  native_add_running(rsc, node, data_set);
2057  if (on_fail != action_fail_ignore) {
2058  set_bit(rsc->flags, pe_rsc_failed);
2059  }
2060 
2061  } else if (rsc->clone_name && strchr(rsc->clone_name, ':') != NULL) {
2062  /* Only do this for older status sections that included instance numbers
2063  * Otherwise stopped instances will appear as orphans
2064  */
2065  pe_rsc_trace(rsc, "Resetting clone_name %s for %s (stopped)", rsc->clone_name, rsc->id);
2066  free(rsc->clone_name);
2067  rsc->clone_name = NULL;
2068 
2069  } else {
2070  GList *possible_matches = pe__resource_actions(rsc, node, RSC_STOP,
2071  FALSE);
2072  GListPtr gIter = possible_matches;
2073 
2074  for (; gIter != NULL; gIter = gIter->next) {
2075  action_t *stop = (action_t *) gIter->data;
2076 
2077  stop->flags |= pe_action_optional;
2078  }
2079 
2080  g_list_free(possible_matches);
2081  }
2082 }
2083 
2084 /* create active recurring operations as optional */
2085 static void
2086 process_recurring(node_t * node, resource_t * rsc,
2087  int start_index, int stop_index,
2088  GListPtr sorted_op_list, pe_working_set_t * data_set)
2089 {
2090  int counter = -1;
2091  const char *task = NULL;
2092  const char *status = NULL;
2093  GListPtr gIter = sorted_op_list;
2094 
2095  CRM_ASSERT(rsc);
2096  pe_rsc_trace(rsc, "%s: Start index %d, stop index = %d", rsc->id, start_index, stop_index);
2097 
2098  for (; gIter != NULL; gIter = gIter->next) {
2099  xmlNode *rsc_op = (xmlNode *) gIter->data;
2100 
2101  guint interval_ms = 0;
2102  char *key = NULL;
2103  const char *id = ID(rsc_op);
2104  const char *interval_ms_s = NULL;
2105 
2106  counter++;
2107 
2108  if (node->details->online == FALSE) {
2109  pe_rsc_trace(rsc, "Skipping %s/%s: node is offline", rsc->id, node->details->uname);
2110  break;
2111 
2112  /* Need to check if there's a monitor for role="Stopped" */
2113  } else if (start_index < stop_index && counter <= stop_index) {
2114  pe_rsc_trace(rsc, "Skipping %s/%s: resource is not active", id, node->details->uname);
2115  continue;
2116 
2117  } else if (counter < start_index) {
2118  pe_rsc_trace(rsc, "Skipping %s/%s: old %d", id, node->details->uname, counter);
2119  continue;
2120  }
2121 
2122  interval_ms_s = crm_element_value(rsc_op, XML_LRM_ATTR_INTERVAL_MS);
2123  interval_ms = crm_parse_ms(interval_ms_s);
2124  if (interval_ms == 0) {
2125  pe_rsc_trace(rsc, "Skipping %s/%s: non-recurring", id, node->details->uname);
2126  continue;
2127  }
2128 
2129  status = crm_element_value(rsc_op, XML_LRM_ATTR_OPSTATUS);
2130  if (safe_str_eq(status, "-1")) {
2131  pe_rsc_trace(rsc, "Skipping %s/%s: status", id, node->details->uname);
2132  continue;
2133  }
2134  task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK);
2135  /* create the action */
2136  key = generate_op_key(rsc->id, task, interval_ms);
2137  pe_rsc_trace(rsc, "Creating %s/%s", key, node->details->uname);
2138  custom_action(rsc, key, task, node, TRUE, TRUE, data_set);
2139  }
2140 }
2141 
2142 void
2143 calculate_active_ops(GListPtr sorted_op_list, int *start_index, int *stop_index)
2144 {
2145  int counter = -1;
2146  int implied_monitor_start = -1;
2147  int implied_clone_start = -1;
2148  const char *task = NULL;
2149  const char *status = NULL;
2150  GListPtr gIter = sorted_op_list;
2151 
2152  *stop_index = -1;
2153  *start_index = -1;
2154 
2155  for (; gIter != NULL; gIter = gIter->next) {
2156  xmlNode *rsc_op = (xmlNode *) gIter->data;
2157 
2158  counter++;
2159 
2160  task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK);
2161  status = crm_element_value(rsc_op, XML_LRM_ATTR_OPSTATUS);
2162 
2163  if (safe_str_eq(task, CRMD_ACTION_STOP)
2164  && safe_str_eq(status, "0")) {
2165  *stop_index = counter;
2166 
2167  } else if (safe_str_eq(task, CRMD_ACTION_START) || safe_str_eq(task, CRMD_ACTION_MIGRATED)) {
2168  *start_index = counter;
2169 
2170  } else if ((implied_monitor_start <= *stop_index) && safe_str_eq(task, CRMD_ACTION_STATUS)) {
2171  const char *rc = crm_element_value(rsc_op, XML_LRM_ATTR_RC);
2172 
2173  if (safe_str_eq(rc, "0") || safe_str_eq(rc, "8")) {
2174  implied_monitor_start = counter;
2175  }
2176  } else if (safe_str_eq(task, CRMD_ACTION_PROMOTE) || safe_str_eq(task, CRMD_ACTION_DEMOTE)) {
2177  implied_clone_start = counter;
2178  }
2179  }
2180 
2181  if (*start_index == -1) {
2182  if (implied_clone_start != -1) {
2183  *start_index = implied_clone_start;
2184  } else if (implied_monitor_start != -1) {
2185  *start_index = implied_monitor_start;
2186  }
2187  }
2188 }
2189 
2190 static resource_t *
2191 unpack_lrm_rsc_state(node_t * node, xmlNode * rsc_entry, pe_working_set_t * data_set)
2192 {
2193  GListPtr gIter = NULL;
2194  int stop_index = -1;
2195  int start_index = -1;
2196  enum rsc_role_e req_role = RSC_ROLE_UNKNOWN;
2197 
2198  const char *task = NULL;
2199  const char *rsc_id = crm_element_value(rsc_entry, XML_ATTR_ID);
2200 
2201  resource_t *rsc = NULL;
2202  GListPtr op_list = NULL;
2203  GListPtr sorted_op_list = NULL;
2204 
2205  xmlNode *migrate_op = NULL;
2206  xmlNode *rsc_op = NULL;
2207  xmlNode *last_failure = NULL;
2208 
2209  enum action_fail_response on_fail = FALSE;
2210  enum rsc_role_e saved_role = RSC_ROLE_UNKNOWN;
2211 
2212  crm_trace("[%s] Processing %s on %s",
2213  crm_element_name(rsc_entry), rsc_id, node->details->uname);
2214 
2215  /* extract operations */
2216  op_list = NULL;
2217  sorted_op_list = NULL;
2218 
2219  for (rsc_op = __xml_first_child_element(rsc_entry); rsc_op != NULL;
2220  rsc_op = __xml_next_element(rsc_op)) {
2221  if (crm_str_eq((const char *)rsc_op->name, XML_LRM_TAG_RSC_OP, TRUE)) {
2222  op_list = g_list_prepend(op_list, rsc_op);
2223  }
2224  }
2225 
2226  if (op_list == NULL) {
2227  /* if there are no operations, there is nothing to do */
2228  return NULL;
2229  }
2230 
2231  /* find the resource */
2232  rsc = unpack_find_resource(data_set, node, rsc_id, rsc_entry);
2233  if (rsc == NULL) {
2234  rsc = process_orphan_resource(rsc_entry, node, data_set);
2235  }
2236  CRM_ASSERT(rsc != NULL);
2237 
2238  /* process operations */
2239  saved_role = rsc->role;
2240  on_fail = action_fail_ignore;
2241  rsc->role = RSC_ROLE_UNKNOWN;
2242  sorted_op_list = g_list_sort(op_list, sort_op_by_callid);
2243 
2244  for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) {
2245  xmlNode *rsc_op = (xmlNode *) gIter->data;
2246 
2247  task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK);
2248  if (safe_str_eq(task, CRMD_ACTION_MIGRATED)) {
2249  migrate_op = rsc_op;
2250  }
2251 
2252  unpack_rsc_op(rsc, node, rsc_op, &last_failure, &on_fail, data_set);
2253  }
2254 
2255  /* create active recurring operations as optional */
2256  calculate_active_ops(sorted_op_list, &start_index, &stop_index);
2257  process_recurring(node, rsc, start_index, stop_index, sorted_op_list, data_set);
2258 
2259  /* no need to free the contents */
2260  g_list_free(sorted_op_list);
2261 
2262  process_rsc_state(rsc, node, on_fail, migrate_op, data_set);
2263 
2264  if (get_target_role(rsc, &req_role)) {
2265  if (rsc->next_role == RSC_ROLE_UNKNOWN || req_role < rsc->next_role) {
2266  pe_rsc_debug(rsc, "%s: Overwriting calculated next role %s"
2267  " with requested next role %s",
2268  rsc->id, role2text(rsc->next_role), role2text(req_role));
2269  rsc->next_role = req_role;
2270 
2271  } else if (req_role > rsc->next_role) {
2272  pe_rsc_info(rsc, "%s: Not overwriting calculated next role %s"
2273  " with requested next role %s",
2274  rsc->id, role2text(rsc->next_role), role2text(req_role));
2275  }
2276  }
2277 
2278  if (saved_role > rsc->role) {
2279  rsc->role = saved_role;
2280  }
2281 
2282  return rsc;
2283 }
2284 
2285 static void
2286 handle_orphaned_container_fillers(xmlNode * lrm_rsc_list, pe_working_set_t * data_set)
2287 {
2288  xmlNode *rsc_entry = NULL;
2289  for (rsc_entry = __xml_first_child_element(lrm_rsc_list); rsc_entry != NULL;
2290  rsc_entry = __xml_next_element(rsc_entry)) {
2291 
2292  resource_t *rsc;
2293  resource_t *container;
2294  const char *rsc_id;
2295  const char *container_id;
2296 
2297  if (safe_str_neq((const char *)rsc_entry->name, XML_LRM_TAG_RESOURCE)) {
2298  continue;
2299  }
2300 
2301  container_id = crm_element_value(rsc_entry, XML_RSC_ATTR_CONTAINER);
2302  rsc_id = crm_element_value(rsc_entry, XML_ATTR_ID);
2303  if (container_id == NULL || rsc_id == NULL) {
2304  continue;
2305  }
2306 
2307  container = pe_find_resource(data_set->resources, container_id);
2308  if (container == NULL) {
2309  continue;
2310  }
2311 
2312  rsc = pe_find_resource(data_set->resources, rsc_id);
2313  if (rsc == NULL ||
2314  is_set(rsc->flags, pe_rsc_orphan_container_filler) == FALSE ||
2315  rsc->container != NULL) {
2316  continue;
2317  }
2318 
2319  pe_rsc_trace(rsc, "Mapped container of orphaned resource %s to %s",
2320  rsc->id, container_id);
2321  rsc->container = container;
2322  container->fillers = g_list_append(container->fillers, rsc);
2323  }
2324 }
2325 
2326 gboolean
2327 unpack_lrm_resources(node_t * node, xmlNode * lrm_rsc_list, pe_working_set_t * data_set)
2328 {
2329  xmlNode *rsc_entry = NULL;
2330  gboolean found_orphaned_container_filler = FALSE;
2331 
2332  CRM_CHECK(node != NULL, return FALSE);
2333 
2334  crm_trace("Unpacking resources on %s", node->details->uname);
2335 
2336  for (rsc_entry = __xml_first_child_element(lrm_rsc_list); rsc_entry != NULL;
2337  rsc_entry = __xml_next_element(rsc_entry)) {
2338 
2339  if (crm_str_eq((const char *)rsc_entry->name, XML_LRM_TAG_RESOURCE, TRUE)) {
2340  resource_t *rsc = unpack_lrm_rsc_state(node, rsc_entry, data_set);
2341  if (!rsc) {
2342  continue;
2343  }
2344  if (is_set(rsc->flags, pe_rsc_orphan_container_filler)) {
2345  found_orphaned_container_filler = TRUE;
2346  }
2347  }
2348  }
2349 
2350  /* now that all the resource state has been unpacked for this node
2351  * we have to go back and map any orphaned container fillers to their
2352  * container resource */
2353  if (found_orphaned_container_filler) {
2354  handle_orphaned_container_fillers(lrm_rsc_list, data_set);
2355  }
2356  return TRUE;
2357 }
2358 
2359 static void
2360 set_active(resource_t * rsc)
2361 {
2362  resource_t *top = uber_parent(rsc);
2363 
2364  if (top && is_set(top->flags, pe_rsc_promotable)) {
2365  rsc->role = RSC_ROLE_SLAVE;
2366  } else {
2367  rsc->role = RSC_ROLE_STARTED;
2368  }
2369 }
2370 
2371 static void
2372 set_node_score(gpointer key, gpointer value, gpointer user_data)
2373 {
2374  node_t *node = value;
2375  int *score = user_data;
2376 
2377  node->weight = *score;
2378 }
2379 
2380 #define STATUS_PATH_MAX 1024
2381 static xmlNode *
2382 find_lrm_op(const char *resource, const char *op, const char *node, const char *source,
2383  bool success_only, pe_working_set_t *data_set)
2384 {
2385  int offset = 0;
2386  char xpath[STATUS_PATH_MAX];
2387  xmlNode *xml = NULL;
2388 
2389  offset += snprintf(xpath + offset, STATUS_PATH_MAX - offset, "//node_state[@uname='%s']", node);
2390  offset +=
2391  snprintf(xpath + offset, STATUS_PATH_MAX - offset, "//" XML_LRM_TAG_RESOURCE "[@id='%s']",
2392  resource);
2393 
2394  /* Need to check against transition_magic too? */
2395  if (source && safe_str_eq(op, CRMD_ACTION_MIGRATE)) {
2396  offset +=
2397  snprintf(xpath + offset, STATUS_PATH_MAX - offset,
2398  "/" XML_LRM_TAG_RSC_OP "[@operation='%s' and @migrate_target='%s']", op,
2399  source);
2400  } else if (source && safe_str_eq(op, CRMD_ACTION_MIGRATED)) {
2401  offset +=
2402  snprintf(xpath + offset, STATUS_PATH_MAX - offset,
2403  "/" XML_LRM_TAG_RSC_OP "[@operation='%s' and @migrate_source='%s']", op,
2404  source);
2405  } else {
2406  offset +=
2407  snprintf(xpath + offset, STATUS_PATH_MAX - offset,
2408  "/" XML_LRM_TAG_RSC_OP "[@operation='%s']", op);
2409  }
2410 
2411  CRM_LOG_ASSERT(offset > 0);
2412  xml = get_xpath_object(xpath, data_set->input, LOG_DEBUG);
2413 
2414  if (xml && success_only) {
2415  int rc = PCMK_OCF_UNKNOWN_ERROR;
2416  int status = PCMK_LRM_OP_ERROR;
2417 
2420  if ((rc != PCMK_OCF_OK) || (status != PCMK_LRM_OP_DONE)) {
2421  return NULL;
2422  }
2423  }
2424  return xml;
2425 }
2426 
2427 static int
2428 pe__call_id(xmlNode *op_xml)
2429 {
2430  int id = 0;
2431 
2432  if (op_xml) {
2434  }
2435  return id;
2436 }
2437 
2454 static bool
2455 stop_happened_after(pe_resource_t *rsc, pe_node_t *node, xmlNode *xml_op,
2456  pe_working_set_t *data_set)
2457 {
2458  xmlNode *stop_op = find_lrm_op(rsc->id, CRMD_ACTION_STOP,
2459  node->details->uname, NULL, TRUE, data_set);
2460 
2461  return (stop_op && (pe__call_id(stop_op) > pe__call_id(xml_op)));
2462 }
2463 
2464 static void
2465 unpack_migrate_to_success(pe_resource_t *rsc, pe_node_t *node, xmlNode *xml_op,
2466  pe_working_set_t *data_set)
2467 {
2468  /* A successful migration sequence is:
2469  * migrate_to on source node
2470  * migrate_from on target node
2471  * stop on source node
2472  *
2473  * If a migrate_to is followed by a stop, the entire migration (successful
2474  * or failed) is complete, and we don't care what happened on the target.
2475  *
2476  * If no migrate_from has happened, the migration is considered to be
2477  * "partial". If the migrate_from failed, make sure the resource gets
2478  * stopped on both source and target (if up).
2479  *
2480  * If the migrate_to and migrate_from both succeeded (which also implies the
2481  * resource is no longer running on the source), but there is no stop, the
2482  * migration is considered to be "dangling". Schedule a stop on the source
2483  * in this case.
2484  */
2485  int from_rc = 0;
2486  int from_status = 0;
2487  pe_node_t *target_node = NULL;
2488  pe_node_t *source_node = NULL;
2489  xmlNode *migrate_from = NULL;
2490  const char *source = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_SOURCE);
2491  const char *target = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_TARGET);
2492 
2493  // Sanity check
2494  CRM_CHECK(source && target && !strcmp(source, node->details->uname), return);
2495 
2496  if (stop_happened_after(rsc, node, xml_op, data_set)) {
2497  return;
2498  }
2499 
2500  // Clones are not allowed to migrate, so role can't be master
2501  rsc->role = RSC_ROLE_STARTED;
2502 
2503  target_node = pe_find_node(data_set->nodes, target);
2504  source_node = pe_find_node(data_set->nodes, source);
2505 
2506  // Check whether there was a migrate_from action on the target
2507  migrate_from = find_lrm_op(rsc->id, CRMD_ACTION_MIGRATED, target,
2508  source, FALSE, data_set);
2509  if (migrate_from) {
2510  crm_element_value_int(migrate_from, XML_LRM_ATTR_RC, &from_rc);
2511  crm_element_value_int(migrate_from, XML_LRM_ATTR_OPSTATUS, &from_status);
2512  pe_rsc_trace(rsc, "%s op on %s exited with status=%d, rc=%d",
2513  ID(migrate_from), target, from_status, from_rc);
2514  }
2515 
2516  if (migrate_from && from_rc == PCMK_OCF_OK
2517  && from_status == PCMK_LRM_OP_DONE) {
2518  /* The migrate_to and migrate_from both succeeded, so mark the migration
2519  * as "dangling". This will be used to schedule a stop action on the
2520  * source without affecting the target.
2521  */
2522  pe_rsc_trace(rsc, "Detected dangling migration op: %s on %s", ID(xml_op),
2523  source);
2524  rsc->role = RSC_ROLE_STOPPED;
2525  rsc->dangling_migrations = g_list_prepend(rsc->dangling_migrations, node);
2526 
2527  } else if (migrate_from && (from_status != PCMK_LRM_OP_PENDING)) { // Failed
2528  if (target_node && target_node->details->online) {
2529  pe_rsc_trace(rsc, "Marking active on %s %p %d", target, target_node,
2530  target_node->details->online);
2531  native_add_running(rsc, target_node, data_set);
2532  }
2533 
2534  } else { // Pending, or complete but erased
2535  if (target_node && target_node->details->online) {
2536  pe_rsc_trace(rsc, "Marking active on %s %p %d", target, target_node,
2537  target_node->details->online);
2538 
2539  native_add_running(rsc, target_node, data_set);
2540  if (source_node && source_node->details->online) {
2541  /* This is a partial migration: the migrate_to completed
2542  * successfully on the source, but the migrate_from has not
2543  * completed. Remember the source and target; if the newly
2544  * chosen target remains the same when we schedule actions
2545  * later, we may continue with the migration.
2546  */
2547  rsc->partial_migration_target = target_node;
2548  rsc->partial_migration_source = source_node;
2549  }
2550  } else {
2551  /* Consider it failed here - forces a restart, prevents migration */
2552  set_bit(rsc->flags, pe_rsc_failed);
2554  }
2555  }
2556 }
2557 
2558 static void
2559 unpack_migrate_to_failure(pe_resource_t *rsc, pe_node_t *node, xmlNode *xml_op,
2560  pe_working_set_t *data_set)
2561 {
2562  int target_stop_id = 0;
2563  int target_migrate_from_id = 0;
2564  xmlNode *target_stop = NULL;
2565  xmlNode *target_migrate_from = NULL;
2566  const char *source = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_SOURCE);
2567  const char *target = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_TARGET);
2568 
2569  // Sanity check
2570  CRM_CHECK(source && target && !strcmp(source, node->details->uname), return);
2571 
2572  /* If a migration failed, we have to assume the resource is active. Clones
2573  * are not allowed to migrate, so role can't be master.
2574  */
2575  rsc->role = RSC_ROLE_STARTED;
2576 
2577  // Check for stop on the target
2578  target_stop = find_lrm_op(rsc->id, CRMD_ACTION_STOP, target, NULL,
2579  TRUE, data_set);
2580  target_stop_id = pe__call_id(target_stop);
2581 
2582  // Check for migrate_from on the target
2583  target_migrate_from = find_lrm_op(rsc->id, CRMD_ACTION_MIGRATED, target,
2584  source, TRUE, data_set);
2585  target_migrate_from_id = pe__call_id(target_migrate_from);
2586 
2587  if ((target_stop == NULL) || (target_stop_id < target_migrate_from_id)) {
2588  /* There was no stop on the source, or a stop that happened before a
2589  * migrate_from, so assume the resource is still active on the target
2590  * (if it is up).
2591  */
2592  node_t *target_node = pe_find_node(data_set->nodes, target);
2593 
2594  pe_rsc_trace(rsc, "stop (%d) + migrate_from (%d)",
2595  target_stop_id, target_migrate_from_id);
2596  if (target_node && target_node->details->online) {
2597  native_add_running(rsc, target_node, data_set);
2598  }
2599 
2600  } else if (target_migrate_from == NULL) {
2601  /* We know there was a stop on the target, but there may not have been a
2602  * migrate_from (the stop could have happened before migrate_from was
2603  * scheduled or attempted).
2604  *
2605  * That means this could be a "dangling" migration. But first, check
2606  * whether there is a newer migrate_from or start on the source node --
2607  * it's possible the failed migration was followed by a successful
2608  * full restart or migration in the reverse direction, in which case we
2609  * don't want to force it to stop.
2610  */
2611  xmlNode *source_migrate_from = NULL;
2612  xmlNode *source_start = NULL;
2613  int source_migrate_to_id = pe__call_id(xml_op);
2614 
2615  source_migrate_from = find_lrm_op(rsc->id, CRMD_ACTION_MIGRATED, source,
2616  NULL, TRUE, data_set);
2617  if (pe__call_id(source_migrate_from) > source_migrate_to_id) {
2618  return;
2619  }
2620 
2621  source_start = find_lrm_op(rsc->id, CRMD_ACTION_START, source, NULL,
2622  TRUE, data_set);
2623  if (pe__call_id(source_start) > source_migrate_to_id) {
2624  return;
2625  }
2626 
2627  // Mark node as having dangling migration so we can force a stop later
2628  rsc->dangling_migrations = g_list_prepend(rsc->dangling_migrations, node);
2629  }
2630 }
2631 
2632 static void
2633 unpack_migrate_from_failure(pe_resource_t *rsc, pe_node_t *node,
2634  xmlNode *xml_op, pe_working_set_t *data_set)
2635 {
2636  xmlNode *source_stop = NULL;
2637  xmlNode *source_migrate_to = NULL;
2638  const char *source = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_SOURCE);
2639  const char *target = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_TARGET);
2640 
2641  // Sanity check
2642  CRM_CHECK(source && target && !strcmp(target, node->details->uname), return);
2643 
2644  /* If a migration failed, we have to assume the resource is active. Clones
2645  * are not allowed to migrate, so role can't be master.
2646  */
2647  rsc->role = RSC_ROLE_STARTED;
2648 
2649  // Check for a stop on the source
2650  source_stop = find_lrm_op(rsc->id, CRMD_ACTION_STOP, source, NULL,
2651  TRUE, data_set);
2652 
2653  // Check for a migrate_to on the source
2654  source_migrate_to = find_lrm_op(rsc->id, CRMD_ACTION_MIGRATE,
2655  source, target, TRUE, data_set);
2656 
2657  if ((source_stop == NULL)
2658  || (pe__call_id(source_stop) < pe__call_id(source_migrate_to))) {
2659  /* There was no stop on the source, or a stop that happened before
2660  * migrate_to, so assume the resource is still active on the source (if
2661  * it is up).
2662  */
2663  pe_node_t *source_node = pe_find_node(data_set->nodes, source);
2664 
2665  if (source_node && source_node->details->online) {
2666  native_add_running(rsc, source_node, data_set);
2667  }
2668  }
2669 }
2670 
2671 static void
2672 record_failed_op(xmlNode *op, const pe_node_t *node,
2673  const pe_resource_t *rsc, pe_working_set_t *data_set)
2674 {
2675  xmlNode *xIter = NULL;
2676  const char *op_key = crm_element_value(op, XML_LRM_ATTR_TASK_KEY);
2677 
2678  if (node->details->online == FALSE) {
2679  return;
2680  }
2681 
2682  for (xIter = data_set->failed->children; xIter; xIter = xIter->next) {
2683  const char *key = crm_element_value(xIter, XML_LRM_ATTR_TASK_KEY);
2684  const char *uname = crm_element_value(xIter, XML_ATTR_UNAME);
2685 
2686  if(safe_str_eq(op_key, key) && safe_str_eq(uname, node->details->uname)) {
2687  crm_trace("Skipping duplicate entry %s on %s", op_key, node->details->uname);
2688  return;
2689  }
2690  }
2691 
2692  crm_trace("Adding entry %s on %s", op_key, node->details->uname);
2693  crm_xml_add(op, XML_ATTR_UNAME, node->details->uname);
2694  crm_xml_add(op, XML_LRM_ATTR_RSCID, rsc->id);
2695  add_node_copy(data_set->failed, op);
2696 }
2697 
2698 static const char *get_op_key(xmlNode *xml_op)
2699 {
2700  const char *key = crm_element_value(xml_op, XML_LRM_ATTR_TASK_KEY);
2701  if(key == NULL) {
2702  key = ID(xml_op);
2703  }
2704  return key;
2705 }
2706 
2707 static const char *
2708 last_change_str(xmlNode *xml_op)
2709 {
2710  time_t when;
2711  const char *when_s = NULL;
2712 
2714  &when) == pcmk_ok) {
2715  when_s = crm_now_string(&when);
2716  if (when_s) {
2717  // Skip day of week to make message shorter
2718  when_s = strchr(when_s, ' ');
2719  if (when_s) {
2720  ++when_s;
2721  }
2722  }
2723  }
2724  return ((when_s && *when_s)? when_s : "unknown time");
2725 }
2726 
2727 static void
2728 unpack_rsc_op_failure(resource_t * rsc, node_t * node, int rc, xmlNode * xml_op, xmlNode ** last_failure,
2729  enum action_fail_response * on_fail, pe_working_set_t * data_set)
2730 {
2731  guint interval_ms = 0;
2732  bool is_probe = false;
2733  action_t *action = NULL;
2734 
2735  const char *key = get_op_key(xml_op);
2736  const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK);
2737  const char *exit_reason = crm_element_value(xml_op,
2739 
2740  CRM_ASSERT(rsc);
2741  CRM_CHECK(task != NULL, return);
2742 
2743  *last_failure = xml_op;
2744 
2745  crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms);
2746  if ((interval_ms == 0) && !strcmp(task, CRMD_ACTION_STATUS)) {
2747  is_probe = true;
2748  }
2749 
2750  if (exit_reason == NULL) {
2751  exit_reason = "";
2752  }
2753 
2754  if (is_not_set(data_set->flags, pe_flag_symmetric_cluster)
2755  && (rc == PCMK_OCF_NOT_INSTALLED)) {
2756  crm_trace("Unexpected result (%s%s%s) was recorded for "
2757  "%s of %s on %s at %s " CRM_XS " rc=%d id=%s",
2758  services_ocf_exitcode_str(rc),
2759  (*exit_reason? ": " : ""), exit_reason,
2760  (is_probe? "probe" : task), rsc->id, node->details->uname,
2761  last_change_str(xml_op), rc, ID(xml_op));
2762  } else {
2763  crm_warn("Unexpected result (%s%s%s) was recorded for "
2764  "%s of %s on %s at %s " CRM_XS " rc=%d id=%s",
2765  services_ocf_exitcode_str(rc),
2766  (*exit_reason? ": " : ""), exit_reason,
2767  (is_probe? "probe" : task), rsc->id, node->details->uname,
2768  last_change_str(xml_op), rc, ID(xml_op));
2769 
2770  if (is_probe && (rc != PCMK_OCF_OK)
2771  && (rc != PCMK_OCF_NOT_RUNNING)
2772  && (rc != PCMK_OCF_RUNNING_MASTER)) {
2773 
2774  /* A failed (not just unexpected) probe result could mean the user
2775  * didn't know resources will be probed even where they can't run.
2776  */
2777  crm_notice("If it is not possible for %s to run on %s, see "
2778  "the resource-discovery option for location constraints",
2779  rsc->id, node->details->uname);
2780  }
2781 
2782  record_failed_op(xml_op, node, rsc, data_set);
2783  }
2784 
2785  action = custom_action(rsc, strdup(key), task, NULL, TRUE, FALSE, data_set);
2786  if ((action->on_fail <= action_fail_fence && *on_fail < action->on_fail) ||
2787  (action->on_fail == action_fail_reset_remote && *on_fail <= action_fail_recover) ||
2788  (action->on_fail == action_fail_restart_container && *on_fail <= action_fail_recover) ||
2789  (*on_fail == action_fail_restart_container && action->on_fail >= action_fail_migrate)) {
2790  pe_rsc_trace(rsc, "on-fail %s -> %s for %s (%s)", fail2text(*on_fail),
2791  fail2text(action->on_fail), action->uuid, key);
2792  *on_fail = action->on_fail;
2793  }
2794 
2795  if (!strcmp(task, CRMD_ACTION_STOP)) {
2796  resource_location(rsc, node, -INFINITY, "__stop_fail__", data_set);
2797 
2798  } else if (!strcmp(task, CRMD_ACTION_MIGRATE)) {
2799  unpack_migrate_to_failure(rsc, node, xml_op, data_set);
2800 
2801  } else if (!strcmp(task, CRMD_ACTION_MIGRATED)) {
2802  unpack_migrate_from_failure(rsc, node, xml_op, data_set);
2803 
2804  } else if (!strcmp(task, CRMD_ACTION_PROMOTE)) {
2805  rsc->role = RSC_ROLE_MASTER;
2806 
2807  } else if (!strcmp(task, CRMD_ACTION_DEMOTE)) {
2808  if (action->on_fail == action_fail_block) {
2809  rsc->role = RSC_ROLE_MASTER;
2810  rsc->next_role = RSC_ROLE_STOPPED;
2811 
2812  } else if(rc == PCMK_OCF_NOT_RUNNING) {
2813  rsc->role = RSC_ROLE_STOPPED;
2814 
2815  } else {
2816  /*
2817  * Staying in master role would put the PE/TE into a loop. Setting
2818  * slave role is not dangerous because the resource will be stopped
2819  * as part of recovery, and any master promotion will be ordered
2820  * after that stop.
2821  */
2822  rsc->role = RSC_ROLE_SLAVE;
2823  }
2824  }
2825 
2826  if(is_probe && rc == PCMK_OCF_NOT_INSTALLED) {
2827  /* leave stopped */
2828  pe_rsc_trace(rsc, "Leaving %s stopped", rsc->id);
2829  rsc->role = RSC_ROLE_STOPPED;
2830 
2831  } else if (rsc->role < RSC_ROLE_STARTED) {
2832  pe_rsc_trace(rsc, "Setting %s active", rsc->id);
2833  set_active(rsc);
2834  }
2835 
2836  pe_rsc_trace(rsc, "Resource %s: role=%s, unclean=%s, on_fail=%s, fail_role=%s",
2837  rsc->id, role2text(rsc->role),
2838  node->details->unclean ? "true" : "false",
2839  fail2text(action->on_fail), role2text(action->fail_role));
2840 
2841  if (action->fail_role != RSC_ROLE_STARTED && rsc->next_role < action->fail_role) {
2842  rsc->next_role = action->fail_role;
2843  }
2844 
2845  if (action->fail_role == RSC_ROLE_STOPPED) {
2846  int score = -INFINITY;
2847 
2848  resource_t *fail_rsc = rsc;
2849 
2850  if (fail_rsc->parent) {
2851  resource_t *parent = uber_parent(fail_rsc);
2852 
2853  if (pe_rsc_is_clone(parent)
2854  && is_not_set(parent->flags, pe_rsc_unique)) {
2855  /* For clone resources, if a child fails on an operation
2856  * with on-fail = stop, all the resources fail. Do this by preventing
2857  * the parent from coming up again. */
2858  fail_rsc = parent;
2859  }
2860  }
2861  crm_notice("%s will not be started under current conditions",
2862  fail_rsc->id);
2863  /* make sure it doesn't come up again */
2864  if (fail_rsc->allowed_nodes != NULL) {
2865  g_hash_table_destroy(fail_rsc->allowed_nodes);
2866  }
2867  fail_rsc->allowed_nodes = node_hash_from_list(data_set->nodes);
2868  g_hash_table_foreach(fail_rsc->allowed_nodes, set_node_score, &score);
2869  }
2870 
2871  pe_free_action(action);
2872 }
2873 
2893 static int
2894 determine_op_status(
2895  resource_t *rsc, int rc, int target_rc, node_t * node, xmlNode * xml_op, enum action_fail_response * on_fail, pe_working_set_t * data_set)
2896 {
2897  guint interval_ms = 0;
2898  bool is_probe = false;
2899  int result = PCMK_LRM_OP_DONE;
2900  const char *key = get_op_key(xml_op);
2901  const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK);
2902  const char *exit_reason = crm_element_value(xml_op,
2904 
2905  CRM_ASSERT(rsc);
2906  CRM_CHECK(task != NULL, return PCMK_LRM_OP_ERROR);
2907 
2908  if (exit_reason == NULL) {
2909  exit_reason = "";
2910  }
2911 
2912  crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms);
2913  if ((interval_ms == 0) && !strcmp(task, CRMD_ACTION_STATUS)) {
2914  is_probe = true;
2915  task = "probe";
2916  }
2917 
2918  if (target_rc < 0) {
2919  /* Pre-1.0 Pacemaker versions, and Pacemaker 1.1.6 or earlier with
2920  * Heartbeat 2.0.7 or earlier as the cluster layer, did not include the
2921  * target_rc in the transition key, which (along with the similar case
2922  * of a corrupted transition key in the CIB) will be reported to this
2923  * function as -1. Pacemaker 2.0+ does not support rolling upgrades from
2924  * those versions or processing of saved CIB files from those versions,
2925  * so we do not need to care much about this case.
2926  */
2927  result = PCMK_LRM_OP_ERROR;
2928  crm_warn("Expected result not found for %s on %s (corrupt or obsolete CIB?)",
2929  key, node->details->uname);
2930 
2931  } else if (target_rc != rc) {
2932  result = PCMK_LRM_OP_ERROR;
2933  pe_rsc_debug(rsc, "%s on %s: expected %d (%s), got %d (%s%s%s)",
2934  key, node->details->uname,
2935  target_rc, services_ocf_exitcode_str(target_rc),
2936  rc, services_ocf_exitcode_str(rc),
2937  (*exit_reason? ": " : ""), exit_reason);
2938  }
2939 
2940  switch (rc) {
2941  case PCMK_OCF_OK:
2942  if (is_probe && (target_rc == PCMK_OCF_NOT_RUNNING)) {
2943  result = PCMK_LRM_OP_DONE;
2944  pe_rsc_info(rsc, "Probe found %s active on %s at %s",
2945  rsc->id, node->details->uname,
2946  last_change_str(xml_op));
2947  }
2948  break;
2949 
2950  case PCMK_OCF_NOT_RUNNING:
2951  if (is_probe || target_rc == rc || is_not_set(rsc->flags, pe_rsc_managed)) {
2952  result = PCMK_LRM_OP_DONE;
2953  rsc->role = RSC_ROLE_STOPPED;
2954 
2955  /* clear any previous failure actions */
2956  *on_fail = action_fail_ignore;
2957  rsc->next_role = RSC_ROLE_UNKNOWN;
2958  }
2959  break;
2960 
2962  if (is_probe && (rc != target_rc)) {
2963  result = PCMK_LRM_OP_DONE;
2964  pe_rsc_info(rsc,
2965  "Probe found %s active and promoted on %s at %s",
2966  rsc->id, node->details->uname,
2967  last_change_str(xml_op));
2968  }
2969  rsc->role = RSC_ROLE_MASTER;
2970  break;
2971 
2974  rsc->role = RSC_ROLE_MASTER;
2975  result = PCMK_LRM_OP_ERROR;
2976  break;
2977 
2979  result = PCMK_LRM_OP_ERROR_FATAL;
2980  break;
2981 
2983  if (interval_ms > 0) {
2984  result = PCMK_LRM_OP_NOTSUPPORTED;
2985  break;
2986  }
2987  // fall through
2991  if (!pe_can_fence(data_set, node)
2992  && !strcmp(task, CRMD_ACTION_STOP)) {
2993  /* If a stop fails and we can't fence, there's nothing else we can do */
2994  pe_proc_err("No further recovery can be attempted for %s "
2995  "because %s on %s failed (%s%s%s) at %s "
2996  CRM_XS " rc=%d id=%s", rsc->id, task,
2997  node->details->uname, services_ocf_exitcode_str(rc),
2998  (*exit_reason? ": " : ""), exit_reason,
2999  last_change_str(xml_op), rc, ID(xml_op));
3001  set_bit(rsc->flags, pe_rsc_block);
3002  }
3003  result = PCMK_LRM_OP_ERROR_HARD;
3004  break;
3005 
3006  default:
3007  if (result == PCMK_LRM_OP_DONE) {
3008  crm_info("Treating unknown exit status %d from %s of %s "
3009  "on %s at %s as failure",
3010  rc, task, rsc->id, node->details->uname,
3011  last_change_str(xml_op));
3012  result = PCMK_LRM_OP_ERROR;
3013  }
3014  break;
3015  }
3016  return result;
3017 }
3018 
3019 // return TRUE if start or monitor last failure but parameters changed
3020 static bool
3021 should_clear_for_param_change(xmlNode *xml_op, const char *task,
3022  pe_resource_t *rsc, pe_node_t *node,
3023  pe_working_set_t *data_set)
3024 {
3025  if (!strcmp(task, "start") || !strcmp(task, "monitor")) {
3026 
3027  if (pe__bundle_needs_remote_name(rsc)) {
3028  /* We haven't allocated resources yet, so we can't reliably
3029  * substitute addr parameters for the REMOTE_CONTAINER_HACK.
3030  * When that's needed, defer the check until later.
3031  */
3032  pe__add_param_check(xml_op, rsc, node, pe_check_last_failure,
3033  data_set);
3034 
3035  } else {
3036  op_digest_cache_t *digest_data = NULL;
3037 
3038  digest_data = rsc_action_digest_cmp(rsc, xml_op, node, data_set);
3039  switch (digest_data->rc) {
3040  case RSC_DIGEST_UNKNOWN:
3041  crm_trace("Resource %s history entry %s on %s"
3042  " has no digest to compare",
3043  rsc->id, get_op_key(xml_op), node->details->id);
3044  break;
3045  case RSC_DIGEST_MATCH:
3046  break;
3047  default:
3048  return TRUE;
3049  }
3050  }
3051  }
3052  return FALSE;
3053 }
3054 
3055 // Order action after fencing of remote node, given connection rsc
3056 static void
3057 order_after_remote_fencing(pe_action_t *action, pe_resource_t *remote_conn,
3058  pe_working_set_t *data_set)
3059 {
3060  pe_node_t *remote_node = pe_find_node(data_set->nodes, remote_conn->id);
3061 
3062  if (remote_node) {
3063  pe_action_t *fence = pe_fence_op(remote_node, NULL, TRUE, NULL,
3064  data_set);
3065 
3066  order_actions(fence, action, pe_order_implies_then);
3067  }
3068 }
3069 
3070 static bool
3071 should_ignore_failure_timeout(pe_resource_t *rsc, xmlNode *xml_op,
3072  const char *task, guint interval_ms,
3073  bool is_last_failure, pe_working_set_t *data_set)
3074 {
3075  /* Clearing failures of recurring monitors has special concerns. The
3076  * executor reports only changes in the monitor result, so if the
3077  * monitor is still active and still getting the same failure result,
3078  * that will go undetected after the failure is cleared.
3079  *
3080  * Also, the operation history will have the time when the recurring
3081  * monitor result changed to the given code, not the time when the
3082  * result last happened.
3083  *
3084  * @TODO We probably should clear such failures only when the failure
3085  * timeout has passed since the last occurrence of the failed result.
3086  * However we don't record that information. We could maybe approximate
3087  * that by clearing only if there is a more recent successful monitor or
3088  * stop result, but we don't even have that information at this point
3089  * since we are still unpacking the resource's operation history.
3090  *
3091  * This is especially important for remote connection resources with a
3092  * reconnect interval, so in that case, we skip clearing failures
3093  * if the remote node hasn't been fenced.
3094  */
3095  if (rsc->remote_reconnect_ms
3096  && is_set(data_set->flags, pe_flag_stonith_enabled)
3097  && (interval_ms != 0) && safe_str_eq(task, CRMD_ACTION_STATUS)) {
3098 
3099  pe_node_t *remote_node = pe_find_node(data_set->nodes, rsc->id);
3100 
3101  if (remote_node && !remote_node->details->remote_was_fenced) {
3102  if (is_last_failure) {
3103  crm_info("Waiting to clear monitor failure for remote node %s"
3104  " until fencing has occurred", rsc->id);
3105  }
3106  return TRUE;
3107  }
3108  }
3109  return FALSE;
3110 }
3111 
3134 static bool
3135 check_operation_expiry(pe_resource_t *rsc, pe_node_t *node, int rc,
3136  xmlNode *xml_op, pe_working_set_t *data_set)
3137 {
3138  bool expired = FALSE;
3139  bool is_last_failure = crm_ends_with(ID(xml_op), "_last_failure_0");
3140  time_t last_run = 0;
3141  guint interval_ms = 0;
3142  int unexpired_fail_count = 0;
3143  const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK);
3144  const char *clear_reason = NULL;
3145 
3146  crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms);
3147 
3148  if ((rsc->failure_timeout > 0)
3150  &last_run) == 0)) {
3151 
3152  // Resource has a failure-timeout, and history entry has a timestamp
3153 
3154  time_t now = get_effective_time(data_set);
3155  time_t last_failure = 0;
3156 
3157  // Is this particular operation history older than the failure timeout?
3158  if ((now >= (last_run + rsc->failure_timeout))
3159  && !should_ignore_failure_timeout(rsc, xml_op, task, interval_ms,
3160  is_last_failure, data_set)) {
3161  expired = TRUE;
3162  }
3163 
3164  // Does the resource as a whole have an unexpired fail count?
3165  unexpired_fail_count = pe_get_failcount(node, rsc, &last_failure,
3166  pe_fc_effective, xml_op,
3167  data_set);
3168 
3169  // Update scheduler recheck time according to *last* failure
3170  crm_trace("%s@%lld is %sexpired @%lld with unexpired_failures=%d timeout=%ds"
3171  " last-failure@%lld",
3172  ID(xml_op), (long long) last_run, (expired? "" : "not "),
3173  (long long) now, unexpired_fail_count, rsc->failure_timeout,
3174  (long long) last_failure);
3175  last_failure += rsc->failure_timeout + 1;
3176  if (unexpired_fail_count && (now < last_failure)) {
3177  pe__update_recheck_time(last_failure, data_set);
3178  }
3179  }
3180 
3181  if (expired) {
3182  if (pe_get_failcount(node, rsc, NULL, pe_fc_default, xml_op, data_set)) {
3183 
3184  // There is a fail count ignoring timeout
3185 
3186  if (unexpired_fail_count == 0) {
3187  // There is no fail count considering timeout
3188  clear_reason = "it expired";
3189 
3190  } else {
3191  /* This operation is old, but there is an unexpired fail count.
3192  * In a properly functioning cluster, this should only be
3193  * possible if this operation is not a failure (otherwise the
3194  * fail count should be expired too), so this is really just a
3195  * failsafe.
3196  */
3197  expired = FALSE;
3198  }
3199 
3200  } else if (is_last_failure && rsc->remote_reconnect_ms) {
3201  /* Clear any expired last failure when reconnect interval is set,
3202  * even if there is no fail count.
3203  */
3204  clear_reason = "reconnect interval is set";
3205  }
3206  }
3207 
3208  if (!expired && is_last_failure
3209  && should_clear_for_param_change(xml_op, task, rsc, node, data_set)) {
3210  clear_reason = "resource parameters have changed";
3211  }
3212 
3213  if (clear_reason != NULL) {
3214  // Schedule clearing of the fail count
3215  pe_action_t *clear_op = pe__clear_failcount(rsc, node, clear_reason,
3216  data_set);
3217 
3218  if (is_set(data_set->flags, pe_flag_stonith_enabled)
3219  && rsc->remote_reconnect_ms) {
3220  /* If we're clearing a remote connection due to a reconnect
3221  * interval, we want to wait until any scheduled fencing
3222  * completes.
3223  *
3224  * We could limit this to remote_node->details->unclean, but at
3225  * this point, that's always true (it won't be reliable until
3226  * after unpack_node_loop() is done).
3227  */
3228  crm_info("Clearing %s failure will wait until any scheduled "
3229  "fencing of %s completes", task, rsc->id);
3230  order_after_remote_fencing(clear_op, rsc, data_set);
3231  }
3232  }
3233 
3234  if (expired && (interval_ms == 0) && safe_str_eq(task, CRMD_ACTION_STATUS)) {
3235  switch(rc) {
3236  case PCMK_OCF_OK:
3237  case PCMK_OCF_NOT_RUNNING:
3239  case PCMK_OCF_DEGRADED:
3241  // Don't expire probes that return these values
3242  expired = FALSE;
3243  break;
3244  }
3245  }
3246 
3247  return expired;
3248 }
3249 
3250 int pe__target_rc_from_xml(xmlNode *xml_op)
3251 {
3252  int target_rc = 0;
3253  const char *key = crm_element_value(xml_op, XML_ATTR_TRANSITION_KEY);
3254 
3255  if (key == NULL) {
3256  return -1;
3257  }
3258  decode_transition_key(key, NULL, NULL, NULL, &target_rc);
3259  return target_rc;
3260 }
3261 
3262 static enum action_fail_response
3263 get_action_on_fail(resource_t *rsc, const char *key, const char *task, pe_working_set_t * data_set)
3264 {
3265  int result = action_fail_recover;
3266  action_t *action = custom_action(rsc, strdup(key), task, NULL, TRUE, FALSE, data_set);
3267 
3268  result = action->on_fail;
3269  pe_free_action(action);
3270 
3271  return result;
3272 }
3273 
3274 static void
3275 update_resource_state(resource_t * rsc, node_t * node, xmlNode * xml_op, const char * task, int rc,
3276  xmlNode * last_failure, enum action_fail_response * on_fail, pe_working_set_t * data_set)
3277 {
3278  gboolean clear_past_failure = FALSE;
3279 
3280  CRM_ASSERT(rsc);
3281  CRM_ASSERT(xml_op);
3282 
3283  if (rc == PCMK_OCF_NOT_RUNNING) {
3284  clear_past_failure = TRUE;
3285 
3286  } else if (rc == PCMK_OCF_NOT_INSTALLED) {
3287  rsc->role = RSC_ROLE_STOPPED;
3288 
3289  } else if (safe_str_eq(task, CRMD_ACTION_STATUS)) {
3290  if (last_failure) {
3291  const char *op_key = get_op_key(xml_op);
3292  const char *last_failure_key = get_op_key(last_failure);
3293 
3294  if (safe_str_eq(op_key, last_failure_key)) {
3295  clear_past_failure = TRUE;
3296  }
3297  }
3298 
3299  if (rsc->role < RSC_ROLE_STARTED) {
3300  set_active(rsc);
3301  }
3302 
3303  } else if (safe_str_eq(task, CRMD_ACTION_START)) {
3304  rsc->role = RSC_ROLE_STARTED;
3305  clear_past_failure = TRUE;
3306 
3307  } else if (safe_str_eq(task, CRMD_ACTION_STOP)) {
3308  rsc->role = RSC_ROLE_STOPPED;
3309  clear_past_failure = TRUE;
3310 
3311  } else if (safe_str_eq(task, CRMD_ACTION_PROMOTE)) {
3312  rsc->role = RSC_ROLE_MASTER;
3313  clear_past_failure = TRUE;
3314 
3315  } else if (safe_str_eq(task, CRMD_ACTION_DEMOTE)) {
3316  /* Demote from Master does not clear an error */
3317  rsc->role = RSC_ROLE_SLAVE;
3318 
3319  } else if (safe_str_eq(task, CRMD_ACTION_MIGRATED)) {
3320  rsc->role = RSC_ROLE_STARTED;
3321  clear_past_failure = TRUE;
3322 
3323  } else if (safe_str_eq(task, CRMD_ACTION_MIGRATE)) {
3324  unpack_migrate_to_success(rsc, node, xml_op, data_set);
3325 
3326  } else if (rsc->role < RSC_ROLE_STARTED) {
3327  pe_rsc_trace(rsc, "%s active on %s", rsc->id, node->details->uname);
3328  set_active(rsc);
3329  }
3330 
3331  /* clear any previous failure actions */
3332  if (clear_past_failure) {
3333  switch (*on_fail) {
3334  case action_fail_stop:
3335  case action_fail_fence:
3336  case action_fail_migrate:
3337  case action_fail_standby:
3338  pe_rsc_trace(rsc, "%s.%s is not cleared by a completed stop",
3339  rsc->id, fail2text(*on_fail));
3340  break;
3341 
3342  case action_fail_block:
3343  case action_fail_ignore:
3344  case action_fail_recover:
3346  *on_fail = action_fail_ignore;
3347  rsc->next_role = RSC_ROLE_UNKNOWN;
3348  break;
3350  if (rsc->remote_reconnect_ms == 0) {
3351  /* With no reconnect interval, the connection is allowed to
3352  * start again after the remote node is fenced and
3353  * completely stopped. (With a reconnect interval, we wait
3354  * for the failure to be cleared entirely before attempting
3355  * to reconnect.)
3356  */
3357  *on_fail = action_fail_ignore;
3358  rsc->next_role = RSC_ROLE_UNKNOWN;
3359  }
3360  break;
3361  }
3362  }
3363 }
3364 
3385 static int
3386 remap_monitor_rc(int rc, xmlNode *xml_op, const pe_node_t *node,
3387  const pe_resource_t *rsc, pe_working_set_t *data_set)
3388 {
3389  int remapped_rc = rc;
3390 
3391  switch (rc) {
3392  case PCMK_OCF_DEGRADED:
3393  remapped_rc = PCMK_OCF_OK;
3394  break;
3395 
3397  remapped_rc = PCMK_OCF_RUNNING_MASTER;
3398  break;
3399 
3400  default:
3401  break;
3402  }
3403 
3404  if (rc != remapped_rc) {
3405  crm_trace("Remapping monitor result %d to %d", rc, remapped_rc);
3406  if (!node->details->shutdown || node->details->online) {
3407  record_failed_op(xml_op, node, rsc, data_set);
3408  }
3409  }
3410  return remapped_rc;
3411 }
3412 
3413 static void
3414 unpack_rsc_op(pe_resource_t *rsc, pe_node_t *node, xmlNode *xml_op,
3415  xmlNode **last_failure, enum action_fail_response *on_fail,
3416  pe_working_set_t *data_set)
3417 {
3418  int rc = 0;
3419  int task_id = 0;
3420  int target_rc = 0;
3421  int status = PCMK_LRM_OP_UNKNOWN;
3422  guint interval_ms = 0;
3423  const char *task = NULL;
3424  const char *task_key = NULL;
3425  const char *exit_reason = NULL;
3426  bool expired = FALSE;
3427  resource_t *parent = rsc;
3428  enum action_fail_response failure_strategy = action_fail_recover;
3429 
3430  CRM_CHECK(rsc && node && xml_op, return);
3431 
3432  target_rc = pe__target_rc_from_xml(xml_op);
3433  task_key = get_op_key(xml_op);
3434  task = crm_element_value(xml_op, XML_LRM_ATTR_TASK);
3435  exit_reason = crm_element_value(xml_op, XML_LRM_ATTR_EXIT_REASON);
3436  if (exit_reason == NULL) {
3437  exit_reason = "";
3438  }
3439 
3440  crm_element_value_int(xml_op, XML_LRM_ATTR_RC, &rc);
3441  crm_element_value_int(xml_op, XML_LRM_ATTR_CALLID, &task_id);
3442  crm_element_value_int(xml_op, XML_LRM_ATTR_OPSTATUS, &status);
3443  crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms);
3444 
3445  CRM_CHECK(task != NULL, return);
3446  CRM_CHECK(status <= PCMK_LRM_OP_INVALID, return);
3447  CRM_CHECK(status >= PCMK_LRM_OP_PENDING, return);
3448 
3449  if (!strcmp(task, CRMD_ACTION_NOTIFY) ||
3450  !strcmp(task, CRMD_ACTION_METADATA)) {
3451  /* safe to ignore these */
3452  return;
3453  }
3454 
3455  if (is_not_set(rsc->flags, pe_rsc_unique)) {
3456  parent = uber_parent(rsc);
3457  }
3458 
3459  pe_rsc_trace(rsc, "Unpacking task %s/%s (call_id=%d, status=%d, rc=%d) on %s (role=%s)",
3460  task_key, task, task_id, status, rc, node->details->uname, role2text(rsc->role));
3461 
3462  if (node->details->unclean) {
3463  pe_rsc_trace(rsc, "Node %s (where %s is running) is unclean."
3464  " Further action depends on the value of the stop's on-fail attribute",
3465  node->details->uname, rsc->id);
3466  }
3467 
3468  /* It should be possible to call remap_monitor_rc() first then call
3469  * check_operation_expiry() only if rc != target_rc, because there should
3470  * never be a fail count without at least one unexpected result in the
3471  * resource history. That would be more efficient by avoiding having to call
3472  * check_operation_expiry() for expected results.
3473  *
3474  * However, we do have such configurations in the scheduler regression
3475  * tests, even if it shouldn't be possible with the current code. It's
3476  * probably a good idea anyway, but that would require updating the test
3477  * inputs to something currently possible.
3478  */
3479 
3480  if ((status != PCMK_LRM_OP_NOT_INSTALLED)
3481  && check_operation_expiry(rsc, node, rc, xml_op, data_set)) {
3482  expired = TRUE;
3483  }
3484 
3485  if (!strcmp(task, CRMD_ACTION_STATUS)) {
3486  rc = remap_monitor_rc(rc, xml_op, node, rsc, data_set);
3487  }
3488 
3489  if (expired && (rc != target_rc)) {
3490  const char *magic = crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC);
3491 
3492  if (interval_ms == 0) {
3493  crm_notice("Ignoring expired %s failure on %s "
3494  CRM_XS " actual=%d expected=%d magic=%s",
3495  task_key, node->details->uname, rc, target_rc, magic);
3496  goto done;
3497 
3498  } else if(node->details->online && node->details->unclean == FALSE) {
3499  /* Reschedule the recurring monitor. CancelXmlOp() won't work at
3500  * this stage, so as a hacky workaround, forcibly change the restart
3501  * digest so check_action_definition() does what we want later.
3502  *
3503  * @TODO We should skip this if there is a newer successful monitor.
3504  * Also, this causes rescheduling only if the history entry
3505  * has an op-digest (which the expire-non-blocked-failure
3506  * scheduler regression test doesn't, but that may not be a
3507  * realistic scenario in production).
3508  */
3509  crm_notice("Rescheduling %s after failure expired on %s "
3510  CRM_XS " actual=%d expected=%d magic=%s",
3511  task_key, node->details->uname, rc, target_rc, magic);
3512  crm_xml_add(xml_op, XML_LRM_ATTR_RESTART_DIGEST, "calculated-failure-timeout");
3513  goto done;
3514  }
3515  }
3516 
3517  /* If the executor reported an operation status of anything but done or
3518  * error, consider that final. But for done or error, we know better whether
3519  * it should be treated as a failure or not, because we know the expected
3520  * result.
3521  */
3522  if(status == PCMK_LRM_OP_DONE || status == PCMK_LRM_OP_ERROR) {
3523  status = determine_op_status(rsc, rc, target_rc, node, xml_op, on_fail, data_set);
3524  pe_rsc_trace(rsc, "Remapped %s status to %d", task_key, status);
3525  }
3526 
3527  switch (status) {
3528  case PCMK_LRM_OP_CANCELLED:
3529  // Should never happen
3530  pe_err("Resource history contains cancellation '%s' "
3531  "(%s of %s on %s at %s)",
3532  ID(xml_op), task, rsc->id, node->details->uname,
3533  last_change_str(xml_op));
3534  break;
3535 
3536  case PCMK_LRM_OP_PENDING:
3537  if (!strcmp(task, CRMD_ACTION_START)) {
3539  set_active(rsc);
3540 
3541  } else if (!strcmp(task, CRMD_ACTION_PROMOTE)) {
3542  rsc->role = RSC_ROLE_MASTER;
3543 
3544  } else if (!strcmp(task, CRMD_ACTION_MIGRATE) && node->details->unclean) {
3545  /* If a pending migrate_to action is out on a unclean node,
3546  * we have to force the stop action on the target. */
3547  const char *migrate_target = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_TARGET);
3548  node_t *target = pe_find_node(data_set->nodes, migrate_target);
3549  if (target) {
3550  stop_action(rsc, target, FALSE);
3551  }
3552  }
3553 
3554  if (rsc->pending_task == NULL) {
3555  if ((interval_ms != 0) || strcmp(task, CRMD_ACTION_STATUS)) {
3556  rsc->pending_task = strdup(task);
3557  rsc->pending_node = node;
3558  } else {
3559  /* Pending probes are not printed, even if pending
3560  * operations are requested. If someone ever requests that
3561  * behavior, enable the below and the corresponding part of
3562  * native.c:native_pending_task().
3563  */
3564 #if 0
3565  rsc->pending_task = strdup("probe");
3566  rsc->pending_node = node;
3567 #endif
3568  }
3569  }
3570  break;
3571 
3572  case PCMK_LRM_OP_DONE:
3573  pe_rsc_trace(rsc, "%s of %s on %s completed at %s " CRM_XS " id=%s",
3574  task, rsc->id, node->details->uname,
3575  last_change_str(xml_op), ID(xml_op));
3576  update_resource_state(rsc, node, xml_op, task, rc, *last_failure, on_fail, data_set);
3577  break;
3578 
3580  failure_strategy = get_action_on_fail(rsc, task_key, task, data_set);
3581  if (failure_strategy == action_fail_ignore) {
3582  crm_warn("Cannot ignore failed %s of %s on %s: "
3583  "Resource agent doesn't exist "
3584  CRM_XS " status=%d rc=%d id=%s",
3585  task, rsc->id, node->details->uname, status, rc,
3586  ID(xml_op));
3587  /* Also for printing it as "FAILED" by marking it as pe_rsc_failed later */
3588  *on_fail = action_fail_migrate;
3589  }
3590  resource_location(parent, node, -INFINITY, "hard-error", data_set);
3591  unpack_rsc_op_failure(rsc, node, rc, xml_op, last_failure, on_fail, data_set);
3592  break;
3593 
3595  if (pe__is_guest_or_remote_node(node)
3596  && is_set(node->details->remote_rsc->flags, pe_rsc_managed)) {
3597  /* We should never get into a situation where a managed remote
3598  * connection resource is considered OK but a resource action
3599  * behind the connection gets a "not connected" status. But as a
3600  * fail-safe in case a bug or unusual circumstances do lead to
3601  * that, ensure the remote connection is considered failed.
3602  */
3604  }
3605 
3606  // fall through
3607 
3608  case PCMK_LRM_OP_ERROR:
3611  case PCMK_LRM_OP_TIMEOUT:
3613  case PCMK_LRM_OP_INVALID:
3614 
3615  failure_strategy = get_action_on_fail(rsc, task_key, task, data_set);
3616  if ((failure_strategy == action_fail_ignore)
3617  || (failure_strategy == action_fail_restart_container
3618  && !strcmp(task, CRMD_ACTION_STOP))) {
3619 
3620  crm_warn("Pretending failed %s (%s%s%s) of %s on %s at %s "
3621  "succeeded " CRM_XS " rc=%d id=%s",
3622  task, services_ocf_exitcode_str(rc),
3623  (*exit_reason? ": " : ""), exit_reason, rsc->id,
3624  node->details->uname, last_change_str(xml_op), rc,
3625  ID(xml_op));
3626 
3627  update_resource_state(rsc, node, xml_op, task, target_rc, *last_failure, on_fail, data_set);
3628  crm_xml_add(xml_op, XML_ATTR_UNAME, node->details->uname);
3630 
3631  record_failed_op(xml_op, node, rsc, data_set);
3632 
3633  if (failure_strategy == action_fail_restart_container && *on_fail <= action_fail_recover) {
3634  *on_fail = failure_strategy;
3635  }
3636 
3637  } else {
3638  unpack_rsc_op_failure(rsc, node, rc, xml_op, last_failure, on_fail, data_set);
3639 
3640  if(status == PCMK_LRM_OP_ERROR_HARD) {
3641  do_crm_log(rc != PCMK_OCF_NOT_INSTALLED?LOG_ERR:LOG_NOTICE,
3642  "Preventing %s from restarting on %s because "
3643  "of hard failure (%s%s%s)" CRM_XS " rc=%d id=%s",
3644  parent->id, node->details->uname,
3645  services_ocf_exitcode_str(rc),
3646  (*exit_reason? ": " : ""), exit_reason,
3647  rc, ID(xml_op));
3648  resource_location(parent, node, -INFINITY, "hard-error", data_set);
3649 
3650  } else if(status == PCMK_LRM_OP_ERROR_FATAL) {
3651  crm_err("Preventing %s from restarting anywhere because "
3652  "of fatal failure (%s%s%s) " CRM_XS " rc=%d id=%s",
3653  parent->id, services_ocf_exitcode_str(rc),
3654  (*exit_reason? ": " : ""), exit_reason,
3655  rc, ID(xml_op));
3656  resource_location(parent, NULL, -INFINITY, "fatal-error", data_set);
3657  }
3658  }
3659  break;
3660  }
3661 
3662  done:
3663  pe_rsc_trace(rsc, "Resource %s after %s: role=%s, next=%s",
3664  rsc->id, task, role2text(rsc->role),
3665  role2text(rsc->next_role));
3666 }
3667 
3668 static void
3669 add_node_attrs(xmlNode *xml_obj, pe_node_t *node, bool overwrite,
3670  pe_working_set_t *data_set)
3671 {
3672  const char *cluster_name = NULL;
3673 
3674  g_hash_table_insert(node->details->attrs,
3675  strdup(CRM_ATTR_UNAME), strdup(node->details->uname));
3676 
3677  g_hash_table_insert(node->details->attrs, strdup(CRM_ATTR_ID),
3678  strdup(node->details->id));
3679  if (safe_str_eq(node->details->id, data_set->dc_uuid)) {
3680  data_set->dc_node = node;
3681  node->details->is_dc = TRUE;
3682  g_hash_table_insert(node->details->attrs,
3683  strdup(CRM_ATTR_IS_DC), strdup(XML_BOOLEAN_TRUE));
3684  } else {
3685  g_hash_table_insert(node->details->attrs,
3686  strdup(CRM_ATTR_IS_DC), strdup(XML_BOOLEAN_FALSE));
3687  }
3688 
3689  cluster_name = g_hash_table_lookup(data_set->config_hash, "cluster-name");
3690  if (cluster_name) {
3691  g_hash_table_insert(node->details->attrs, strdup(CRM_ATTR_CLUSTER_NAME),
3692  strdup(cluster_name));
3693  }
3694 
3696  node->details->attrs, NULL, overwrite, data_set);
3697 
3698  if (pe_node_attribute_raw(node, CRM_ATTR_SITE_NAME) == NULL) {
3699  const char *site_name = pe_node_attribute_raw(node, "site-name");
3700 
3701  if (site_name) {
3702  g_hash_table_insert(node->details->attrs,
3703  strdup(CRM_ATTR_SITE_NAME),
3704  strdup(site_name));
3705 
3706  } else if (cluster_name) {
3707  /* Default to cluster-name if unset */
3708  g_hash_table_insert(node->details->attrs,
3709  strdup(CRM_ATTR_SITE_NAME),
3710  strdup(cluster_name));
3711  }
3712  }
3713 }
3714 
3715 static GListPtr
3716 extract_operations(const char *node, const char *rsc, xmlNode * rsc_entry, gboolean active_filter)
3717 {
3718  int counter = -1;
3719  int stop_index = -1;
3720  int start_index = -1;
3721 
3722  xmlNode *rsc_op = NULL;
3723 
3724  GListPtr gIter = NULL;
3725  GListPtr op_list = NULL;
3726  GListPtr sorted_op_list = NULL;
3727 
3728  /* extract operations */
3729  op_list = NULL;
3730  sorted_op_list = NULL;
3731 
3732  for (rsc_op = __xml_first_child_element(rsc_entry);
3733  rsc_op != NULL; rsc_op = __xml_next_element(rsc_op)) {
3734  if (crm_str_eq((const char *)rsc_op->name, XML_LRM_TAG_RSC_OP, TRUE)) {
3735  crm_xml_add(rsc_op, "resource", rsc);
3736  crm_xml_add(rsc_op, XML_ATTR_UNAME, node);
3737  op_list = g_list_prepend(op_list, rsc_op);
3738  }
3739  }
3740 
3741  if (op_list == NULL) {
3742  /* if there are no operations, there is nothing to do */
3743  return NULL;
3744  }
3745 
3746  sorted_op_list = g_list_sort(op_list, sort_op_by_callid);
3747 
3748  /* create active recurring operations as optional */
3749  if (active_filter == FALSE) {
3750  return sorted_op_list;
3751  }
3752 
3753  op_list = NULL;
3754 
3755  calculate_active_ops(sorted_op_list, &start_index, &stop_index);
3756 
3757  for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) {
3758  xmlNode *rsc_op = (xmlNode *) gIter->data;
3759 
3760  counter++;
3761 
3762  if (start_index < stop_index) {
3763  crm_trace("Skipping %s: not active", ID(rsc_entry));
3764  break;
3765 
3766  } else if (counter < start_index) {
3767  crm_trace("Skipping %s: old", ID(rsc_op));
3768  continue;
3769  }
3770  op_list = g_list_append(op_list, rsc_op);
3771  }
3772 
3773  g_list_free(sorted_op_list);
3774  return op_list;
3775 }
3776 
3777 GListPtr
3778 find_operations(const char *rsc, const char *node, gboolean active_filter,
3779  pe_working_set_t * data_set)
3780 {
3781  GListPtr output = NULL;
3782  GListPtr intermediate = NULL;
3783 
3784  xmlNode *tmp = NULL;
3785  xmlNode *status = find_xml_node(data_set->input, XML_CIB_TAG_STATUS, TRUE);
3786 
3787  node_t *this_node = NULL;
3788 
3789  xmlNode *node_state = NULL;
3790 
3791  for (node_state = __xml_first_child_element(status); node_state != NULL;
3792  node_state = __xml_next_element(node_state)) {
3793 
3794  if (crm_str_eq((const char *)node_state->name, XML_CIB_TAG_STATE, TRUE)) {
3795  const char *uname = crm_element_value(node_state, XML_ATTR_UNAME);
3796 
3797  if (node != NULL && safe_str_neq(uname, node)) {
3798  continue;
3799  }
3800 
3801  this_node = pe_find_node(data_set->nodes, uname);
3802  if(this_node == NULL) {
3803  CRM_LOG_ASSERT(this_node != NULL);
3804  continue;
3805 
3806  } else if (pe__is_guest_or_remote_node(this_node)) {
3807  determine_remote_online_status(data_set, this_node);
3808 
3809  } else {
3810  determine_online_status(node_state, this_node, data_set);
3811  }
3812 
3813  if (this_node->details->online || is_set(data_set->flags, pe_flag_stonith_enabled)) {
3814  /* offline nodes run no resources...
3815  * unless stonith is enabled in which case we need to
3816  * make sure rsc start events happen after the stonith
3817  */
3818  xmlNode *lrm_rsc = NULL;
3819 
3820  tmp = find_xml_node(node_state, XML_CIB_TAG_LRM, FALSE);
3821  tmp = find_xml_node(tmp, XML_LRM_TAG_RESOURCES, FALSE);
3822 
3823  for (lrm_rsc = __xml_first_child_element(tmp); lrm_rsc != NULL;
3824  lrm_rsc = __xml_next_element(lrm_rsc)) {
3825  if (crm_str_eq((const char *)lrm_rsc->name, XML_LRM_TAG_RESOURCE, TRUE)) {
3826 
3827  const char *rsc_id = crm_element_value(lrm_rsc, XML_ATTR_ID);
3828 
3829  if (rsc != NULL && safe_str_neq(rsc_id, rsc)) {
3830  continue;
3831  }
3832 
3833  intermediate = extract_operations(uname, rsc_id, lrm_rsc, active_filter);
3834  output = g_list_concat(output, intermediate);
3835  }
3836  }
3837  }
3838  }
3839  }
3840 
3841  return output;
3842 }
CRMD_ACTION_METADATA
#define CRMD_ACTION_METADATA
Definition: crm.h:186
get_target_role
gboolean get_target_role(resource_t *rsc, enum rsc_role_e *role)
Definition: utils.c:1742
resource_object_functions_s::location
pe_node_t *(* location)(const pe_resource_t *, GList **, int)
Definition: pe_types.h:53
pe__unpack_dataset_nvpairs
void pe__unpack_dataset_nvpairs(xmlNode *xml_obj, const char *set_name, GHashTable *node_hash, GHashTable *hash, const char *always_first, gboolean overwrite, pe_working_set_t *data_set)
Definition: utils.c:2558
pe_rsc_orphan
#define pe_rsc_orphan
Definition: pe_types.h:224
pe_ticket_s::last_granted
time_t last_granted
Definition: pe_types.h:422
pe_native
@ pe_native
Definition: pe_types.h:37
unpack_lrm_resources
gboolean unpack_lrm_resources(node_t *node, xmlNode *lrm_rsc_list, pe_working_set_t *data_set)
Definition: unpack.c:2327
GListPtr
GList * GListPtr
Definition: crm.h:214
XML_LRM_ATTR_MIGRATE_SOURCE
#define XML_LRM_ATTR_MIGRATE_SOURCE
Definition: msg_xml.h:285
pe_working_set_s::input
xmlNode * input
Definition: pe_types.h:118
CRM_ATTR_KIND
#define CRM_ATTR_KIND
Definition: crm.h:112
INFINITY
#define INFINITY
Definition: crm.h:95
CRMD_JOINSTATE_DOWN
#define CRMD_JOINSTATE_DOWN
Definition: crm.h:159
order_actions
gboolean order_actions(action_t *lh_action, action_t *rh_action, enum pe_ordering order)
Definition: utils.c:1778
action_fail_response
action_fail_response
Definition: common.h:36
XML_LRM_ATTR_TASK_KEY
#define XML_LRM_ATTR_TASK_KEY
Definition: msg_xml.h:261
crm_str_eq
gboolean crm_str_eq(const char *a, const char *b, gboolean use_case)
Definition: strings.c:224
pe_resource_s::variant
enum pe_obj_types variant
Definition: pe_types.h:301
XML_LRM_TAG_RESOURCE
#define XML_LRM_TAG_RESOURCE
Definition: msg_xml.h:227
pe_fc_default
@ pe_fc_default
Definition: internal.h:148
XML_RSC_ATTR_REMOTE_NODE
#define XML_RSC_ATTR_REMOTE_NODE
Definition: msg_xml.h:208
pe_tag_s::id
char * id
Definition: pe_types.h:428
pe_node_shared_s::rsc_discovery_enabled
gboolean rsc_discovery_enabled
Definition: pe_types.h:200
pe_resource_s::dangling_migrations
GListPtr dangling_migrations
Definition: pe_types.h:349
pe_proc_warn
#define pe_proc_warn(fmt...)
Definition: internal.h:24
pe_rsc_allow_migrate
#define pe_rsc_allow_migrate
Definition: pe_types.h:247
XML_LRM_ATTR_OPSTATUS
#define XML_LRM_ATTR_OPSTATUS
Definition: msg_xml.h:270
pe_find_resource
pe_resource_t * pe_find_resource(GListPtr rsc_list, const char *id_rh)
Definition: status.c:370
pe_working_set_s::resources
GListPtr resources
Definition: pe_types.h:139
action_fail_standby
@ action_fail_standby
Definition: common.h:42
PCMK_OCF_DEGRADED_MASTER
@ PCMK_OCF_DEGRADED_MASTER
Definition: services.h:106
pe_node_shared_s::expected_up
gboolean expected_up
Definition: pe_types.h:197
op_digest_cache_s::rc
enum rsc_digest_cmp_val rc
Definition: internal.h:329
no_quorum_freeze
@ no_quorum_freeze
Definition: pe_types.h:61
pe_resource_s::next_role
enum rsc_role_e next_role
Definition: pe_types.h:342
pe_find_node
pe_node_t * pe_find_node(GListPtr node_list, const char *uname)
Definition: status.c:422
pe_node_shared_s::unseen
gboolean unseen
Definition: pe_types.h:195
pe_working_set_s::nodes
GListPtr nodes
Definition: pe_types.h:138
msg_xml.h
RSC_ROLE_STOPPED
@ RSC_ROLE_STOPPED
Definition: common.h:88
XML_NODE_JOIN_STATE
#define XML_NODE_JOIN_STATE
Definition: msg_xml.h:238
node_score_yellow
int node_score_yellow
Definition: utils.c:65
XML_CIB_TAG_TICKETS
#define XML_CIB_TAG_TICKETS
Definition: msg_xml.h:385
pe_rsc_info
#define pe_rsc_info(rsc, fmt, args...)
Definition: internal.h:17
action_fail_stop
@ action_fail_stop
Definition: common.h:41
data
char data[0]
Definition: internal.h:12
PCMK_LRM_OP_ERROR
@ PCMK_LRM_OP_ERROR
Definition: services.h:125
pe_node_shared_s::remote_rsc
pe_resource_t * remote_rsc
Definition: pe_types.h:207
RSC_ROLE_MASTER
@ RSC_ROLE_MASTER
Definition: common.h:91
pe_rsc_debug
#define pe_rsc_debug(rsc, fmt, args...)
Definition: internal.h:18
CRMD_ACTION_NOTIFY
#define CRMD_ACTION_NOTIFY
Definition: crm.h:182
XML_ATTR_TRANSITION_KEY
#define XML_ATTR_TRANSITION_KEY
Definition: msg_xml.h:358
pe_action_s::on_fail
enum action_fail_response on_fail
Definition: pe_types.h:384
crm_element_value_int
int crm_element_value_int(const xmlNode *data, const char *name, int *dest)
Retrieve the integer value of an XML attribute.
Definition: nvpair.c:555
pe_find_node_any
pe_node_t * pe_find_node_any(GListPtr node_list, const char *id, const char *uname)
Definition: status.c:394
pe_ticket_s::granted
gboolean granted
Definition: pe_types.h:421
create_xml_node
xmlNode * create_xml_node(xmlNode *parent, const char *name)
Definition: xml.c:1970
PCMK_LRM_OP_CANCELLED
@ PCMK_LRM_OP_CANCELLED
Definition: services.h:122
pe_resource_s::known_on
GHashTable * known_on
Definition: pe_types.h:338
CRM_ATTR_CLUSTER_NAME
#define CRM_ATTR_CLUSTER_NAME
Definition: crm.h:115
pe_resource_s::children
GListPtr children
Definition: pe_types.h:348
pe_resource_s::id
char * id
Definition: pe_types.h:292
stop_action
#define stop_action(rsc, node, optional)
Definition: internal.h:230
XML_NODE_IN_CLUSTER
#define XML_NODE_IN_CLUSTER
Definition: msg_xml.h:240
rsc_role_e
rsc_role_e
Definition: common.h:86
pe_working_set_s::stonith_timeout
int stonith_timeout
Definition: pe_types.h:129
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
get_xpath_object
xmlNode * get_xpath_object(const char *xpath, xmlNode *xml_obj, int error_level)
Definition: xpath.c:220
sort_rsc_priority
gint sort_rsc_priority(gconstpointer a, gconstpointer b)
Definition: utils.c:428
pe_fc_effective
@ pe_fc_effective
Definition: internal.h:149
PCMK_LRM_OP_NOT_CONNECTED
@ PCMK_LRM_OP_NOT_CONNECTED
Definition: services.h:129
XML_CIB_TAG_STATE
#define XML_CIB_TAG_STATE
Definition: msg_xml.h:158
XML_RULE_ATTR_SCORE
#define XML_RULE_ATTR_SCORE
Definition: msg_xml.h:296
CRM_CHECK
#define CRM_CHECK(expr, failure_action)
Definition: logging.h:157
pe_node_s::weight
int weight
Definition: pe_types.h:217
CRMD_JOINSTATE_MEMBER
#define CRMD_JOINSTATE_MEMBER
Definition: crm.h:161
crm_parse_ms
guint crm_parse_ms(const char *text)
Definition: strings.c:147
clear_bit
#define clear_bit(word, bit)
Definition: crm_internal.h:168
pe_pref
const char * pe_pref(GHashTable *options, const char *name)
Definition: common.c:187
XML_CIB_TAG_LRM
#define XML_CIB_TAG_LRM
Definition: msg_xml.h:225
CRM_ATTR_UNAME
#define CRM_ATTR_UNAME
Definition: crm.h:110
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
XML_CIB_TAG_TICKET_STATE
#define XML_CIB_TAG_TICKET_STATE
Definition: msg_xml.h:386
pe_working_set_s::stonith_action
const char * stonith_action
Definition: pe_types.h:124
custom_action
action_t * custom_action(resource_t *rsc, char *key, const char *task, node_t *on_node, gboolean optional, gboolean foo, pe_working_set_t *data_set)
Definition: utils.c:455
crm_notice
#define crm_notice(fmt, args...)
Definition: logging.h:243
PCMK_LRM_OP_INVALID
@ PCMK_LRM_OP_INVALID
Definition: services.h:130
action_fail_recover
@ action_fail_recover
Definition: common.h:38
pe_node_shared_s::id
const char * id
Definition: pe_types.h:185
pe_working_set_s::dc_node
pe_node_t * dc_node
Definition: pe_types.h:123
type
enum crm_ais_msg_types type
Definition: internal.h:5
crm_err
#define crm_err(fmt, args...)
Definition: logging.h:241
pe_can_fence
bool pe_can_fence(pe_working_set_t *data_set, node_t *node)
Definition: utils.c:89
internal.h
pe__update_recheck_time
void pe__update_recheck_time(time_t recheck, pe_working_set_t *data_set)
Definition: utils.c:2544
XML_NODE_ATTR_RSC_DISCOVERY
#define XML_NODE_ATTR_RSC_DISCOVERY
Definition: msg_xml.h:342
CRMD_JOINSTATE_PENDING
#define CRMD_JOINSTATE_PENDING
Definition: crm.h:160
pe_resource_s::pending_node
pe_node_t * pending_node
Definition: pe_types.h:354
pe_working_set_s::stop_needed
GList * stop_needed
Definition: pe_types.h:167
crm_str_hash
#define crm_str_hash
Definition: util.h:62
crm_element_value_ms
int crm_element_value_ms(const xmlNode *data, const char *name, guint *dest)
Retrieve the millisecond value of an XML attribute.
Definition: nvpair.c:611
RSC_DIGEST_MATCH
@ RSC_DIGEST_MATCH
Definition: internal.h:318
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
pe_resource_s::meta
GHashTable * meta
Definition: pe_types.h:344
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_NVPAIR_ATTR_VALUE
#define XML_NVPAIR_ATTR_VALUE
Definition: msg_xml.h:340
pe_node_shared_s::pending
gboolean pending
Definition: pe_types.h:193
node_remote
@ node_remote
Definition: pe_types.h:70
XML_TAG_ATTR_SETS
#define XML_TAG_ATTR_SETS
Definition: msg_xml.h:163
uber_parent
pe_resource_t * uber_parent(pe_resource_t *rsc)
Definition: complex.c:764
ONLINESTATUS
#define ONLINESTATUS
Definition: util.h:36
pe__is_guest_or_remote_node
gboolean pe__is_guest_or_remote_node(pe_node_t *node)
Definition: remote.c:58
XML_ATTR_UNAME
#define XML_ATTR_UNAME
Definition: msg_xml.h:118
pe_ticket_s
Definition: pe_types.h:419
crm_warn
#define crm_warn(fmt, args...)
Definition: logging.h:242
pe_action_s::flags
enum pe_action_flags flags
Definition: pe_types.h:382
free_xml
void free_xml(xmlNode *child)
Definition: xml.c:2130
XML_TAG_TRANSIENT_NODEATTRS
#define XML_TAG_TRANSIENT_NODEATTRS
Definition: msg_xml.h:362
pe_resource_s::fillers
GListPtr fillers
Definition: pe_types.h:352
find_operations
GListPtr find_operations(const char *rsc, const char *node, gboolean active_filter, pe_working_set_t *data_set)
Definition: unpack.c:3778
pe_resource_s::running_on
GListPtr running_on
Definition: pe_types.h:337
pe_resource_s::partial_migration_target
pe_node_t * partial_migration_target
Definition: pe_types.h:335
pe_node_shared_s::utilization
GHashTable * utilization
Definition: pe_types.h:212
pe_rsc_is_container
#define pe_rsc_is_container
Definition: pe_types.h:251
xpath_search
xmlXPathObjectPtr xpath_search(xmlNode *xml_top, const char *path)
Definition: xpath.c:145
common_unpack
gboolean common_unpack(xmlNode *xml_obj, resource_t **rsc, resource_t *parent, pe_working_set_t *data_set)
Definition: complex.c:368
pe_node_shared_s::standby_onfail
gboolean standby_onfail
Definition: pe_types.h:192
pe_get_failcount
int pe_get_failcount(node_t *node, resource_t *rsc, time_t *last_failure, uint32_t flags, xmlNode *xml_op, pe_working_set_t *data_set)
Definition: failcounts.c:251
pe_flag_quick_location
#define pe_flag_quick_location
Definition: pe_types.h:110
xml.h
Wrappers for and extensions to libxml2.
XML_LRM_ATTR_RC
#define XML_LRM_ATTR_RC
Definition: msg_xml.h:271
pe_node_shared_s::is_dc
gboolean is_dc
Definition: pe_types.h:198
clone_strip
char * clone_strip(const char *last_rsc_id)
Definition: unpack.c:1539
crm_is_true
gboolean crm_is_true(const char *s)
Definition: strings.c:176
xml_contains_remote_node
gboolean xml_contains_remote_node(xmlNode *xml)
Definition: remote.c:92
XML_NODE_EXPECTED
#define XML_NODE_EXPECTED
Definition: msg_xml.h:239
pe_working_set_s::placement_strategy
const char * placement_strategy
Definition: pe_types.h:125
XML_CIB_TAG_STATUS
#define XML_CIB_TAG_STATUS
Definition: msg_xml.h:139
PCMK_OCF_DEGRADED
@ PCMK_OCF_DEGRADED
Definition: services.h:105
PCMK_LRM_OP_TIMEOUT
@ PCMK_LRM_OP_TIMEOUT
Definition: services.h:123
clone_zero
char * clone_zero(const char *last_rsc_id)
Definition: unpack.c:1561
pe_node_shared_s::remote_requires_reset
gboolean remote_requires_reset
Definition: pe_types.h:201
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
CRM_ATTR_ID
#define CRM_ATTR_ID
Definition: crm.h:111
pe_fence_node
void pe_fence_node(pe_working_set_t *data_set, node_t *node, const char *reason)
Schedule a fence action for a node.
Definition: unpack.c:78
pe_working_set_s::tags
GHashTable * tags
Definition: pe_types.h:161
calculate_active_ops
void calculate_active_ops(GListPtr sorted_op_list, int *start_index, int *stop_index)
Definition: unpack.c:2143
XML_ATTR_ID
#define XML_ATTR_ID
Definition: msg_xml.h:96
pe_action_s::uuid
char * uuid
Definition: pe_types.h:378
XML_TAG_UTILIZATION
#define XML_TAG_UTILIZATION
Definition: msg_xml.h:171
ID
#define ID(x)
Definition: msg_xml.h:415
XML_CIB_TAG_RESOURCE
#define XML_CIB_TAG_RESOURCE
Definition: msg_xml.h:174
pe_create_node
node_t * pe_create_node(const char *id, const char *uname, const char *type, const char *score, pe_working_set_t *data_set)
Definition: unpack.c:342
PCMK_LRM_OP_NOTSUPPORTED
@ PCMK_LRM_OP_NOTSUPPORTED
Definition: services.h:124
pe_wo_poweroff
@ pe_wo_poweroff
Definition: unpack.h:39
pe_ticket_s::id
char * id
Definition: pe_types.h:420
pe_err
#define pe_err(fmt...)
Definition: internal.h:21
action_fail_block
@ action_fail_block
Definition: common.h:40
RSC_ROLE_SLAVE
@ RSC_ROLE_SLAVE
Definition: common.h:90
pe_action_s
Definition: pe_types.h:369
pe_node_shared_s::shutdown
gboolean shutdown
Definition: pe_types.h:196
rsc_action_digest_cmp
op_digest_cache_t * rsc_action_digest_cmp(resource_t *rsc, xmlNode *xml_op, node_t *node, pe_working_set_t *data_set)
Definition: utils.c:2050
pe__create_clone_child
pe_resource_t * pe__create_clone_child(pe_resource_t *rsc, pe_working_set_t *data_set)
Definition: clone.c:60
pe_check_last_failure
@ pe_check_last_failure
Definition: pe_types.h:176
CRMD_JOINSTATE_NACK
#define CRMD_JOINSTATE_NACK
Definition: crm.h:162
crm_info
#define crm_info(fmt, args...)
Definition: logging.h:244
action_fail_fence
@ action_fail_fence
Definition: common.h:43
pe_flag_startup_fencing
#define pe_flag_startup_fencing
Definition: pe_types.h:104
CRM_LOG_ASSERT
#define CRM_LOG_ASSERT(expr)
Definition: logging.h:143
XML_CIB_TAG_PROPSET
#define XML_CIB_TAG_PROPSET
Definition: msg_xml.h:162
pe__is_remote_node
gboolean pe__is_remote_node(pe_node_t *node)
Definition: remote.c:36
pe__find_bundle_replica
pe_resource_t * pe__find_bundle_replica(const pe_resource_t *bundle, const pe_node_t *node)
Definition: bundle.c:1411
PCMK_OCF_FAILED_MASTER
@ PCMK_OCF_FAILED_MASTER
Definition: services.h:99
CRMD_ACTION_MIGRATED
#define CRMD_ACTION_MIGRATED
Definition: crm.h:169
XML_LRM_ATTR_RSCID
#define XML_LRM_ATTR_RSCID
Definition: msg_xml.h:269
CRM_ATTR_IS_DC
#define CRM_ATTR_IS_DC
Definition: crm.h:114
CRM_XS
#define CRM_XS
Definition: logging.h:34
uname
char uname[MAX_NAME]
Definition: internal.h:7
remote_id_conflict
bool remote_id_conflict(const char *remote_name, pe_working_set_t *data)
Definition: unpack.c:403
XML_LRM_ATTR_TASK
#define XML_LRM_ATTR_TASK
Definition: msg_xml.h:260
CIB_OPTIONS_FIRST
#define CIB_OPTIONS_FIRST
Definition: msg_xml.h:49
id
uint32_t id
Definition: internal.h:2
pe_rsc_orphan_container_filler
#define pe_rsc_orphan_container_filler
Definition: pe_types.h:227
pe_working_set_s::localhost
const char * localhost
Definition: pe_types.h:160
pe_node_s::fixed
gboolean fixed
Definition: pe_types.h:218
action_fail_migrate
@ action_fail_migrate
Definition: common.h:39
XML_RSC_ATTR_MANAGED
#define XML_RSC_ATTR_MANAGED
Definition: msg_xml.h:195
STATUS_PATH_MAX
#define STATUS_PATH_MAX
Definition: unpack.c:2380
action_fail_reset_remote
@ action_fail_reset_remote
Definition: common.h:52
pe_working_set_s::config_hash
GHashTable * config_hash
Definition: pe_types.h:132
role2text
const char * role2text(enum rsc_role_e role)
Definition: common.c:335
crm_strdup_printf
char * crm_strdup_printf(char const *format,...) __attribute__((__format__(__printf__
pe_flag_stop_everything
#define pe_flag_stop_everything
Definition: pe_types.h:100
PCMK_LRM_OP_PENDING
@ PCMK_LRM_OP_PENDING
Definition: services.h:120
PCMK_OCF_INVALID_PARAM
@ PCMK_OCF_INVALID_PARAM
Definition: services.h:92
CRMD_ACTION_START
#define CRMD_ACTION_START
Definition: crm.h:171
RSC_ROLE_UNKNOWN
@ RSC_ROLE_UNKNOWN
Definition: common.h:87
crm_debug
#define crm_debug(fmt, args...)
Definition: logging.h:246
PCMK_OCF_INSUFFICIENT_PRIV
@ PCMK_OCF_INSUFFICIENT_PRIV
Definition: services.h:94
CRMD_ACTION_MIGRATE
#define CRMD_ACTION_MIGRATE
Definition: crm.h:168
XML_CIB_TAG_TAG
#define XML_CIB_TAG_TAG
Definition: msg_xml.h:389
CRMD_ACTION_STOP
#define CRMD_ACTION_STOP
Definition: crm.h:174
pe_node_shared_s::standby
gboolean standby
Definition: pe_types.h:191
native_add_running
void native_add_running(resource_t *rsc, node_t *node, pe_working_set_t *data_set)
Definition: native.c:39
sort_op_by_callid
gint sort_op_by_callid(gconstpointer a, gconstpointer b)
Definition: utils.c:1610
pe_action_optional
@ pe_action_optional
Definition: pe_types.h:268
PCMK_LRM_OP_NOT_INSTALLED
@ PCMK_LRM_OP_NOT_INSTALLED
Definition: services.h:128
pe_resource_s::partial_migration_source
pe_node_t * partial_migration_source
Definition: pe_types.h:336
XML_RSC_OP_LAST_CHANGE
#define XML_RSC_OP_LAST_CHANGE
Definition: msg_xml.h:280
pe_tag_s
Definition: pe_types.h:427
determine_online_status
gboolean determine_online_status(xmlNode *node_state, node_t *this_node, pe_working_set_t *data_set)
Definition: unpack.c:1421
get_effective_time
time_t get_effective_time(pe_working_set_t *data_set)
Definition: utils.c:1727
pe_wo_blind
@ pe_wo_blind
Definition: unpack.h:36
do_crm_log
#define do_crm_log(level, fmt, args...)
Log a message.
Definition: logging.h:122
RSC_STOP
#define RSC_STOP
Definition: crm.h:199
pe_find_clone
@ pe_find_clone
match only clone instances
Definition: pe_types.h:83
crm_xml_add
const char * crm_xml_add(xmlNode *node, const char *name, const char *value)
Create an XML attribute with specified name and value.
Definition: nvpair.c:313
pe_warn_once
#define pe_warn_once(pe_wo_bit, fmt...)
Definition: unpack.h:47
action_fail_restart_container
@ action_fail_restart_container
Definition: common.h:44
PCMK_OCF_UNKNOWN_ERROR
@ PCMK_OCF_UNKNOWN_ERROR
Definition: services.h:91
pe_create_remote_xml
xmlNode * pe_create_remote_xml(xmlNode *parent, const char *uname, const char *container_id, const char *migrateable, const char *is_managed, const char *start_timeout, const char *server, const char *port)
Definition: remote.c:151
XML_LRM_TAG_RESOURCES
#define XML_LRM_TAG_RESOURCES
Definition: msg_xml.h:226
pe_working_set_s
Definition: pe_types.h:117
XML_LRM_TAG_RSC_OP
#define XML_LRM_TAG_RSC_OP
Definition: msg_xml.h:228
pe__shutdown_requested
bool pe__shutdown_requested(pe_node_t *node)
Definition: utils.c:2529
node_member
@ node_member
Definition: pe_types.h:69
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
XML_NODE_IS_FENCED
#define XML_NODE_IS_FENCED
Definition: msg_xml.h:243
node_copy
node_t * node_copy(const node_t *this_node)
Definition: utils.c:132
no_quorum_ignore
@ no_quorum_ignore
Definition: pe_types.h:63
pe_status_private.h
PCMK_LRM_OP_UNKNOWN
@ PCMK_LRM_OP_UNKNOWN
Definition: services.h:119
crm_now_string
const char * crm_now_string(time_t *when)
Definition: iso8601.c:1699
node_hash_from_list
GHashTable * node_hash_from_list(GListPtr list)
Definition: utils.c:188
CRM_TRACE_INIT_DATA
CRM_TRACE_INIT_DATA(pe_status)
XML_CIB_TAG_GROUP
#define XML_CIB_TAG_GROUP
Definition: msg_xml.h:175
sort_node_uname
gint sort_node_uname(gconstpointer a, gconstpointer b)
Definition: utils.c:231
XML_TAG_META_SETS
#define XML_TAG_META_SETS
Definition: msg_xml.h:164
pe_tag_s::refs
GListPtr refs
Definition: pe_types.h:429
crm_log_xml_debug
#define crm_log_xml_debug(xml, text)
Definition: logging.h:254
pe_working_set_s::template_rsc_sets
GHashTable * template_rsc_sets
Definition: pe_types.h:159
pe_wo
uint32_t pe_wo
Definition: unpack.c:51
ticket_new
ticket_t * ticket_new(const char *ticket_id, pe_working_set_t *data_set)
Definition: utils.c:1859
pe_ticket_s::state
GHashTable * state
Definition: pe_types.h:424
pe_base_name_end
const char * pe_base_name_end(const char *id)
Definition: unpack.c:1499
PCMK_LRM_OP_ERROR_FATAL
@ PCMK_LRM_OP_ERROR_FATAL
Definition: services.h:127
rules.h
PCMK_OCF_UNIMPLEMENT_FEATURE
@ PCMK_OCF_UNIMPLEMENT_FEATURE
Definition: services.h:93
add_tag_ref
gboolean add_tag_ref(GHashTable *tags, const char *tag_name, const char *obj_ref)
Definition: utils.c:2405
pe_resource_s::container
pe_resource_t * container
Definition: pe_types.h:351
pe__target_rc_from_xml
int pe__target_rc_from_xml(xmlNode *xml_op)
Definition: unpack.c:3250
pe_fence_op
action_t * pe_fence_op(node_t *node, const char *op, bool optional, const char *reason, pe_working_set_t *data_set)
Definition: utils.c:2289
pe_rsc_needs_fencing
#define pe_rsc_needs_fencing
Definition: pe_types.h:254
pe_flag_have_stonith_resource
#define pe_flag_have_stonith_resource
Definition: pe_types.h:94
pe_rsc_unique
#define pe_rsc_unique
Definition: pe_types.h:230
crm_parse_int
int crm_parse_int(const char *text, const char *default_text)
Parse an integer value from a string.
Definition: strings.c:114
pe_order_implies_then
@ pe_order_implies_then
Definition: pe_types.h:452
resource_location
void resource_location(resource_t *rsc, node_t *node, int score, const char *tag, pe_working_set_t *data_set)
Definition: utils.c:1566
XML_LRM_ATTR_EXIT_REASON
#define XML_LRM_ATTR_EXIT_REASON
Definition: msg_xml.h:278
XML_BOOLEAN_FALSE
#define XML_BOOLEAN_FALSE
Definition: msg_xml.h:108
PCMK_LRM_OP_ERROR_HARD
@ PCMK_LRM_OP_ERROR_HARD
Definition: services.h:126
host
AIS_Host host
Definition: internal.h:6
decode_transition_key
gboolean decode_transition_key(const char *key, char **uuid, int *action, int *transition_id, int *target_rc)
Parse a transition key into its constituent parts.
Definition: operations.c:215
pe_ticket_s::standby
gboolean standby
Definition: pe_types.h:423
XML_CIB_TAG_RSC_TEMPLATE
#define XML_CIB_TAG_RSC_TEMPLATE
Definition: msg_xml.h:180
pe_resource_s::clone_name
char * clone_name
Definition: pe_types.h:293
safe_str_neq
gboolean safe_str_neq(const char *a, const char *b)
Definition: strings.c:161
verify_pe_options
void verify_pe_options(GHashTable *options)
Definition: common.c:181
PCMK_OCF_NOT_CONFIGURED
@ PCMK_OCF_NOT_CONFIGURED
Definition: services.h:96
crm_config_warn
#define crm_config_warn(fmt...)
Definition: crm_internal.h:180
PCMK_LRM_OP_DONE
@ PCMK_LRM_OP_DONE
Definition: services.h:121
XPATH_ENABLE_UNFENCING
#define XPATH_ENABLE_UNFENCING
Definition: unpack.c:155
pe_resource_s::parent
pe_resource_t * parent
Definition: pe_types.h:299
crm_parse_interval_spec
guint crm_parse_interval_spec(const char *input)
Definition: utils.c:542
XML_LRM_ATTR_MIGRATE_TARGET
#define XML_LRM_ATTR_MIGRATE_TARGET
Definition: msg_xml.h:286
crm_str
#define crm_str(x)
Definition: logging.h:267
char2score
int char2score(const char *score)
Definition: utils.c:199
XML_LRM_ATTR_RESTART_DIGEST
#define XML_LRM_ATTR_RESTART_DIGEST
Definition: msg_xml.h:276
services.h
Services API.
pe_flag_concurrent_fencing
#define pe_flag_concurrent_fencing
Definition: pe_types.h:96
pe_resource_s::flags
unsigned long long flags
Definition: pe_types.h:319
pe_flag_maintenance_mode
#define pe_flag_maintenance_mode
Definition: pe_types.h:91
pe_resource_s::remote_reconnect_ms
guint remote_reconnect_ms
Definition: pe_types.h:316
pe_flag_enable_unfencing
#define pe_flag_enable_unfencing
Definition: pe_types.h:95
pe_flag_remove_after_stop
#define pe_flag_remove_after_stop
Definition: pe_types.h:103
unpack_nodes
gboolean unpack_nodes(xmlNode *xml_nodes, pe_working_set_t *data_set)
Definition: unpack.c:514
PCMK_OCF_RUNNING_MASTER
@ PCMK_OCF_RUNNING_MASTER
Definition: services.h:98
pe_resource_s::role
enum rsc_role_e role
Definition: pe_types.h:341
pe_rsc_trace
#define pe_rsc_trace(rsc, fmt, args...)
Definition: internal.h:19
PCMK_OCF_OK
@ PCMK_OCF_OK
Definition: services.h:90
XML_ATTR_TRANSITION_MAGIC
#define XML_ATTR_TRANSITION_MAGIC
Definition: msg_xml.h:357
XML_NODE_IS_PEER
#define XML_NODE_IS_PEER
Definition: msg_xml.h:241
pe_node_shared_s::remote_was_fenced
gboolean remote_was_fenced
Definition: pe_types.h:202
pe_flag_startup_probes
#define pe_flag_startup_probes
Definition: pe_types.h:106
crm_ends_with
gboolean crm_ends_with(const char *s, const char *match)
Definition: strings.c:313
pe__add_param_check
void pe__add_param_check(xmlNode *rsc_op, pe_resource_t *rsc, pe_node_t *node, enum pe_check_parameters, pe_working_set_t *data_set)
Definition: remote.c:215
CRM_ASSERT
#define CRM_ASSERT(expr)
Definition: results.h:42
find_xml_node
xmlNode * find_xml_node(xmlNode *cib, const char *node_path, gboolean must_find)
Definition: xml.c:1758
pe__bundle_needs_remote_name
bool pe__bundle_needs_remote_name(pe_resource_t *rsc)
Definition: bundle.c:955
pe__resource_actions
GList * pe__resource_actions(const pe_resource_t *rsc, const pe_node_t *node, const char *task, bool require_node)
Find all actions of given type for a resource.
Definition: utils.c:1518
pe_rsc_start_pending
#define pe_rsc_start_pending
Definition: pe_types.h:243
XML_ATTR_QUORUM_PANIC
#define XML_ATTR_QUORUM_PANIC
Definition: msg_xml.h:84
pe_working_set_s::tickets
GHashTable * tickets
Definition: pe_types.h:133
pe_node_shared_s
Definition: pe_types.h:184
pe_flag_start_failure_fatal
#define pe_flag_start_failure_fatal
Definition: pe_types.h:102
pe__clear_failcount
pe_action_t * pe__clear_failcount(pe_resource_t *rsc, pe_node_t *node, const char *reason, pe_working_set_t *data_set)
Schedule a controller operation to clear a fail count.
Definition: failcounts.c:360
CRMD_ACTION_DEMOTE
#define CRMD_ACTION_DEMOTE
Definition: crm.h:179
set_config_flag
#define set_config_flag(data_set, option, flag)
Definition: unpack.c:30
pe_rsc_managed
#define pe_rsc_managed
Definition: pe_types.h:225
pe_action_s::fail_role
enum rsc_role_e fail_role
Definition: pe_types.h:385
action_fail_ignore
@ action_fail_ignore
Definition: common.h:37
iso8601_internal.h
CRMD_ACTION_STATUS
#define CRMD_ACTION_STATUS
Definition: crm.h:185
pe_node_shared_s::unpacked
gboolean unpacked
Definition: pe_types.h:204
pe_resource_s::pending_task
char * pending_task
Definition: pe_types.h:317
unpack.h
XML_LRM_ATTR_INTERVAL_MS
#define XML_LRM_ATTR_INTERVAL_MS
Definition: msg_xml.h:258
unpack_resources
gboolean unpack_resources(xmlNode *xml_resources, pe_working_set_t *data_set)
Definition: unpack.c:740
no_quorum_suicide
@ no_quorum_suicide
Definition: pe_types.h:64
crm_atoi
#define crm_atoi(text, default_text)
Definition: util.h:110
PCMK_OCF_NOT_RUNNING
@ PCMK_OCF_NOT_RUNNING
Definition: services.h:97
node_score_red
int node_score_red
Definition: utils.c:63
pe_node_shared_s::remote_maintenance
gboolean remote_maintenance
Definition: pe_types.h:203
pe_node_attribute_raw
const char * pe_node_attribute_raw(pe_node_t *node, const char *name)
Definition: common.c:468
XML_ATTR_TYPE
#define XML_ATTR_TYPE
Definition: msg_xml.h:99
RSC_DIGEST_UNKNOWN
@ RSC_DIGEST_UNKNOWN
Definition: internal.h:325
pe_rsc_promotable
#define pe_rsc_promotable
Definition: pe_types.h:232
copy_in_properties
void copy_in_properties(xmlNode *target, xmlNode *src)
Definition: xml.c:1830
pe_flag_stonith_enabled
#define pe_flag_stonith_enabled
Definition: pe_types.h:93
pe_node_shared_s::maintenance
gboolean maintenance
Definition: pe_types.h:199
pe__is_guest_node
gboolean pe__is_guest_node(pe_node_t *node)
Definition: remote.c:47
pe_resource_s
Definition: pe_types.h:291
pe_resource_s::allowed_nodes
GHashTable * allowed_nodes
Definition: pe_types.h:339
pe_working_set_s::flags
unsigned long long flags
Definition: pe_types.h:127
pe_node_shared_s::unclean
gboolean unclean
Definition: pe_types.h:194
XML_ATTR_HAVE_WATCHDOG
#define XML_ATTR_HAVE_WATCHDOG
Definition: msg_xml.h:86
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
RSC_ROLE_STARTED
@ RSC_ROLE_STARTED
Definition: common.h:89
pe_working_set_s::no_quorum_policy
enum pe_quorum_policy no_quorum_policy
Definition: pe_types.h:130
crm_element_value_epoch
int crm_element_value_epoch(const xmlNode *xml, const char *name, time_t *dest)
Retrieve the seconds-since-epoch value of an XML attribute.
Definition: nvpair.c:633
pe_flag_symmetric_cluster
#define pe_flag_symmetric_cluster
Definition: pe_types.h:90
generate_op_key
char * generate_op_key(const char *rsc_id, const char *op_type, guint interval_ms)
Generate an operation key.
Definition: operations.c:39
XML_LRM_ATTR_CALLID
#define XML_LRM_ATTR_CALLID
Definition: msg_xml.h:272
pe_resource_s::failure_timeout
int failure_timeout
Definition: pe_types.h:314
CRM_ATTR_SITE_NAME
#define CRM_ATTR_SITE_NAME
Definition: crm.h:116
XML_CIB_TAG_NODE
#define XML_CIB_TAG_NODE
Definition: msg_xml.h:159
pe_node_shared_s::type
enum node_type type
Definition: pe_types.h:187
pe_node_shared_s::online
gboolean online
Definition: pe_types.h:190
pe_node_shared_s::uname
const char * uname
Definition: pe_types.h:186
no_quorum_stop
@ no_quorum_stop
Definition: pe_types.h:62
pe_free_action
void pe_free_action(action_t *action)
Definition: utils.c:1314
strndup
char * strndup(const char *str, size_t len)
destroy_ticket
void destroy_ticket(gpointer data)
Definition: utils.c:1847
XML_NODE_IS_MAINTENANCE
#define XML_NODE_IS_MAINTENANCE
Definition: msg_xml.h:244
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
PCMK_OCF_NOT_INSTALLED
@ PCMK_OCF_NOT_INSTALLED
Definition: services.h:95
pe_flag_stop_rsc_orphans
#define pe_flag_stop_rsc_orphans
Definition: pe_types.h:98
add_node_copy
xmlNode * add_node_copy(xmlNode *new_parent, xmlNode *xml_node)
Definition: xml.c:1948
pe_resource_s::is_remote_node
gboolean is_remote_node
Definition: pe_types.h:322
crm_internal.h
util.h
Utility functions.
pe_node_s
Definition: pe_types.h:216
pe__is_universal_clone
bool pe__is_universal_clone(pe_resource_t *rsc, pe_working_set_t *data_set)
Definition: clone.c:1032
freeXpathObject
void freeXpathObject(xmlXPathObjectPtr xpathObj)
Definition: xpath.c:45
pe_flag_have_quorum
#define pe_flag_have_quorum
Definition: pe_types.h:89
XML_CIB_TAG_OBJ_REF
#define XML_CIB_TAG_OBJ_REF
Definition: msg_xml.h:390
crm.h
A dumping ground.
node_score_green
int node_score_green
Definition: utils.c:64
CRMD_ACTION_PROMOTE
#define CRMD_ACTION_PROMOTE
Definition: crm.h:177
XML_RSC_ATTR_CONTAINER
#define XML_RSC_ATTR_CONTAINER
Definition: msg_xml.h:205
XML_NVPAIR_ATTR_NAME
#define XML_NVPAIR_ATTR_NAME
Definition: msg_xml.h:339
pe_rsc_block
#define pe_rsc_block
Definition: pe_types.h:226
fail2text
const char * fail2text(enum action_fail_response fail)
Definition: common.c:193
XML_BOOLEAN_TRUE
#define XML_BOOLEAN_TRUE
Definition: msg_xml.h:107
pe_rsc_failure_ignored
#define pe_rsc_failure_ignored
Definition: pe_types.h:249
pe_resource_s::fns
resource_object_functions_t * fns
Definition: pe_types.h:303
pcmk_ok
#define pcmk_ok
Definition: results.h:57
pe_flag_have_remote_nodes
#define pe_flag_have_remote_nodes
Definition: pe_types.h:108
unpack_status
gboolean unpack_status(xmlNode *status, pe_working_set_t *data_set)
Definition: unpack.c:1090
node_ping
@ node_ping
Definition: pe_types.h:68
pe_node_shared_s::attrs
GHashTable * attrs
Definition: pe_types.h:211
crm_config_err
#define crm_config_err(fmt...)
Definition: crm_internal.h:179
op_digest_cache_s
Definition: internal.h:328
pe_proc_err
#define pe_proc_err(fmt...)
Definition: internal.h:23
pe_rsc_failed
#define pe_rsc_failed
Definition: pe_types.h:241