This source file includes following definitions.
- is_dangling_guest_node
 
- pe_fence_node
 
- set_if_xpath
 
- unpack_config
 
- pe_create_node
 
- expand_remote_rsc_meta
 
- handle_startup_fencing
 
- unpack_nodes
 
- setup_container
 
- unpack_remote_nodes
 
- link_rsc2remotenode
 
- destroy_tag
 
- unpack_resources
 
- unpack_tags
 
- unpack_ticket_state
 
- unpack_tickets_state
 
- unpack_handle_remote_attrs
 
- unpack_transient_attributes
 
- unpack_node_state
 
- unpack_node_history
 
- unpack_status
 
- determine_online_status_no_fencing
 
- determine_online_status_fencing
 
- determine_remote_online_status
 
- determine_online_status
 
- pe_base_name_end
 
- clone_strip
 
- clone_zero
 
- create_fake_resource
 
- create_anonymous_orphan
 
- find_anonymous_clone
 
- unpack_find_resource
 
- process_orphan_resource
 
- process_rsc_state
 
- process_recurring
 
- calculate_active_ops
 
- unpack_shutdown_lock
 
- unpack_lrm_resource
 
- handle_orphaned_container_fillers
 
- unpack_node_lrm
 
- set_active
 
- set_node_score
 
- find_lrm_op
 
- pe__call_id
 
- stop_happened_after
 
- unpack_migrate_to_success
 
- newer_op
 
- unpack_migrate_to_failure
 
- unpack_migrate_from_failure
 
- record_failed_op
 
- get_op_key
 
- last_change_str
 
- cmp_on_fail
 
- unpack_rsc_op_failure
 
- remap_operation
 
- should_clear_for_param_change
 
- order_after_remote_fencing
 
- should_ignore_failure_timeout
 
- check_operation_expiry
 
- pe__target_rc_from_xml
 
- get_action_on_fail
 
- update_resource_state
 
- unpack_rsc_op
 
- add_node_attrs
 
- extract_operations
 
- find_operations
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 #include <crm_internal.h>
  11 
  12 #include <stdio.h>
  13 #include <string.h>
  14 #include <glib.h>
  15 #include <time.h>
  16 
  17 #include <crm/crm.h>
  18 #include <crm/services.h>
  19 #include <crm/msg_xml.h>
  20 #include <crm/common/xml.h>
  21 #include <crm/common/xml_internal.h>
  22 
  23 #include <crm/common/util.h>
  24 #include <crm/pengine/rules.h>
  25 #include <crm/pengine/internal.h>
  26 #include <pe_status_private.h>
  27 
  28 CRM_TRACE_INIT_DATA(pe_status);
  29 
  30 
  31 
  32 
  33 
  34 #define set_config_flag(data_set, option, flag) do {                        \
  35         const char *scf_value = pe_pref((data_set)->config_hash, (option)); \
  36         if (scf_value != NULL) {                                            \
  37             if (crm_is_true(scf_value)) {                                   \
  38                 (data_set)->flags = pcmk__set_flags_as(__func__, __LINE__,  \
  39                                     LOG_TRACE, "Working set",               \
  40                                     crm_system_name, (data_set)->flags,     \
  41                                     (flag), #flag);                         \
  42             } else {                                                        \
  43                 (data_set)->flags = pcmk__clear_flags_as(__func__, __LINE__,\
  44                                     LOG_TRACE, "Working set",               \
  45                                     crm_system_name, (data_set)->flags,     \
  46                                     (flag), #flag);                         \
  47             }                                                               \
  48         }                                                                   \
  49     } while(0)
  50 
  51 static void unpack_rsc_op(pe_resource_t *rsc, pe_node_t *node, xmlNode *xml_op,
  52                           xmlNode **last_failure,
  53                           enum action_fail_response *failed,
  54                           pe_working_set_t *data_set);
  55 static void determine_remote_online_status(pe_working_set_t *data_set,
  56                                            pe_node_t *this_node);
  57 static void add_node_attrs(xmlNode *attrs, pe_node_t *node, bool overwrite,
  58                            pe_working_set_t *data_set);
  59 static void determine_online_status(xmlNode *node_state, pe_node_t *this_node,
  60                                     pe_working_set_t *data_set);
  61 
  62 static void unpack_node_lrm(pe_node_t *node, xmlNode *xml,
  63                             pe_working_set_t *data_set);
  64 
  65 
  66 
  67 uint32_t pe_wo = 0;
  68 
  69 static gboolean
  70 is_dangling_guest_node(pe_node_t *node)
     
  71 {
  72     
  73 
  74 
  75     if (pe__is_guest_or_remote_node(node) &&
  76         node->details->remote_rsc &&
  77         node->details->remote_rsc->container == NULL &&
  78         pcmk_is_set(node->details->remote_rsc->flags,
  79                     pe_rsc_orphan_container_filler)) {
  80         return TRUE;
  81     }
  82 
  83     return FALSE;
  84 }
  85 
  86 
  87 
  88 
  89 
  90 
  91 
  92 
  93 
  94 void
  95 pe_fence_node(pe_working_set_t * data_set, pe_node_t * node,
     
  96               const char *reason, bool priority_delay)
  97 {
  98     CRM_CHECK(node, return);
  99 
 100     
 101     if (pe__is_guest_node(node)) {
 102         pe_resource_t *rsc = node->details->remote_rsc->container;
 103 
 104         if (!pcmk_is_set(rsc->flags, pe_rsc_failed)) {
 105             if (!pcmk_is_set(rsc->flags, pe_rsc_managed)) {
 106                 crm_notice("Not fencing guest node %s "
 107                            "(otherwise would because %s): "
 108                            "its guest resource %s is unmanaged",
 109                            node->details->uname, reason, rsc->id);
 110             } else {
 111                 crm_warn("Guest node %s will be fenced "
 112                          "(by recovering its guest resource %s): %s",
 113                          node->details->uname, rsc->id, reason);
 114 
 115                 
 116 
 117 
 118 
 119                 node->details->remote_requires_reset = TRUE;
 120                 pe__set_resource_flags(rsc, pe_rsc_failed|pe_rsc_stop);
 121             }
 122         }
 123 
 124     } else if (is_dangling_guest_node(node)) {
 125         crm_info("Cleaning up dangling connection for guest node %s: "
 126                  "fencing was already done because %s, "
 127                  "and guest resource no longer exists",
 128                  node->details->uname, reason);
 129         pe__set_resource_flags(node->details->remote_rsc,
 130                                pe_rsc_failed|pe_rsc_stop);
 131 
 132     } else if (pe__is_remote_node(node)) {
 133         pe_resource_t *rsc = node->details->remote_rsc;
 134 
 135         if ((rsc != NULL) && !pcmk_is_set(rsc->flags, pe_rsc_managed)) {
 136             crm_notice("Not fencing remote node %s "
 137                        "(otherwise would because %s): connection is unmanaged",
 138                        node->details->uname, reason);
 139         } else if(node->details->remote_requires_reset == FALSE) {
 140             node->details->remote_requires_reset = TRUE;
 141             crm_warn("Remote node %s %s: %s",
 142                      node->details->uname,
 143                      pe_can_fence(data_set, node)? "will be fenced" : "is unclean",
 144                      reason);
 145         }
 146         node->details->unclean = TRUE;
 147         
 148         pe_fence_op(node, NULL, TRUE, reason, FALSE, data_set);
 149 
 150     } else if (node->details->unclean) {
 151         crm_trace("Cluster node %s %s because %s",
 152                   node->details->uname,
 153                   pe_can_fence(data_set, node)? "would also be fenced" : "also is unclean",
 154                   reason);
 155 
 156     } else {
 157         crm_warn("Cluster node %s %s: %s",
 158                  node->details->uname,
 159                  pe_can_fence(data_set, node)? "will be fenced" : "is unclean",
 160                  reason);
 161         node->details->unclean = TRUE;
 162         pe_fence_op(node, NULL, TRUE, reason, priority_delay, data_set);
 163     }
 164 }
 165 
 166 
 167 
 168 
 169 #define XPATH_UNFENCING_NVPAIR XML_CIB_TAG_NVPAIR                \
 170     "[(@" XML_NVPAIR_ATTR_NAME "='" PCMK_STONITH_PROVIDES "'"    \
 171     "or @" XML_NVPAIR_ATTR_NAME "='" XML_RSC_ATTR_REQUIRES "') " \
 172     "and @" XML_NVPAIR_ATTR_VALUE "='unfencing']"
 173 
 174 
 175 #define XPATH_ENABLE_UNFENCING \
 176     "/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RESOURCES   \
 177     "//" XML_TAG_META_SETS "/" XPATH_UNFENCING_NVPAIR                                               \
 178     "|/" XML_TAG_CIB "/" XML_CIB_TAG_CONFIGURATION "/" XML_CIB_TAG_RSCCONFIG  \
 179     "/" XML_TAG_META_SETS "/" XPATH_UNFENCING_NVPAIR
 180 
 181 static void
 182 set_if_xpath(uint64_t flag, const char *xpath, pe_working_set_t *data_set)
     
 183 {
 184     xmlXPathObjectPtr result = NULL;
 185 
 186     if (!pcmk_is_set(data_set->flags, flag)) {
 187         result = xpath_search(data_set->input, xpath);
 188         if (result && (numXpathResults(result) > 0)) {
 189             pe__set_working_set_flags(data_set, flag);
 190         }
 191         freeXpathObject(result);
 192     }
 193 }
 194 
 195 gboolean
 196 unpack_config(xmlNode * config, pe_working_set_t * data_set)
     
 197 {
 198     const char *value = NULL;
 199     GHashTable *config_hash = pcmk__strkey_table(free, free);
 200 
 201     pe_rule_eval_data_t rule_data = {
 202         .node_hash = NULL,
 203         .role = RSC_ROLE_UNKNOWN,
 204         .now = data_set->now,
 205         .match_data = NULL,
 206         .rsc_data = NULL,
 207         .op_data = NULL
 208     };
 209 
 210     data_set->config_hash = config_hash;
 211 
 212     pe__unpack_dataset_nvpairs(config, XML_CIB_TAG_PROPSET, &rule_data, config_hash,
 213                                CIB_OPTIONS_FIRST, FALSE, data_set);
 214 
 215     verify_pe_options(data_set->config_hash);
 216 
 217     set_config_flag(data_set, "enable-startup-probes", pe_flag_startup_probes);
 218     if (!pcmk_is_set(data_set->flags, pe_flag_startup_probes)) {
 219         crm_info("Startup probes: disabled (dangerous)");
 220     }
 221 
 222     value = pe_pref(data_set->config_hash, XML_ATTR_HAVE_WATCHDOG);
 223     if (value && crm_is_true(value)) {
 224         crm_info("Watchdog-based self-fencing will be performed via SBD if "
 225                  "fencing is required and stonith-watchdog-timeout is nonzero");
 226         pe__set_working_set_flags(data_set, pe_flag_have_stonith_resource);
 227     }
 228 
 229     
 230 
 231 
 232     set_if_xpath(pe_flag_enable_unfencing, XPATH_ENABLE_UNFENCING, data_set);
 233 
 234     value = pe_pref(data_set->config_hash, "stonith-timeout");
 235     data_set->stonith_timeout = (int) crm_parse_interval_spec(value);
 236     crm_debug("STONITH timeout: %d", data_set->stonith_timeout);
 237 
 238     set_config_flag(data_set, "stonith-enabled", pe_flag_stonith_enabled);
 239     crm_debug("STONITH of failed nodes is %s",
 240               pcmk_is_set(data_set->flags, pe_flag_stonith_enabled)? "enabled" : "disabled");
 241 
 242     data_set->stonith_action = pe_pref(data_set->config_hash, "stonith-action");
 243     if (!strcmp(data_set->stonith_action, "poweroff")) {
 244         pe_warn_once(pe_wo_poweroff,
 245                      "Support for stonith-action of 'poweroff' is deprecated "
 246                      "and will be removed in a future release (use 'off' instead)");
 247         data_set->stonith_action = "off";
 248     }
 249     crm_trace("STONITH will %s nodes", data_set->stonith_action);
 250 
 251     set_config_flag(data_set, "concurrent-fencing", pe_flag_concurrent_fencing);
 252     crm_debug("Concurrent fencing is %s",
 253               pcmk_is_set(data_set->flags, pe_flag_concurrent_fencing)? "enabled" : "disabled");
 254 
 255     value = pe_pref(data_set->config_hash,
 256                     XML_CONFIG_ATTR_PRIORITY_FENCING_DELAY);
 257     if (value) {
 258         data_set->priority_fencing_delay = crm_parse_interval_spec(value) / 1000;
 259         crm_trace("Priority fencing delay is %ds", data_set->priority_fencing_delay);
 260     }
 261 
 262     set_config_flag(data_set, "stop-all-resources", pe_flag_stop_everything);
 263     crm_debug("Stop all active resources: %s",
 264               pcmk__btoa(pcmk_is_set(data_set->flags, pe_flag_stop_everything)));
 265 
 266     set_config_flag(data_set, "symmetric-cluster", pe_flag_symmetric_cluster);
 267     if (pcmk_is_set(data_set->flags, pe_flag_symmetric_cluster)) {
 268         crm_debug("Cluster is symmetric" " - resources can run anywhere by default");
 269     }
 270 
 271     value = pe_pref(data_set->config_hash, "no-quorum-policy");
 272 
 273     if (pcmk__str_eq(value, "ignore", pcmk__str_casei)) {
 274         data_set->no_quorum_policy = no_quorum_ignore;
 275 
 276     } else if (pcmk__str_eq(value, "freeze", pcmk__str_casei)) {
 277         data_set->no_quorum_policy = no_quorum_freeze;
 278 
 279     } else if (pcmk__str_eq(value, "demote", pcmk__str_casei)) {
 280         data_set->no_quorum_policy = no_quorum_demote;
 281 
 282     } else if (pcmk__str_eq(value, "suicide", pcmk__str_casei)) {
 283         if (pcmk_is_set(data_set->flags, pe_flag_stonith_enabled)) {
 284             int do_panic = 0;
 285 
 286             crm_element_value_int(data_set->input, XML_ATTR_QUORUM_PANIC,
 287                                   &do_panic);
 288             if (do_panic || pcmk_is_set(data_set->flags, pe_flag_have_quorum)) {
 289                 data_set->no_quorum_policy = no_quorum_suicide;
 290             } else {
 291                 crm_notice("Resetting no-quorum-policy to 'stop': cluster has never had quorum");
 292                 data_set->no_quorum_policy = no_quorum_stop;
 293             }
 294         } else {
 295             pcmk__config_err("Resetting no-quorum-policy to 'stop' because "
 296                              "fencing is disabled");
 297             data_set->no_quorum_policy = no_quorum_stop;
 298         }
 299 
 300     } else {
 301         data_set->no_quorum_policy = no_quorum_stop;
 302     }
 303 
 304     switch (data_set->no_quorum_policy) {
 305         case no_quorum_freeze:
 306             crm_debug("On loss of quorum: Freeze resources");
 307             break;
 308         case no_quorum_stop:
 309             crm_debug("On loss of quorum: Stop ALL resources");
 310             break;
 311         case no_quorum_demote:
 312             crm_debug("On loss of quorum: "
 313                       "Demote promotable resources and stop other resources");
 314             break;
 315         case no_quorum_suicide:
 316             crm_notice("On loss of quorum: Fence all remaining nodes");
 317             break;
 318         case no_quorum_ignore:
 319             crm_notice("On loss of quorum: Ignore");
 320             break;
 321     }
 322 
 323     set_config_flag(data_set, "stop-orphan-resources", pe_flag_stop_rsc_orphans);
 324     crm_trace("Orphan resources are %s",
 325               pcmk_is_set(data_set->flags, pe_flag_stop_rsc_orphans)? "stopped" : "ignored");
 326 
 327     set_config_flag(data_set, "stop-orphan-actions", pe_flag_stop_action_orphans);
 328     crm_trace("Orphan resource actions are %s",
 329               pcmk_is_set(data_set->flags, pe_flag_stop_action_orphans)? "stopped" : "ignored");
 330 
 331     value = pe_pref(data_set->config_hash, "remove-after-stop");
 332     if (value != NULL) {
 333         if (crm_is_true(value)) {
 334             pe__set_working_set_flags(data_set, pe_flag_remove_after_stop);
 335 #ifndef PCMK__COMPAT_2_0
 336             pe_warn_once(pe_wo_remove_after,
 337                          "Support for the remove-after-stop cluster property is"
 338                          " deprecated and will be removed in a future release");
 339 #endif
 340         } else {
 341             pe__clear_working_set_flags(data_set, pe_flag_remove_after_stop);
 342         }
 343     }
 344 
 345     set_config_flag(data_set, "maintenance-mode", pe_flag_maintenance_mode);
 346     crm_trace("Maintenance mode: %s",
 347               pcmk__btoa(pcmk_is_set(data_set->flags, pe_flag_maintenance_mode)));
 348 
 349     set_config_flag(data_set, "start-failure-is-fatal", pe_flag_start_failure_fatal);
 350     crm_trace("Start failures are %s",
 351               pcmk_is_set(data_set->flags, pe_flag_start_failure_fatal)? "always fatal" : "handled by failcount");
 352 
 353     if (pcmk_is_set(data_set->flags, pe_flag_stonith_enabled)) {
 354         set_config_flag(data_set, "startup-fencing", pe_flag_startup_fencing);
 355     }
 356     if (pcmk_is_set(data_set->flags, pe_flag_startup_fencing)) {
 357         crm_trace("Unseen nodes will be fenced");
 358     } else {
 359         pe_warn_once(pe_wo_blind, "Blind faith: not fencing unseen nodes");
 360     }
 361 
 362     pe__unpack_node_health_scores(data_set);
 363 
 364     data_set->placement_strategy = pe_pref(data_set->config_hash, "placement-strategy");
 365     crm_trace("Placement strategy: %s", data_set->placement_strategy);
 366 
 367     set_config_flag(data_set, "shutdown-lock", pe_flag_shutdown_lock);
 368     crm_trace("Resources will%s be locked to cleanly shut down nodes",
 369               (pcmk_is_set(data_set->flags, pe_flag_shutdown_lock)? "" : " not"));
 370     if (pcmk_is_set(data_set->flags, pe_flag_shutdown_lock)) {
 371         value = pe_pref(data_set->config_hash,
 372                         XML_CONFIG_ATTR_SHUTDOWN_LOCK_LIMIT);
 373         data_set->shutdown_lock = crm_parse_interval_spec(value) / 1000;
 374         crm_trace("Shutdown locks expire after %us", data_set->shutdown_lock);
 375     }
 376 
 377     return TRUE;
 378 }
 379 
 380 pe_node_t *
 381 pe_create_node(const char *id, const char *uname, const char *type,
     
 382                const char *score, pe_working_set_t * data_set)
 383 {
 384     pe_node_t *new_node = NULL;
 385 
 386     if (pe_find_node(data_set->nodes, uname) != NULL) {
 387         pcmk__config_warn("More than one node entry has name '%s'", uname);
 388     }
 389 
 390     new_node = calloc(1, sizeof(pe_node_t));
 391     if (new_node == NULL) {
 392         return NULL;
 393     }
 394 
 395     new_node->weight = char2score(score);
 396     new_node->fixed = FALSE;
 397     new_node->details = calloc(1, sizeof(struct pe_node_shared_s));
 398 
 399     if (new_node->details == NULL) {
 400         free(new_node);
 401         return NULL;
 402     }
 403 
 404     crm_trace("Creating node for entry %s/%s", uname, id);
 405     new_node->details->id = id;
 406     new_node->details->uname = uname;
 407     new_node->details->online = FALSE;
 408     new_node->details->shutdown = FALSE;
 409     new_node->details->rsc_discovery_enabled = TRUE;
 410     new_node->details->running_rsc = NULL;
 411     new_node->details->data_set = data_set;
 412 
 413     if (pcmk__str_eq(type, "member", pcmk__str_null_matches | pcmk__str_casei)) {
 414         new_node->details->type = node_member;
 415 
 416     } else if (pcmk__str_eq(type, "remote", pcmk__str_casei)) {
 417         new_node->details->type = node_remote;
 418         pe__set_working_set_flags(data_set, pe_flag_have_remote_nodes);
 419 
 420     } else {
 421         
 422 
 423 
 424         if (!pcmk__str_eq(type, "ping", pcmk__str_casei)) {
 425             pcmk__config_warn("Node %s has unrecognized type '%s', "
 426                               "assuming 'ping'", crm_str(uname), type);
 427         }
 428         pe_warn_once(pe_wo_ping_node,
 429                      "Support for nodes of type 'ping' (such as %s) is "
 430                      "deprecated and will be removed in a future release",
 431                      crm_str(uname));
 432         new_node->details->type = node_ping;
 433     }
 434 
 435     new_node->details->attrs = pcmk__strkey_table(free, free);
 436 
 437     if (pe__is_guest_or_remote_node(new_node)) {
 438         g_hash_table_insert(new_node->details->attrs, strdup(CRM_ATTR_KIND),
 439                             strdup("remote"));
 440     } else {
 441         g_hash_table_insert(new_node->details->attrs, strdup(CRM_ATTR_KIND),
 442                             strdup("cluster"));
 443     }
 444 
 445     new_node->details->utilization = pcmk__strkey_table(free, free);
 446     new_node->details->digest_cache = pcmk__strkey_table(free,
 447                                                           pe__free_digests);
 448 
 449     data_set->nodes = g_list_insert_sorted(data_set->nodes, new_node, sort_node_uname);
 450     return new_node;
 451 }
 452 
 453 static const char *
 454 expand_remote_rsc_meta(xmlNode *xml_obj, xmlNode *parent, pe_working_set_t *data)
     
 455 {
 456     xmlNode *attr_set = NULL;
 457     xmlNode *attr = NULL;
 458 
 459     const char *container_id = ID(xml_obj);
 460     const char *remote_name = NULL;
 461     const char *remote_server = NULL;
 462     const char *remote_port = NULL;
 463     const char *connect_timeout = "60s";
 464     const char *remote_allow_migrate=NULL;
 465     const char *is_managed = NULL;
 466 
 467     for (attr_set = pcmk__xe_first_child(xml_obj); attr_set != NULL;
 468          attr_set = pcmk__xe_next(attr_set)) {
 469 
 470         if (!pcmk__str_eq((const char *)attr_set->name, XML_TAG_META_SETS,
 471                           pcmk__str_casei)) {
 472             continue;
 473         }
 474 
 475         for (attr = pcmk__xe_first_child(attr_set); attr != NULL;
 476              attr = pcmk__xe_next(attr)) {
 477             const char *value = crm_element_value(attr, XML_NVPAIR_ATTR_VALUE);
 478             const char *name = crm_element_value(attr, XML_NVPAIR_ATTR_NAME);
 479 
 480             if (pcmk__str_eq(name, XML_RSC_ATTR_REMOTE_NODE, pcmk__str_casei)) {
 481                 remote_name = value;
 482             } else if (pcmk__str_eq(name, "remote-addr", pcmk__str_casei)) {
 483                 remote_server = value;
 484             } else if (pcmk__str_eq(name, "remote-port", pcmk__str_casei)) {
 485                 remote_port = value;
 486             } else if (pcmk__str_eq(name, "remote-connect-timeout", pcmk__str_casei)) {
 487                 connect_timeout = value;
 488             } else if (pcmk__str_eq(name, "remote-allow-migrate", pcmk__str_casei)) {
 489                 remote_allow_migrate=value;
 490             } else if (pcmk__str_eq(name, XML_RSC_ATTR_MANAGED, pcmk__str_casei)) {
 491                 is_managed = value;
 492             }
 493         }
 494     }
 495 
 496     if (remote_name == NULL) {
 497         return NULL;
 498     }
 499 
 500     if (pe_find_resource(data->resources, remote_name) != NULL) {
 501         return NULL;
 502     }
 503 
 504     pe_create_remote_xml(parent, remote_name, container_id,
 505                          remote_allow_migrate, is_managed,
 506                          connect_timeout, remote_server, remote_port);
 507     return remote_name;
 508 }
 509 
 510 static void
 511 handle_startup_fencing(pe_working_set_t *data_set, pe_node_t *new_node)
     
 512 {
 513     if ((new_node->details->type == node_remote) && (new_node->details->remote_rsc == NULL)) {
 514         
 515 
 516 
 517 
 518         return;
 519     }
 520 
 521     if (pcmk_is_set(data_set->flags, pe_flag_startup_fencing)) {
 522         
 523         new_node->details->unclean = TRUE;
 524 
 525     } else {
 526         
 527         new_node->details->unclean = FALSE;
 528     }
 529 
 530     
 531 
 532     new_node->details->unseen = TRUE;
 533 }
 534 
 535 gboolean
 536 unpack_nodes(xmlNode * xml_nodes, pe_working_set_t * data_set)
     
 537 {
 538     xmlNode *xml_obj = NULL;
 539     pe_node_t *new_node = NULL;
 540     const char *id = NULL;
 541     const char *uname = NULL;
 542     const char *type = NULL;
 543     const char *score = NULL;
 544 
 545     pe_rule_eval_data_t rule_data = {
 546         .node_hash = NULL,
 547         .role = RSC_ROLE_UNKNOWN,
 548         .now = data_set->now,
 549         .match_data = NULL,
 550         .rsc_data = NULL,
 551         .op_data = NULL
 552     };
 553 
 554     for (xml_obj = pcmk__xe_first_child(xml_nodes); xml_obj != NULL;
 555          xml_obj = pcmk__xe_next(xml_obj)) {
 556 
 557         if (pcmk__str_eq((const char *)xml_obj->name, XML_CIB_TAG_NODE, pcmk__str_none)) {
 558             new_node = NULL;
 559 
 560             id = crm_element_value(xml_obj, XML_ATTR_ID);
 561             uname = crm_element_value(xml_obj, XML_ATTR_UNAME);
 562             type = crm_element_value(xml_obj, XML_ATTR_TYPE);
 563             score = crm_element_value(xml_obj, XML_RULE_ATTR_SCORE);
 564             crm_trace("Processing node %s/%s", uname, id);
 565 
 566             if (id == NULL) {
 567                 pcmk__config_err("Ignoring <" XML_CIB_TAG_NODE
 568                                  "> entry in configuration without id");
 569                 continue;
 570             }
 571             new_node = pe_create_node(id, uname, type, score, data_set);
 572 
 573             if (new_node == NULL) {
 574                 return FALSE;
 575             }
 576 
 577 
 578 
 579 
 580 
 581 
 582 
 583             handle_startup_fencing(data_set, new_node);
 584 
 585             add_node_attrs(xml_obj, new_node, FALSE, data_set);
 586             pe__unpack_dataset_nvpairs(xml_obj, XML_TAG_UTILIZATION, &rule_data,
 587                                        new_node->details->utilization, NULL,
 588                                        FALSE, data_set);
 589 
 590             crm_trace("Done with node %s", crm_element_value(xml_obj, XML_ATTR_UNAME));
 591         }
 592     }
 593 
 594     if (data_set->localhost && pe_find_node(data_set->nodes, data_set->localhost) == NULL) {
 595         crm_info("Creating a fake local node");
 596         pe_create_node(data_set->localhost, data_set->localhost, NULL, 0,
 597                        data_set);
 598     }
 599 
 600     return TRUE;
 601 }
 602 
 603 static void
 604 setup_container(pe_resource_t * rsc, pe_working_set_t * data_set)
     
 605 {
 606     const char *container_id = NULL;
 607 
 608     if (rsc->children) {
 609         g_list_foreach(rsc->children, (GFunc) setup_container, data_set);
 610         return;
 611     }
 612 
 613     container_id = g_hash_table_lookup(rsc->meta, XML_RSC_ATTR_CONTAINER);
 614     if (container_id && !pcmk__str_eq(container_id, rsc->id, pcmk__str_casei)) {
 615         pe_resource_t *container = pe_find_resource(data_set->resources, container_id);
 616 
 617         if (container) {
 618             rsc->container = container;
 619             pe__set_resource_flags(container, pe_rsc_is_container);
 620             container->fillers = g_list_append(container->fillers, rsc);
 621             pe_rsc_trace(rsc, "Resource %s's container is %s", rsc->id, container_id);
 622         } else {
 623             pe_err("Resource %s: Unknown resource container (%s)", rsc->id, container_id);
 624         }
 625     }
 626 }
 627 
 628 gboolean
 629 unpack_remote_nodes(xmlNode * xml_resources, pe_working_set_t * data_set)
     
 630 {
 631     xmlNode *xml_obj = NULL;
 632 
 633     
 634 
 635 
 636     for (xml_obj = pcmk__xe_first_child(xml_resources); xml_obj != NULL;
 637          xml_obj = pcmk__xe_next(xml_obj)) {
 638 
 639         const char *new_node_id = NULL;
 640 
 641         
 642 
 643 
 644         if (xml_contains_remote_node(xml_obj)) {
 645             new_node_id = ID(xml_obj);
 646             
 647 
 648             if (new_node_id && pe_find_node(data_set->nodes, new_node_id) == NULL) {
 649                 crm_trace("Found remote node %s defined by resource %s",
 650                           new_node_id, ID(xml_obj));
 651                 pe_create_node(new_node_id, new_node_id, "remote", NULL,
 652                                data_set);
 653             }
 654             continue;
 655         }
 656 
 657         
 658 
 659 
 660         if (pcmk__str_eq((const char *)xml_obj->name, XML_CIB_TAG_RESOURCE, pcmk__str_none)) {
 661             
 662 
 663 
 664 
 665             new_node_id = expand_remote_rsc_meta(xml_obj, xml_resources, data_set);
 666             if (new_node_id && pe_find_node(data_set->nodes, new_node_id) == NULL) {
 667                 crm_trace("Found guest node %s in resource %s",
 668                           new_node_id, ID(xml_obj));
 669                 pe_create_node(new_node_id, new_node_id, "remote", NULL,
 670                                data_set);
 671             }
 672             continue;
 673         }
 674 
 675         
 676 
 677 
 678         if (pcmk__str_eq((const char *)xml_obj->name, XML_CIB_TAG_GROUP, pcmk__str_none)) {
 679             xmlNode *xml_obj2 = NULL;
 680             for (xml_obj2 = pcmk__xe_first_child(xml_obj); xml_obj2 != NULL;
 681                  xml_obj2 = pcmk__xe_next(xml_obj2)) {
 682 
 683                 new_node_id = expand_remote_rsc_meta(xml_obj2, xml_resources, data_set);
 684 
 685                 if (new_node_id && pe_find_node(data_set->nodes, new_node_id) == NULL) {
 686                     crm_trace("Found guest node %s in resource %s inside group %s",
 687                               new_node_id, ID(xml_obj2), ID(xml_obj));
 688                     pe_create_node(new_node_id, new_node_id, "remote", NULL,
 689                                    data_set);
 690                 }
 691             }
 692         }
 693     }
 694     return TRUE;
 695 }
 696 
 697 
 698 
 699 
 700 
 701 
 702 
 703 
 704 
 705 static void
 706 link_rsc2remotenode(pe_working_set_t *data_set, pe_resource_t *new_rsc)
     
 707 {
 708     pe_node_t *remote_node = NULL;
 709 
 710     if (new_rsc->is_remote_node == FALSE) {
 711         return;
 712     }
 713 
 714     if (pcmk_is_set(data_set->flags, pe_flag_quick_location)) {
 715         
 716         return;
 717     }
 718 
 719     remote_node = pe_find_node(data_set->nodes, new_rsc->id);
 720     CRM_CHECK(remote_node != NULL, return);
 721 
 722     pe_rsc_trace(new_rsc, "Linking remote connection resource %s to node %s",
 723                  new_rsc->id, remote_node->details->uname);
 724     remote_node->details->remote_rsc = new_rsc;
 725 
 726     if (new_rsc->container == NULL) {
 727         
 728 
 729 
 730         handle_startup_fencing(data_set, remote_node);
 731 
 732     } else {
 733         
 734 
 735 
 736         g_hash_table_replace(remote_node->details->attrs, strdup(CRM_ATTR_KIND),
 737                              strdup("container"));
 738     }
 739 }
 740 
 741 static void
 742 destroy_tag(gpointer data)
     
 743 {
 744     pe_tag_t *tag = data;
 745 
 746     if (tag) {
 747         free(tag->id);
 748         g_list_free_full(tag->refs, free);
 749         free(tag);
 750     }
 751 }
 752 
 753 
 754 
 755 
 756 
 757 
 758 
 759 
 760 
 761 
 762 
 763 
 764 
 765 gboolean
 766 unpack_resources(xmlNode * xml_resources, pe_working_set_t * data_set)
     
 767 {
 768     xmlNode *xml_obj = NULL;
 769     GList *gIter = NULL;
 770 
 771     data_set->template_rsc_sets = pcmk__strkey_table(free, destroy_tag);
 772 
 773     for (xml_obj = pcmk__xe_first_child(xml_resources); xml_obj != NULL;
 774          xml_obj = pcmk__xe_next(xml_obj)) {
 775 
 776         pe_resource_t *new_rsc = NULL;
 777 
 778         if (pcmk__str_eq((const char *)xml_obj->name, XML_CIB_TAG_RSC_TEMPLATE, pcmk__str_none)) {
 779             const char *template_id = ID(xml_obj);
 780 
 781             if (template_id && g_hash_table_lookup_extended(data_set->template_rsc_sets,
 782                                                             template_id, NULL, NULL) == FALSE) {
 783                 
 784                 g_hash_table_insert(data_set->template_rsc_sets, strdup(template_id), NULL);
 785             }
 786             continue;
 787         }
 788 
 789         crm_trace("Beginning unpack... <%s id=%s... >", crm_element_name(xml_obj), ID(xml_obj));
 790         if (common_unpack(xml_obj, &new_rsc, NULL, data_set) && (new_rsc != NULL)) {
 791             data_set->resources = g_list_append(data_set->resources, new_rsc);
 792             pe_rsc_trace(new_rsc, "Added resource %s", new_rsc->id);
 793 
 794         } else {
 795             pcmk__config_err("Ignoring <%s> resource '%s' "
 796                              "because configuration is invalid",
 797                              crm_element_name(xml_obj), crm_str(ID(xml_obj)));
 798             if (new_rsc != NULL && new_rsc->fns != NULL) {
 799                 new_rsc->fns->free(new_rsc);
 800             }
 801         }
 802     }
 803 
 804     for (gIter = data_set->resources; gIter != NULL; gIter = gIter->next) {
 805         pe_resource_t *rsc = (pe_resource_t *) gIter->data;
 806 
 807         setup_container(rsc, data_set);
 808         link_rsc2remotenode(data_set, rsc);
 809     }
 810 
 811     data_set->resources = g_list_sort(data_set->resources, sort_rsc_priority);
 812     if (pcmk_is_set(data_set->flags, pe_flag_quick_location)) {
 813         
 814 
 815     } else if (pcmk_is_set(data_set->flags, pe_flag_stonith_enabled)
 816                && !pcmk_is_set(data_set->flags, pe_flag_have_stonith_resource)) {
 817 
 818         pcmk__config_err("Resource start-up disabled since no STONITH resources have been defined");
 819         pcmk__config_err("Either configure some or disable STONITH with the stonith-enabled option");
 820         pcmk__config_err("NOTE: Clusters with shared data need STONITH to ensure data integrity");
 821     }
 822 
 823     return TRUE;
 824 }
 825 
 826 gboolean
 827 unpack_tags(xmlNode * xml_tags, pe_working_set_t * data_set)
     
 828 {
 829     xmlNode *xml_tag = NULL;
 830 
 831     data_set->tags = pcmk__strkey_table(free, destroy_tag);
 832 
 833     for (xml_tag = pcmk__xe_first_child(xml_tags); xml_tag != NULL;
 834          xml_tag = pcmk__xe_next(xml_tag)) {
 835 
 836         xmlNode *xml_obj_ref = NULL;
 837         const char *tag_id = ID(xml_tag);
 838 
 839         if (!pcmk__str_eq((const char *)xml_tag->name, XML_CIB_TAG_TAG, pcmk__str_none)) {
 840             continue;
 841         }
 842 
 843         if (tag_id == NULL) {
 844             pcmk__config_err("Ignoring <%s> without " XML_ATTR_ID,
 845                              crm_element_name(xml_tag));
 846             continue;
 847         }
 848 
 849         for (xml_obj_ref = pcmk__xe_first_child(xml_tag); xml_obj_ref != NULL;
 850              xml_obj_ref = pcmk__xe_next(xml_obj_ref)) {
 851 
 852             const char *obj_ref = ID(xml_obj_ref);
 853 
 854             if (!pcmk__str_eq((const char *)xml_obj_ref->name, XML_CIB_TAG_OBJ_REF, pcmk__str_none)) {
 855                 continue;
 856             }
 857 
 858             if (obj_ref == NULL) {
 859                 pcmk__config_err("Ignoring <%s> for tag '%s' without " XML_ATTR_ID,
 860                                  crm_element_name(xml_obj_ref), tag_id);
 861                 continue;
 862             }
 863 
 864             if (add_tag_ref(data_set->tags, tag_id, obj_ref) == FALSE) {
 865                 return FALSE;
 866             }
 867         }
 868     }
 869 
 870     return TRUE;
 871 }
 872 
 873 
 874 
 875 static gboolean
 876 unpack_ticket_state(xmlNode * xml_ticket, pe_working_set_t * data_set)
     
 877 {
 878     const char *ticket_id = NULL;
 879     const char *granted = NULL;
 880     const char *last_granted = NULL;
 881     const char *standby = NULL;
 882     xmlAttrPtr xIter = NULL;
 883 
 884     pe_ticket_t *ticket = NULL;
 885 
 886     ticket_id = ID(xml_ticket);
 887     if (pcmk__str_empty(ticket_id)) {
 888         return FALSE;
 889     }
 890 
 891     crm_trace("Processing ticket state for %s", ticket_id);
 892 
 893     ticket = g_hash_table_lookup(data_set->tickets, ticket_id);
 894     if (ticket == NULL) {
 895         ticket = ticket_new(ticket_id, data_set);
 896         if (ticket == NULL) {
 897             return FALSE;
 898         }
 899     }
 900 
 901     for (xIter = xml_ticket->properties; xIter; xIter = xIter->next) {
 902         const char *prop_name = (const char *)xIter->name;
 903         const char *prop_value = crm_element_value(xml_ticket, prop_name);
 904 
 905         if (pcmk__str_eq(prop_name, XML_ATTR_ID, pcmk__str_none)) {
 906             continue;
 907         }
 908         g_hash_table_replace(ticket->state, strdup(prop_name), strdup(prop_value));
 909     }
 910 
 911     granted = g_hash_table_lookup(ticket->state, "granted");
 912     if (granted && crm_is_true(granted)) {
 913         ticket->granted = TRUE;
 914         crm_info("We have ticket '%s'", ticket->id);
 915     } else {
 916         ticket->granted = FALSE;
 917         crm_info("We do not have ticket '%s'", ticket->id);
 918     }
 919 
 920     last_granted = g_hash_table_lookup(ticket->state, "last-granted");
 921     if (last_granted) {
 922         long long last_granted_ll;
 923 
 924         pcmk__scan_ll(last_granted, &last_granted_ll, 0LL);
 925         ticket->last_granted = (time_t) last_granted_ll;
 926     }
 927 
 928     standby = g_hash_table_lookup(ticket->state, "standby");
 929     if (standby && crm_is_true(standby)) {
 930         ticket->standby = TRUE;
 931         if (ticket->granted) {
 932             crm_info("Granted ticket '%s' is in standby-mode", ticket->id);
 933         }
 934     } else {
 935         ticket->standby = FALSE;
 936     }
 937 
 938     crm_trace("Done with ticket state for %s", ticket_id);
 939 
 940     return TRUE;
 941 }
 942 
 943 static gboolean
 944 unpack_tickets_state(xmlNode * xml_tickets, pe_working_set_t * data_set)
     
 945 {
 946     xmlNode *xml_obj = NULL;
 947 
 948     for (xml_obj = pcmk__xe_first_child(xml_tickets); xml_obj != NULL;
 949          xml_obj = pcmk__xe_next(xml_obj)) {
 950 
 951         if (!pcmk__str_eq((const char *)xml_obj->name, XML_CIB_TAG_TICKET_STATE, pcmk__str_none)) {
 952             continue;
 953         }
 954         unpack_ticket_state(xml_obj, data_set);
 955     }
 956 
 957     return TRUE;
 958 }
 959 
 960 static void
 961 unpack_handle_remote_attrs(pe_node_t *this_node, xmlNode *state, pe_working_set_t * data_set) 
     
 962 {
 963     const char *resource_discovery_enabled = NULL;
 964     xmlNode *attrs = NULL;
 965     pe_resource_t *rsc = NULL;
 966 
 967     if (!pcmk__str_eq((const char *)state->name, XML_CIB_TAG_STATE, pcmk__str_none)) {
 968         return;
 969     }
 970 
 971     if ((this_node == NULL) || !pe__is_guest_or_remote_node(this_node)) {
 972         return;
 973     }
 974     crm_trace("Processing remote node id=%s, uname=%s", this_node->details->id, this_node->details->uname);
 975 
 976     pcmk__scan_min_int(crm_element_value(state, XML_NODE_IS_MAINTENANCE),
 977                        &(this_node->details->remote_maintenance), 0);
 978 
 979     rsc = this_node->details->remote_rsc;
 980     if (this_node->details->remote_requires_reset == FALSE) {
 981         this_node->details->unclean = FALSE;
 982         this_node->details->unseen = FALSE;
 983     }
 984     attrs = find_xml_node(state, XML_TAG_TRANSIENT_NODEATTRS, FALSE);
 985     add_node_attrs(attrs, this_node, TRUE, data_set);
 986 
 987     if (pe__shutdown_requested(this_node)) {
 988         crm_info("Node %s is shutting down", this_node->details->uname);
 989         this_node->details->shutdown = TRUE;
 990     }
 991  
 992     if (crm_is_true(pe_node_attribute_raw(this_node, "standby"))) {
 993         crm_info("Node %s is in standby-mode", this_node->details->uname);
 994         this_node->details->standby = TRUE;
 995     }
 996 
 997     if (crm_is_true(pe_node_attribute_raw(this_node, "maintenance")) ||
 998         ((rsc != NULL) && !pcmk_is_set(rsc->flags, pe_rsc_managed))) {
 999         crm_info("Node %s is in maintenance-mode", this_node->details->uname);
1000         this_node->details->maintenance = TRUE;
1001     }
1002 
1003     resource_discovery_enabled = pe_node_attribute_raw(this_node, XML_NODE_ATTR_RSC_DISCOVERY);
1004     if (resource_discovery_enabled && !crm_is_true(resource_discovery_enabled)) {
1005         if (pe__is_remote_node(this_node)
1006             && !pcmk_is_set(data_set->flags, pe_flag_stonith_enabled)) {
1007             crm_warn("Ignoring %s attribute on remote node %s because stonith is disabled",
1008                      XML_NODE_ATTR_RSC_DISCOVERY, this_node->details->uname);
1009         } else {
1010             
1011 
1012 
1013 
1014 
1015             crm_info("Node %s has resource discovery disabled", this_node->details->uname);
1016             this_node->details->rsc_discovery_enabled = FALSE;
1017         }
1018     }
1019 }
1020 
1021 
1022 
1023 
1024 
1025 
1026 
1027 
1028 
1029 static void
1030 unpack_transient_attributes(xmlNode *state, pe_node_t *node,
     
1031                             pe_working_set_t *data_set)
1032 {
1033     const char *discovery = NULL;
1034     xmlNode *attrs = find_xml_node(state, XML_TAG_TRANSIENT_NODEATTRS, FALSE);
1035 
1036     add_node_attrs(attrs, node, TRUE, data_set);
1037 
1038     if (crm_is_true(pe_node_attribute_raw(node, "standby"))) {
1039         crm_info("Node %s is in standby-mode", node->details->uname);
1040         node->details->standby = TRUE;
1041     }
1042 
1043     if (crm_is_true(pe_node_attribute_raw(node, "maintenance"))) {
1044         crm_info("Node %s is in maintenance-mode", node->details->uname);
1045         node->details->maintenance = TRUE;
1046     }
1047 
1048     discovery = pe_node_attribute_raw(node, XML_NODE_ATTR_RSC_DISCOVERY);
1049     if ((discovery != NULL) && !crm_is_true(discovery)) {
1050         crm_warn("Ignoring %s attribute for node %s because disabling "
1051                  "resource discovery is not allowed for cluster nodes",
1052                  XML_NODE_ATTR_RSC_DISCOVERY, node->details->uname);
1053     }
1054 }
1055 
1056 
1057 
1058 
1059 
1060 
1061 
1062 
1063 
1064 
1065 
1066 
1067 
1068 static void
1069 unpack_node_state(xmlNode *state, pe_working_set_t *data_set)
     
1070 {
1071     const char *id = NULL;
1072     const char *uname = NULL;
1073     pe_node_t *this_node = NULL;
1074 
1075     id = crm_element_value(state, XML_ATTR_ID);
1076     if (id == NULL) {
1077         crm_warn("Ignoring malformed " XML_CIB_TAG_STATE " entry without "
1078                  XML_ATTR_ID);
1079         return;
1080     }
1081 
1082     uname = crm_element_value(state, XML_ATTR_UNAME);
1083     if (uname == NULL) {
1084         crm_warn("Ignoring malformed " XML_CIB_TAG_STATE " entry without "
1085                  XML_ATTR_UNAME);
1086         return;
1087     }
1088 
1089     this_node = pe_find_node_any(data_set->nodes, id, uname);
1090     if (this_node == NULL) {
1091         pcmk__config_warn("Ignoring recorded node state for '%s' because "
1092                           "it is no longer in the configuration", uname);
1093         return;
1094     }
1095 
1096     if (pe__is_guest_or_remote_node(this_node)) {
1097         
1098 
1099 
1100 
1101 
1102         pcmk__scan_min_int(crm_element_value(state, XML_NODE_IS_FENCED),
1103                            &(this_node->details->remote_was_fenced), 0);
1104         return;
1105     }
1106 
1107     unpack_transient_attributes(state, this_node, data_set);
1108 
1109     
1110 
1111 
1112     this_node->details->unclean = FALSE;
1113     this_node->details->unseen = FALSE;
1114 
1115     crm_trace("Determining online status of cluster node %s (id %s)",
1116               this_node->details->uname, id);
1117     determine_online_status(state, this_node, data_set);
1118 
1119     if (!pcmk_is_set(data_set->flags, pe_flag_have_quorum)
1120         && this_node->details->online
1121         && (data_set->no_quorum_policy == no_quorum_suicide)) {
1122         
1123 
1124 
1125 
1126         pe_fence_node(data_set, this_node, "cluster does not have quorum",
1127                       FALSE);
1128     }
1129 }
1130 
1131 
1132 
1133 
1134 
1135 
1136 
1137 
1138 
1139 
1140 
1141 
1142 
1143 
1144 
1145 
1146 
1147 
1148 static int
1149 unpack_node_history(xmlNode *status, bool fence, pe_working_set_t *data_set)
     
1150 {
1151     int rc = pcmk_rc_ok;
1152 
1153     
1154     for (xmlNode *state = first_named_child(status, XML_CIB_TAG_STATE);
1155          state != NULL; state = crm_next_same_xml(state)) {
1156 
1157         const char *id = ID(state);
1158         const char *uname = crm_element_value(state, XML_ATTR_UNAME);
1159         pe_node_t *this_node = NULL;
1160 
1161         if ((id == NULL) || (uname == NULL)) {
1162             
1163             crm_trace("Not unpacking resource history from malformed "
1164                       XML_CIB_TAG_STATE " without id and/or uname");
1165             continue;
1166         }
1167 
1168         this_node = pe_find_node_any(data_set->nodes, id, uname);
1169         if (this_node == NULL) {
1170             
1171             crm_trace("Not unpacking resource history for node %s because "
1172                       "no longer in configuration", id);
1173             continue;
1174         }
1175 
1176         if (this_node->details->unpacked) {
1177             crm_trace("Not unpacking resource history for node %s because "
1178                       "already unpacked", id);
1179             continue;
1180         }
1181 
1182         if (fence) {
1183             
1184 
1185         } else if (pe__is_guest_node(this_node)) {
1186             
1187 
1188 
1189 
1190             pe_resource_t *rsc = this_node->details->remote_rsc;
1191 
1192             if ((rsc == NULL) || (rsc->role != RSC_ROLE_STARTED)
1193                 || (rsc->container->role != RSC_ROLE_STARTED)) {
1194                 crm_trace("Not unpacking resource history for guest node %s "
1195                           "because container and connection are not known to "
1196                           "be up", id);
1197                 continue;
1198             }
1199 
1200         } else if (pe__is_remote_node(this_node)) {
1201             
1202 
1203 
1204 
1205 
1206             pe_resource_t *rsc = this_node->details->remote_rsc;
1207 
1208             if ((rsc == NULL)
1209                 || (!pcmk_is_set(data_set->flags, pe_flag_shutdown_lock)
1210                     && (rsc->role != RSC_ROLE_STARTED))) {
1211                 crm_trace("Not unpacking resource history for remote node %s "
1212                           "because connection is not known to be up", id);
1213                 continue;
1214             }
1215 
1216         
1217 
1218 
1219 
1220 
1221         } else if (!pcmk_any_flags_set(data_set->flags, pe_flag_stonith_enabled
1222                                                         |pe_flag_shutdown_lock)
1223                    && !this_node->details->online) {
1224             crm_trace("Not unpacking resource history for offline "
1225                       "cluster node %s", id);
1226             continue;
1227         }
1228 
1229         if (pe__is_guest_or_remote_node(this_node)) {
1230             determine_remote_online_status(data_set, this_node);
1231             unpack_handle_remote_attrs(this_node, state, data_set);
1232         }
1233 
1234         crm_trace("Unpacking resource history for %snode %s",
1235                   (fence? "unseen " : ""), id);
1236 
1237         this_node->details->unpacked = TRUE;
1238         unpack_node_lrm(this_node, state, data_set);
1239 
1240         rc = EAGAIN; 
1241     }
1242     return rc;
1243 }
1244 
1245 
1246 
1247 
1248 gboolean
1249 unpack_status(xmlNode * status, pe_working_set_t * data_set)
     
1250 {
1251     xmlNode *state = NULL;
1252 
1253     crm_trace("Beginning unpack");
1254 
1255     if (data_set->tickets == NULL) {
1256         data_set->tickets = pcmk__strkey_table(free, destroy_ticket);
1257     }
1258 
1259     for (state = pcmk__xe_first_child(status); state != NULL;
1260          state = pcmk__xe_next(state)) {
1261 
1262         if (pcmk__str_eq((const char *)state->name, XML_CIB_TAG_TICKETS, pcmk__str_none)) {
1263             unpack_tickets_state((xmlNode *) state, data_set);
1264 
1265         } else if (pcmk__str_eq((const char *)state->name, XML_CIB_TAG_STATE, pcmk__str_none)) {
1266             unpack_node_state(state, data_set);
1267         }
1268     }
1269 
1270     while (unpack_node_history(status, FALSE, data_set) == EAGAIN) {
1271         crm_trace("Another pass through node resource histories is needed");
1272     }
1273 
1274     
1275     unpack_node_history(status,
1276                         pcmk_is_set(data_set->flags, pe_flag_stonith_enabled),
1277                         data_set);
1278 
1279     
1280 
1281 
1282     if (data_set->stop_needed != NULL) {
1283         for (GList *item = data_set->stop_needed; item; item = item->next) {
1284             pe_resource_t *container = item->data;
1285             pe_node_t *node = pe__current_node(container);
1286 
1287             if (node) {
1288                 stop_action(container, node, FALSE);
1289             }
1290         }
1291         g_list_free(data_set->stop_needed);
1292         data_set->stop_needed = NULL;
1293     }
1294 
1295     
1296 
1297 
1298 
1299     for (GList *gIter = data_set->nodes; gIter != NULL; gIter = gIter->next) {
1300         pe_node_t *this_node = gIter->data;
1301 
1302         if (!pe__is_guest_or_remote_node(this_node)) {
1303             continue;
1304         }
1305         if (this_node->details->shutdown
1306             && (this_node->details->remote_rsc != NULL)) {
1307             pe__set_next_role(this_node->details->remote_rsc, RSC_ROLE_STOPPED,
1308                               "remote shutdown");
1309         }
1310         if (!this_node->details->unpacked) {
1311             determine_remote_online_status(data_set, this_node);
1312         }
1313     }
1314 
1315     return TRUE;
1316 }
1317 
1318 static gboolean
1319 determine_online_status_no_fencing(pe_working_set_t * data_set, xmlNode * node_state,
     
1320                                    pe_node_t * this_node)
1321 {
1322     gboolean online = FALSE;
1323     const char *join = crm_element_value(node_state, XML_NODE_JOIN_STATE);
1324     const char *is_peer = crm_element_value(node_state, XML_NODE_IS_PEER);
1325     const char *in_cluster = crm_element_value(node_state, XML_NODE_IN_CLUSTER);
1326     const char *exp_state = crm_element_value(node_state, XML_NODE_EXPECTED);
1327 
1328     if (!crm_is_true(in_cluster)) {
1329         crm_trace("Node is down: in_cluster=%s", crm_str(in_cluster));
1330 
1331     } else if (pcmk__str_eq(is_peer, ONLINESTATUS, pcmk__str_casei)) {
1332         if (pcmk__str_eq(join, CRMD_JOINSTATE_MEMBER, pcmk__str_casei)) {
1333             online = TRUE;
1334         } else {
1335             crm_debug("Node is not ready to run resources: %s", join);
1336         }
1337 
1338     } else if (this_node->details->expected_up == FALSE) {
1339         crm_trace("Controller is down: in_cluster=%s", crm_str(in_cluster));
1340         crm_trace("\tis_peer=%s, join=%s, expected=%s",
1341                   crm_str(is_peer), crm_str(join), crm_str(exp_state));
1342 
1343     } else {
1344         
1345         pe_fence_node(data_set, this_node, "peer is unexpectedly down", FALSE);
1346         crm_info("\tin_cluster=%s, is_peer=%s, join=%s, expected=%s",
1347                  crm_str(in_cluster), crm_str(is_peer), crm_str(join), crm_str(exp_state));
1348     }
1349     return online;
1350 }
1351 
1352 static gboolean
1353 determine_online_status_fencing(pe_working_set_t * data_set, xmlNode * node_state,
     
1354                                 pe_node_t * this_node)
1355 {
1356     gboolean online = FALSE;
1357     gboolean do_terminate = FALSE;
1358     bool crmd_online = FALSE;
1359     const char *join = crm_element_value(node_state, XML_NODE_JOIN_STATE);
1360     const char *is_peer = crm_element_value(node_state, XML_NODE_IS_PEER);
1361     const char *in_cluster = crm_element_value(node_state, XML_NODE_IN_CLUSTER);
1362     const char *exp_state = crm_element_value(node_state, XML_NODE_EXPECTED);
1363     const char *terminate = pe_node_attribute_raw(this_node, "terminate");
1364 
1365 
1366 
1367 
1368 
1369 
1370 
1371 
1372     if (crm_is_true(terminate)) {
1373         do_terminate = TRUE;
1374 
1375     } else if (terminate != NULL && strlen(terminate) > 0) {
1376         
1377         char t = terminate[0];
1378 
1379         if (t != '0' && isdigit(t)) {
1380             do_terminate = TRUE;
1381         }
1382     }
1383 
1384     crm_trace("%s: in_cluster=%s, is_peer=%s, join=%s, expected=%s, term=%d",
1385               this_node->details->uname, crm_str(in_cluster), crm_str(is_peer),
1386               crm_str(join), crm_str(exp_state), do_terminate);
1387 
1388     online = crm_is_true(in_cluster);
1389     crmd_online = pcmk__str_eq(is_peer, ONLINESTATUS, pcmk__str_casei);
1390     if (exp_state == NULL) {
1391         exp_state = CRMD_JOINSTATE_DOWN;
1392     }
1393 
1394     if (this_node->details->shutdown) {
1395         crm_debug("%s is shutting down", this_node->details->uname);
1396 
1397         
1398         online = crmd_online;
1399 
1400     } else if (in_cluster == NULL) {
1401         pe_fence_node(data_set, this_node, "peer has not been seen by the cluster", FALSE);
1402 
1403     } else if (pcmk__str_eq(join, CRMD_JOINSTATE_NACK, pcmk__str_casei)) {
1404         pe_fence_node(data_set, this_node,
1405                       "peer failed Pacemaker membership criteria", FALSE);
1406 
1407     } else if (do_terminate == FALSE && pcmk__str_eq(exp_state, CRMD_JOINSTATE_DOWN, pcmk__str_casei)) {
1408 
1409         if (crm_is_true(in_cluster) || crmd_online) {
1410             crm_info("- Node %s is not ready to run resources", this_node->details->uname);
1411             this_node->details->standby = TRUE;
1412             this_node->details->pending = TRUE;
1413 
1414         } else {
1415             crm_trace("%s is down or still coming up", this_node->details->uname);
1416         }
1417 
1418     } else if (do_terminate && pcmk__str_eq(join, CRMD_JOINSTATE_DOWN, pcmk__str_casei)
1419                && crm_is_true(in_cluster) == FALSE && !crmd_online) {
1420         crm_info("Node %s was just shot", this_node->details->uname);
1421         online = FALSE;
1422 
1423     } else if (crm_is_true(in_cluster) == FALSE) {
1424         
1425         pe_fence_node(data_set, this_node, "peer is no longer part of the cluster", TRUE);
1426 
1427     } else if (!crmd_online) {
1428         pe_fence_node(data_set, this_node, "peer process is no longer available", FALSE);
1429 
1430         
1431     } else if (do_terminate) {
1432         pe_fence_node(data_set, this_node, "termination was requested", FALSE);
1433 
1434     } else if (pcmk__str_eq(join, CRMD_JOINSTATE_MEMBER, pcmk__str_casei)) {
1435         crm_info("Node %s is active", this_node->details->uname);
1436 
1437     } else if (pcmk__strcase_any_of(join, CRMD_JOINSTATE_PENDING, CRMD_JOINSTATE_DOWN, NULL)) {
1438         crm_info("Node %s is not ready to run resources", this_node->details->uname);
1439         this_node->details->standby = TRUE;
1440         this_node->details->pending = TRUE;
1441 
1442     } else {
1443         pe_fence_node(data_set, this_node, "peer was in an unknown state", FALSE);
1444         crm_warn("%s: in-cluster=%s, is-peer=%s, join=%s, expected=%s, term=%d, shutdown=%d",
1445                  this_node->details->uname, crm_str(in_cluster), crm_str(is_peer),
1446                  crm_str(join), crm_str(exp_state), do_terminate, this_node->details->shutdown);
1447     }
1448 
1449     return online;
1450 }
1451 
1452 static void
1453 determine_remote_online_status(pe_working_set_t * data_set, pe_node_t * this_node)
     
1454 {
1455     pe_resource_t *rsc = this_node->details->remote_rsc;
1456     pe_resource_t *container = NULL;
1457     pe_node_t *host = NULL;
1458 
1459     
1460 
1461 
1462 
1463     if (rsc == NULL) {
1464         this_node->details->online = FALSE;
1465         goto remote_online_done;
1466     }
1467 
1468     container = rsc->container;
1469 
1470     if (container && pcmk__list_of_1(rsc->running_on)) {
1471         host = rsc->running_on->data;
1472     }
1473 
1474     
1475     if (rsc->role == RSC_ROLE_STARTED) {
1476         crm_trace("%s node %s presumed ONLINE because connection resource is started",
1477                   (container? "Guest" : "Remote"), this_node->details->id);
1478         this_node->details->online = TRUE;
1479     }
1480 
1481     
1482     if (rsc->role == RSC_ROLE_STARTED && rsc->next_role == RSC_ROLE_STOPPED) {
1483         crm_trace("%s node %s shutting down because connection resource is stopping",
1484                   (container? "Guest" : "Remote"), this_node->details->id);
1485         this_node->details->shutdown = TRUE;
1486     }
1487 
1488     
1489     if(container && pcmk_is_set(container->flags, pe_rsc_failed)) {
1490         crm_trace("Guest node %s UNCLEAN because guest resource failed",
1491                   this_node->details->id);
1492         this_node->details->online = FALSE;
1493         this_node->details->remote_requires_reset = TRUE;
1494 
1495     } else if (pcmk_is_set(rsc->flags, pe_rsc_failed)) {
1496         crm_trace("%s node %s OFFLINE because connection resource failed",
1497                   (container? "Guest" : "Remote"), this_node->details->id);
1498         this_node->details->online = FALSE;
1499 
1500     } else if (rsc->role == RSC_ROLE_STOPPED
1501         || (container && container->role == RSC_ROLE_STOPPED)) {
1502 
1503         crm_trace("%s node %s OFFLINE because its resource is stopped",
1504                   (container? "Guest" : "Remote"), this_node->details->id);
1505         this_node->details->online = FALSE;
1506         this_node->details->remote_requires_reset = FALSE;
1507 
1508     } else if (host && (host->details->online == FALSE)
1509                && host->details->unclean) {
1510         crm_trace("Guest node %s UNCLEAN because host is unclean",
1511                   this_node->details->id);
1512         this_node->details->online = FALSE;
1513         this_node->details->remote_requires_reset = TRUE;
1514     }
1515 
1516 remote_online_done:
1517     crm_trace("Remote node %s online=%s",
1518         this_node->details->id, this_node->details->online ? "TRUE" : "FALSE");
1519 }
1520 
1521 static void
1522 determine_online_status(xmlNode * node_state, pe_node_t * this_node, pe_working_set_t * data_set)
     
1523 {
1524     gboolean online = FALSE;
1525     const char *exp_state = crm_element_value(node_state, XML_NODE_EXPECTED);
1526 
1527     CRM_CHECK(this_node != NULL, return);
1528 
1529     this_node->details->shutdown = FALSE;
1530     this_node->details->expected_up = FALSE;
1531 
1532     if (pe__shutdown_requested(this_node)) {
1533         this_node->details->shutdown = TRUE;
1534 
1535     } else if (pcmk__str_eq(exp_state, CRMD_JOINSTATE_MEMBER, pcmk__str_casei)) {
1536         this_node->details->expected_up = TRUE;
1537     }
1538 
1539     if (this_node->details->type == node_ping) {
1540         this_node->details->unclean = FALSE;
1541         online = FALSE;         
1542 
1543 
1544 
1545 
1546     } else if (!pcmk_is_set(data_set->flags, pe_flag_stonith_enabled)) {
1547         online = determine_online_status_no_fencing(data_set, node_state, this_node);
1548 
1549     } else {
1550         online = determine_online_status_fencing(data_set, node_state, this_node);
1551     }
1552 
1553     if (online) {
1554         this_node->details->online = TRUE;
1555 
1556     } else {
1557         
1558         this_node->fixed = TRUE;
1559         this_node->weight = -INFINITY;
1560     }
1561 
1562     if (online && this_node->details->shutdown) {
1563         
1564         this_node->fixed = TRUE;
1565         this_node->weight = -INFINITY;
1566     }
1567 
1568     if (this_node->details->type == node_ping) {
1569         crm_info("Node %s is not a Pacemaker node", this_node->details->uname);
1570 
1571     } else if (this_node->details->unclean) {
1572         pe_proc_warn("Node %s is unclean", this_node->details->uname);
1573 
1574     } else if (this_node->details->online) {
1575         crm_info("Node %s is %s", this_node->details->uname,
1576                  this_node->details->shutdown ? "shutting down" :
1577                  this_node->details->pending ? "pending" :
1578                  this_node->details->standby ? "standby" :
1579                  this_node->details->maintenance ? "maintenance" : "online");
1580 
1581     } else {
1582         crm_trace("Node %s is offline", this_node->details->uname);
1583     }
1584 }
1585 
1586 
1587 
1588 
1589 
1590 
1591 
1592 
1593 
1594 const char *
1595 pe_base_name_end(const char *id)
     
1596 {
1597     if (!pcmk__str_empty(id)) {
1598         const char *end = id + strlen(id) - 1;
1599 
1600         for (const char *s = end; s > id; --s) {
1601             switch (*s) {
1602                 case '0':
1603                 case '1':
1604                 case '2':
1605                 case '3':
1606                 case '4':
1607                 case '5':
1608                 case '6':
1609                 case '7':
1610                 case '8':
1611                 case '9':
1612                     break;
1613                 case ':':
1614                     return (s == end)? s : (s - 1);
1615                 default:
1616                     return end;
1617             }
1618         }
1619         return end;
1620     }
1621     return NULL;
1622 }
1623 
1624 
1625 
1626 
1627 
1628 
1629 
1630 
1631 
1632 
1633 
1634 char *
1635 clone_strip(const char *last_rsc_id)
     
1636 {
1637     const char *end = pe_base_name_end(last_rsc_id);
1638     char *basename = NULL;
1639 
1640     CRM_ASSERT(end);
1641     basename = strndup(last_rsc_id, end - last_rsc_id + 1);
1642     CRM_ASSERT(basename);
1643     return basename;
1644 }
1645 
1646 
1647 
1648 
1649 
1650 
1651 
1652 
1653 
1654 
1655 
1656 char *
1657 clone_zero(const char *last_rsc_id)
     
1658 {
1659     const char *end = pe_base_name_end(last_rsc_id);
1660     size_t base_name_len = end - last_rsc_id + 1;
1661     char *zero = NULL;
1662 
1663     CRM_ASSERT(end);
1664     zero = calloc(base_name_len + 3, sizeof(char));
1665     CRM_ASSERT(zero);
1666     memcpy(zero, last_rsc_id, base_name_len);
1667     zero[base_name_len] = ':';
1668     zero[base_name_len + 1] = '0';
1669     return zero;
1670 }
1671 
1672 static pe_resource_t *
1673 create_fake_resource(const char *rsc_id, xmlNode * rsc_entry, pe_working_set_t * data_set)
     
1674 {
1675     pe_resource_t *rsc = NULL;
1676     xmlNode *xml_rsc = create_xml_node(NULL, XML_CIB_TAG_RESOURCE);
1677 
1678     copy_in_properties(xml_rsc, rsc_entry);
1679     crm_xml_add(xml_rsc, XML_ATTR_ID, rsc_id);
1680     crm_log_xml_debug(xml_rsc, "Orphan resource");
1681 
1682     if (!common_unpack(xml_rsc, &rsc, NULL, data_set)) {
1683         return NULL;
1684     }
1685 
1686     if (xml_contains_remote_node(xml_rsc)) {
1687         pe_node_t *node;
1688 
1689         crm_debug("Detected orphaned remote node %s", rsc_id);
1690         node = pe_find_node(data_set->nodes, rsc_id);
1691         if (node == NULL) {
1692                 node = pe_create_node(rsc_id, rsc_id, "remote", NULL, data_set);
1693         }
1694         link_rsc2remotenode(data_set, rsc);
1695 
1696         if (node) {
1697             crm_trace("Setting node %s as shutting down due to orphaned connection resource", rsc_id);
1698             node->details->shutdown = TRUE;
1699         }
1700     }
1701 
1702     if (crm_element_value(rsc_entry, XML_RSC_ATTR_CONTAINER)) {
1703         
1704         crm_trace("Detected orphaned container filler %s", rsc_id);
1705         pe__set_resource_flags(rsc, pe_rsc_orphan_container_filler);
1706     }
1707     pe__set_resource_flags(rsc, pe_rsc_orphan);
1708     data_set->resources = g_list_append(data_set->resources, rsc);
1709     return rsc;
1710 }
1711 
1712 
1713 
1714 
1715 
1716 static pe_resource_t *
1717 create_anonymous_orphan(pe_resource_t *parent, const char *rsc_id,
     
1718                         pe_node_t *node, pe_working_set_t *data_set)
1719 {
1720     pe_resource_t *top = pe__create_clone_child(parent, data_set);
1721 
1722     
1723     pe_resource_t *orphan = top->fns->find_rsc(top, rsc_id, NULL, pe_find_clone);
1724 
1725     pe_rsc_debug(parent, "Created orphan %s for %s: %s on %s",
1726                  top->id, parent->id, rsc_id, node->details->uname);
1727     return orphan;
1728 }
1729 
1730 
1731 
1732 
1733 
1734 
1735 
1736 
1737 
1738 
1739 
1740 
1741 
1742 
1743 
1744 static pe_resource_t *
1745 find_anonymous_clone(pe_working_set_t * data_set, pe_node_t * node, pe_resource_t * parent,
     
1746                      const char *rsc_id)
1747 {
1748     GList *rIter = NULL;
1749     pe_resource_t *rsc = NULL;
1750     pe_resource_t *inactive_instance = NULL;
1751     gboolean skip_inactive = FALSE;
1752 
1753     CRM_ASSERT(parent != NULL);
1754     CRM_ASSERT(pe_rsc_is_clone(parent));
1755     CRM_ASSERT(!pcmk_is_set(parent->flags, pe_rsc_unique));
1756 
1757     
1758     pe_rsc_trace(parent, "Looking for %s on %s in %s", rsc_id, node->details->uname, parent->id);
1759     for (rIter = parent->children; rsc == NULL && rIter; rIter = rIter->next) {
1760         GList *locations = NULL;
1761         pe_resource_t *child = rIter->data;
1762 
1763         
1764 
1765 
1766 
1767 
1768 
1769 
1770 
1771 
1772 
1773 
1774 
1775 
1776 
1777 
1778         child->fns->location(child, &locations, 2);
1779         if (locations) {
1780             
1781 
1782 
1783 
1784             CRM_LOG_ASSERT(locations->next == NULL);
1785 
1786             if (((pe_node_t *)locations->data)->details == node->details) {
1787                 
1788 
1789 
1790 
1791 
1792 
1793 
1794                 rsc = parent->fns->find_rsc(child, rsc_id, NULL, pe_find_clone);
1795                 if (rsc) {
1796                     
1797 
1798 
1799 
1800 
1801 
1802 
1803                     if (rsc->running_on) {
1804                         crm_notice("Active (now-)anonymous clone %s has "
1805                                    "multiple (orphan) instance histories on %s",
1806                                    parent->id, node->details->uname);
1807                         skip_inactive = TRUE;
1808                         rsc = NULL;
1809                     } else {
1810                         pe_rsc_trace(parent, "Resource %s, active", rsc->id);
1811                     }
1812                 }
1813             }
1814             g_list_free(locations);
1815 
1816         } else {
1817             pe_rsc_trace(parent, "Resource %s, skip inactive", child->id);
1818             if (!skip_inactive && !inactive_instance
1819                 && !pcmk_is_set(child->flags, pe_rsc_block)) {
1820                 
1821                 inactive_instance = parent->fns->find_rsc(child, rsc_id, NULL,
1822                                                           pe_find_clone);
1823 
1824                 
1825 
1826 
1827                 if (inactive_instance && inactive_instance->pending_node
1828                     && (inactive_instance->pending_node->details != node->details)) {
1829                     inactive_instance = NULL;
1830                 }
1831             }
1832         }
1833     }
1834 
1835     if ((rsc == NULL) && !skip_inactive && (inactive_instance != NULL)) {
1836         pe_rsc_trace(parent, "Resource %s, empty slot", inactive_instance->id);
1837         rsc = inactive_instance;
1838     }
1839 
1840     
1841 
1842 
1843 
1844 
1845 
1846 
1847 
1848 
1849 
1850 
1851 
1852     if ((rsc != NULL) && !pcmk_is_set(rsc->flags, pe_rsc_needs_fencing)
1853         && (!node->details->online || node->details->unclean)
1854         && !pe__is_guest_node(node)
1855         && !pe__is_universal_clone(parent, data_set)) {
1856 
1857         rsc = NULL;
1858     }
1859 
1860     if (rsc == NULL) {
1861         rsc = create_anonymous_orphan(parent, rsc_id, node, data_set);
1862         pe_rsc_trace(parent, "Resource %s, orphan", rsc->id);
1863     }
1864     return rsc;
1865 }
1866 
1867 static pe_resource_t *
1868 unpack_find_resource(pe_working_set_t * data_set, pe_node_t * node, const char *rsc_id,
     
1869                      xmlNode * rsc_entry)
1870 {
1871     pe_resource_t *rsc = NULL;
1872     pe_resource_t *parent = NULL;
1873 
1874     crm_trace("looking for %s", rsc_id);
1875     rsc = pe_find_resource(data_set->resources, rsc_id);
1876 
1877     if (rsc == NULL) {
1878         
1879 
1880 
1881 
1882         char *clone0_id = clone_zero(rsc_id);
1883         pe_resource_t *clone0 = pe_find_resource(data_set->resources, clone0_id);
1884 
1885         if (clone0 && !pcmk_is_set(clone0->flags, pe_rsc_unique)) {
1886             rsc = clone0;
1887             parent = uber_parent(clone0);
1888             crm_trace("%s found as %s (%s)", rsc_id, clone0_id, parent->id);
1889         } else {
1890             crm_trace("%s is not known as %s either (orphan)",
1891                       rsc_id, clone0_id);
1892         }
1893         free(clone0_id);
1894 
1895     } else if (rsc->variant > pe_native) {
1896         crm_trace("Resource history for %s is orphaned because it is no longer primitive",
1897                   rsc_id);
1898         return NULL;
1899 
1900     } else {
1901         parent = uber_parent(rsc);
1902     }
1903 
1904     if (pe_rsc_is_anon_clone(parent)) {
1905 
1906         if (pe_rsc_is_bundled(parent)) {
1907             rsc = pe__find_bundle_replica(parent->parent, node);
1908         } else {
1909             char *base = clone_strip(rsc_id);
1910 
1911             rsc = find_anonymous_clone(data_set, node, parent, base);
1912             free(base);
1913             CRM_ASSERT(rsc != NULL);
1914         }
1915     }
1916 
1917     if (rsc && !pcmk__str_eq(rsc_id, rsc->id, pcmk__str_casei)
1918         && !pcmk__str_eq(rsc_id, rsc->clone_name, pcmk__str_casei)) {
1919 
1920         pcmk__str_update(&rsc->clone_name, rsc_id);
1921         pe_rsc_debug(rsc, "Internally renamed %s on %s to %s%s",
1922                      rsc_id, node->details->uname, rsc->id,
1923                      (pcmk_is_set(rsc->flags, pe_rsc_orphan)? " (ORPHAN)" : ""));
1924     }
1925     return rsc;
1926 }
1927 
1928 static pe_resource_t *
1929 process_orphan_resource(xmlNode * rsc_entry, pe_node_t * node, pe_working_set_t * data_set)
     
1930 {
1931     pe_resource_t *rsc = NULL;
1932     const char *rsc_id = crm_element_value(rsc_entry, XML_ATTR_ID);
1933 
1934     crm_debug("Detected orphan resource %s on %s", rsc_id, node->details->uname);
1935     rsc = create_fake_resource(rsc_id, rsc_entry, data_set);
1936     if (rsc == NULL) {
1937         return NULL;
1938     }
1939 
1940     if (!pcmk_is_set(data_set->flags, pe_flag_stop_rsc_orphans)) {
1941         pe__clear_resource_flags(rsc, pe_rsc_managed);
1942 
1943     } else {
1944         CRM_CHECK(rsc != NULL, return NULL);
1945         pe_rsc_trace(rsc, "Added orphan %s", rsc->id);
1946         resource_location(rsc, NULL, -INFINITY, "__orphan_do_not_run__", data_set);
1947     }
1948     return rsc;
1949 }
1950 
1951 static void
1952 process_rsc_state(pe_resource_t * rsc, pe_node_t * node,
     
1953                   enum action_fail_response on_fail,
1954                   xmlNode * migrate_op, pe_working_set_t * data_set)
1955 {
1956     pe_node_t *tmpnode = NULL;
1957     char *reason = NULL;
1958     enum action_fail_response save_on_fail = action_fail_ignore;
1959 
1960     CRM_ASSERT(rsc);
1961     pe_rsc_trace(rsc, "Resource %s is %s on %s: on_fail=%s",
1962                  rsc->id, role2text(rsc->role), node->details->uname, fail2text(on_fail));
1963 
1964     
1965     if (rsc->role != RSC_ROLE_UNKNOWN) {
1966         pe_resource_t *iter = rsc;
1967 
1968         while (iter) {
1969             if (g_hash_table_lookup(iter->known_on, node->details->id) == NULL) {
1970                 pe_node_t *n = pe__copy_node(node);
1971 
1972                 pe_rsc_trace(rsc, "%s%s%s known on %s",
1973                              rsc->id,
1974                              ((rsc->clone_name == NULL)? "" : " also known as "),
1975                              ((rsc->clone_name == NULL)? "" : rsc->clone_name),
1976                              n->details->uname);
1977                 g_hash_table_insert(iter->known_on, (gpointer) n->details->id, n);
1978             }
1979             if (pcmk_is_set(iter->flags, pe_rsc_unique)) {
1980                 break;
1981             }
1982             iter = iter->parent;
1983         }
1984     }
1985 
1986     
1987     if (rsc->role > RSC_ROLE_STOPPED
1988         && node->details->online == FALSE
1989         && node->details->maintenance == FALSE
1990         && pcmk_is_set(rsc->flags, pe_rsc_managed)) {
1991 
1992         gboolean should_fence = FALSE;
1993 
1994         
1995 
1996 
1997 
1998 
1999 
2000 
2001         if (pe__is_guest_node(node)) {
2002             pe__set_resource_flags(rsc, pe_rsc_failed|pe_rsc_stop);
2003             should_fence = TRUE;
2004 
2005         } else if (pcmk_is_set(data_set->flags, pe_flag_stonith_enabled)) {
2006             if (pe__is_remote_node(node) && node->details->remote_rsc
2007                 && !pcmk_is_set(node->details->remote_rsc->flags, pe_rsc_failed)) {
2008 
2009                 
2010 
2011 
2012 
2013 
2014 
2015                 node->details->unseen = TRUE;
2016                 reason = crm_strdup_printf("%s is active there (fencing will be"
2017                                            " revoked if remote connection can "
2018                                            "be re-established elsewhere)",
2019                                            rsc->id);
2020             }
2021             should_fence = TRUE;
2022         }
2023 
2024         if (should_fence) {
2025             if (reason == NULL) {
2026                reason = crm_strdup_printf("%s is thought to be active there", rsc->id);
2027             }
2028             pe_fence_node(data_set, node, reason, FALSE);
2029         }
2030         free(reason);
2031     }
2032 
2033     
2034     save_on_fail = on_fail;
2035 
2036     if (node->details->unclean) {
2037         
2038 
2039 
2040         on_fail = action_fail_ignore;
2041     }
2042 
2043     switch (on_fail) {
2044         case action_fail_ignore:
2045             
2046             break;
2047 
2048         case action_fail_demote:
2049             pe__set_resource_flags(rsc, pe_rsc_failed);
2050             demote_action(rsc, node, FALSE);
2051             break;
2052 
2053         case action_fail_fence:
2054             
2055 
2056 
2057             reason = crm_strdup_printf("%s failed there", rsc->id);
2058             pe_fence_node(data_set, node, reason, FALSE);
2059             free(reason);
2060             break;
2061 
2062         case action_fail_standby:
2063             node->details->standby = TRUE;
2064             node->details->standby_onfail = TRUE;
2065             break;
2066 
2067         case action_fail_block:
2068             
2069 
2070 
2071             pe__clear_resource_flags(rsc, pe_rsc_managed);
2072             pe__set_resource_flags(rsc, pe_rsc_block);
2073             break;
2074 
2075         case action_fail_migrate:
2076             
2077 
2078 
2079             resource_location(rsc, node, -INFINITY, "__action_migration_auto__", data_set);
2080             break;
2081 
2082         case action_fail_stop:
2083             pe__set_next_role(rsc, RSC_ROLE_STOPPED, "on-fail=stop");
2084             break;
2085 
2086         case action_fail_recover:
2087             if (rsc->role != RSC_ROLE_STOPPED && rsc->role != RSC_ROLE_UNKNOWN) {
2088                 pe__set_resource_flags(rsc, pe_rsc_failed|pe_rsc_stop);
2089                 stop_action(rsc, node, FALSE);
2090             }
2091             break;
2092 
2093         case action_fail_restart_container:
2094             pe__set_resource_flags(rsc, pe_rsc_failed|pe_rsc_stop);
2095             if (rsc->container && pe_rsc_is_bundled(rsc)) {
2096                 
2097 
2098 
2099 
2100 
2101                 data_set->stop_needed = g_list_prepend(data_set->stop_needed,
2102                                                        rsc->container);
2103             } else if (rsc->container) {
2104                 stop_action(rsc->container, node, FALSE);
2105             } else if (rsc->role != RSC_ROLE_STOPPED && rsc->role != RSC_ROLE_UNKNOWN) {
2106                 stop_action(rsc, node, FALSE);
2107             }
2108             break;
2109 
2110         case action_fail_reset_remote:
2111             pe__set_resource_flags(rsc, pe_rsc_failed|pe_rsc_stop);
2112             if (pcmk_is_set(data_set->flags, pe_flag_stonith_enabled)) {
2113                 tmpnode = NULL;
2114                 if (rsc->is_remote_node) {
2115                     tmpnode = pe_find_node(data_set->nodes, rsc->id);
2116                 }
2117                 if (tmpnode &&
2118                     pe__is_remote_node(tmpnode) &&
2119                     tmpnode->details->remote_was_fenced == 0) {
2120 
2121                     
2122 
2123 
2124                     pe_fence_node(data_set, tmpnode,
2125                                   "remote connection is unrecoverable", FALSE);
2126                 }
2127             }
2128 
2129             
2130             if (rsc->role > RSC_ROLE_STOPPED) {
2131                 stop_action(rsc, node, FALSE);
2132             }
2133 
2134             
2135 
2136             if (rsc->remote_reconnect_ms) {
2137                 pe__set_next_role(rsc, RSC_ROLE_STOPPED, "remote reset");
2138             }
2139             break;
2140     }
2141 
2142     
2143 
2144 
2145 
2146     if (pcmk_is_set(rsc->flags, pe_rsc_failed) && rsc->is_remote_node) {
2147         tmpnode = pe_find_node(data_set->nodes, rsc->id);
2148         if (tmpnode && tmpnode->details->unclean) {
2149             tmpnode->details->unseen = FALSE;
2150         }
2151     }
2152 
2153     if (rsc->role != RSC_ROLE_STOPPED && rsc->role != RSC_ROLE_UNKNOWN) {
2154         if (pcmk_is_set(rsc->flags, pe_rsc_orphan)) {
2155             if (pcmk_is_set(rsc->flags, pe_rsc_managed)) {
2156                 pcmk__config_warn("Detected active orphan %s running on %s",
2157                                   rsc->id, node->details->uname);
2158             } else {
2159                 pcmk__config_warn("Resource '%s' must be stopped manually on "
2160                                   "%s because cluster is configured not to "
2161                                   "stop active orphans",
2162                                   rsc->id, node->details->uname);
2163             }
2164         }
2165 
2166         native_add_running(rsc, node, data_set, (save_on_fail != action_fail_ignore));
2167         switch (on_fail) {
2168             case action_fail_ignore:
2169                 break;
2170             case action_fail_demote:
2171             case action_fail_block:
2172                 pe__set_resource_flags(rsc, pe_rsc_failed);
2173                 break;
2174             default:
2175                 pe__set_resource_flags(rsc, pe_rsc_failed|pe_rsc_stop);
2176                 break;
2177         }
2178 
2179     } else if (rsc->clone_name && strchr(rsc->clone_name, ':') != NULL) {
2180         
2181 
2182 
2183         pe_rsc_trace(rsc, "Resetting clone_name %s for %s (stopped)", rsc->clone_name, rsc->id);
2184         free(rsc->clone_name);
2185         rsc->clone_name = NULL;
2186 
2187     } else {
2188         GList *possible_matches = pe__resource_actions(rsc, node, RSC_STOP,
2189                                                        FALSE);
2190         GList *gIter = possible_matches;
2191 
2192         for (; gIter != NULL; gIter = gIter->next) {
2193             pe_action_t *stop = (pe_action_t *) gIter->data;
2194 
2195             pe__set_action_flags(stop, pe_action_optional);
2196         }
2197 
2198         g_list_free(possible_matches);
2199     }
2200 }
2201 
2202 
2203 static void
2204 process_recurring(pe_node_t * node, pe_resource_t * rsc,
     
2205                   int start_index, int stop_index,
2206                   GList *sorted_op_list, pe_working_set_t * data_set)
2207 {
2208     int counter = -1;
2209     const char *task = NULL;
2210     const char *status = NULL;
2211     GList *gIter = sorted_op_list;
2212 
2213     CRM_ASSERT(rsc);
2214     pe_rsc_trace(rsc, "%s: Start index %d, stop index = %d", rsc->id, start_index, stop_index);
2215 
2216     for (; gIter != NULL; gIter = gIter->next) {
2217         xmlNode *rsc_op = (xmlNode *) gIter->data;
2218 
2219         guint interval_ms = 0;
2220         char *key = NULL;
2221         const char *id = ID(rsc_op);
2222 
2223         counter++;
2224 
2225         if (node->details->online == FALSE) {
2226             pe_rsc_trace(rsc, "Skipping %s/%s: node is offline", rsc->id, node->details->uname);
2227             break;
2228 
2229             
2230         } else if (start_index < stop_index && counter <= stop_index) {
2231             pe_rsc_trace(rsc, "Skipping %s/%s: resource is not active", id, node->details->uname);
2232             continue;
2233 
2234         } else if (counter < start_index) {
2235             pe_rsc_trace(rsc, "Skipping %s/%s: old %d", id, node->details->uname, counter);
2236             continue;
2237         }
2238 
2239         crm_element_value_ms(rsc_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms);
2240         if (interval_ms == 0) {
2241             pe_rsc_trace(rsc, "Skipping %s/%s: non-recurring", id, node->details->uname);
2242             continue;
2243         }
2244 
2245         status = crm_element_value(rsc_op, XML_LRM_ATTR_OPSTATUS);
2246         if (pcmk__str_eq(status, "-1", pcmk__str_casei)) {
2247             pe_rsc_trace(rsc, "Skipping %s/%s: status", id, node->details->uname);
2248             continue;
2249         }
2250         task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK);
2251         
2252         key = pcmk__op_key(rsc->id, task, interval_ms);
2253         pe_rsc_trace(rsc, "Creating %s/%s", key, node->details->uname);
2254         custom_action(rsc, key, task, node, TRUE, TRUE, data_set);
2255     }
2256 }
2257 
2258 void
2259 calculate_active_ops(GList *sorted_op_list, int *start_index, int *stop_index)
     
2260 {
2261     int counter = -1;
2262     int implied_monitor_start = -1;
2263     int implied_clone_start = -1;
2264     const char *task = NULL;
2265     const char *status = NULL;
2266     GList *gIter = sorted_op_list;
2267 
2268     *stop_index = -1;
2269     *start_index = -1;
2270 
2271     for (; gIter != NULL; gIter = gIter->next) {
2272         xmlNode *rsc_op = (xmlNode *) gIter->data;
2273 
2274         counter++;
2275 
2276         task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK);
2277         status = crm_element_value(rsc_op, XML_LRM_ATTR_OPSTATUS);
2278 
2279         if (pcmk__str_eq(task, CRMD_ACTION_STOP, pcmk__str_casei)
2280             && pcmk__str_eq(status, "0", pcmk__str_casei)) {
2281             *stop_index = counter;
2282 
2283         } else if (pcmk__strcase_any_of(task, CRMD_ACTION_START, CRMD_ACTION_MIGRATED, NULL)) {
2284             *start_index = counter;
2285 
2286         } else if ((implied_monitor_start <= *stop_index) && pcmk__str_eq(task, CRMD_ACTION_STATUS, pcmk__str_casei)) {
2287             const char *rc = crm_element_value(rsc_op, XML_LRM_ATTR_RC);
2288 
2289             if (pcmk__strcase_any_of(rc, "0", "8", NULL)) {
2290                 implied_monitor_start = counter;
2291             }
2292         } else if (pcmk__strcase_any_of(task, CRMD_ACTION_PROMOTE, CRMD_ACTION_DEMOTE, NULL)) {
2293             implied_clone_start = counter;
2294         }
2295     }
2296 
2297     if (*start_index == -1) {
2298         if (implied_clone_start != -1) {
2299             *start_index = implied_clone_start;
2300         } else if (implied_monitor_start != -1) {
2301             *start_index = implied_monitor_start;
2302         }
2303     }
2304 }
2305 
2306 
2307 static void
2308 unpack_shutdown_lock(xmlNode *rsc_entry, pe_resource_t *rsc, pe_node_t *node,
     
2309                      pe_working_set_t *data_set)
2310 {
2311     time_t lock_time = 0;   
2312 
2313     if ((crm_element_value_epoch(rsc_entry, XML_CONFIG_ATTR_SHUTDOWN_LOCK,
2314                                  &lock_time) == pcmk_ok) && (lock_time != 0)) {
2315 
2316         if ((data_set->shutdown_lock > 0)
2317             && (get_effective_time(data_set)
2318                 > (lock_time + data_set->shutdown_lock))) {
2319             pe_rsc_info(rsc, "Shutdown lock for %s on %s expired",
2320                         rsc->id, node->details->uname);
2321             pe__clear_resource_history(rsc, node, data_set);
2322         } else {
2323             rsc->lock_node = node;
2324             rsc->lock_time = lock_time;
2325         }
2326     }
2327 }
2328 
2329 
2330 
2331 
2332 
2333 
2334 
2335 
2336 
2337 
2338 
2339 static pe_resource_t *
2340 unpack_lrm_resource(pe_node_t *node, xmlNode *lrm_resource,
     
2341                     pe_working_set_t *data_set)
2342 {
2343     GList *gIter = NULL;
2344     int stop_index = -1;
2345     int start_index = -1;
2346     enum rsc_role_e req_role = RSC_ROLE_UNKNOWN;
2347 
2348     const char *task = NULL;
2349     const char *rsc_id = ID(lrm_resource);
2350 
2351     pe_resource_t *rsc = NULL;
2352     GList *op_list = NULL;
2353     GList *sorted_op_list = NULL;
2354 
2355     xmlNode *migrate_op = NULL;
2356     xmlNode *rsc_op = NULL;
2357     xmlNode *last_failure = NULL;
2358 
2359     enum action_fail_response on_fail = action_fail_ignore;
2360     enum rsc_role_e saved_role = RSC_ROLE_UNKNOWN;
2361 
2362     if (rsc_id == NULL) {
2363         crm_warn("Ignoring malformed " XML_LRM_TAG_RESOURCE
2364                  " entry without id");
2365         return NULL;
2366     }
2367     crm_trace("Unpacking " XML_LRM_TAG_RESOURCE " for %s on %s",
2368               rsc_id, node->details->uname);
2369 
2370     
2371     for (rsc_op = first_named_child(lrm_resource, XML_LRM_TAG_RSC_OP);
2372          rsc_op != NULL; rsc_op = crm_next_same_xml(rsc_op)) {
2373 
2374         op_list = g_list_prepend(op_list, rsc_op);
2375     }
2376 
2377     if (!pcmk_is_set(data_set->flags, pe_flag_shutdown_lock)) {
2378         if (op_list == NULL) {
2379             
2380             return NULL;
2381         }
2382     }
2383 
2384     
2385     rsc = unpack_find_resource(data_set, node, rsc_id, lrm_resource);
2386     if (rsc == NULL) {
2387         if (op_list == NULL) {
2388             
2389             return NULL;
2390         } else {
2391             rsc = process_orphan_resource(lrm_resource, node, data_set);
2392         }
2393     }
2394     CRM_ASSERT(rsc != NULL);
2395 
2396     
2397     if (pcmk_is_set(data_set->flags, pe_flag_shutdown_lock)) {
2398         unpack_shutdown_lock(lrm_resource, rsc, node, data_set);
2399     }
2400 
2401     
2402     saved_role = rsc->role;
2403     rsc->role = RSC_ROLE_UNKNOWN;
2404     sorted_op_list = g_list_sort(op_list, sort_op_by_callid);
2405 
2406     for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) {
2407         xmlNode *rsc_op = (xmlNode *) gIter->data;
2408 
2409         task = crm_element_value(rsc_op, XML_LRM_ATTR_TASK);
2410         if (pcmk__str_eq(task, CRMD_ACTION_MIGRATED, pcmk__str_casei)) {
2411             migrate_op = rsc_op;
2412         }
2413 
2414         unpack_rsc_op(rsc, node, rsc_op, &last_failure, &on_fail, data_set);
2415     }
2416 
2417     
2418     calculate_active_ops(sorted_op_list, &start_index, &stop_index);
2419     process_recurring(node, rsc, start_index, stop_index, sorted_op_list, data_set);
2420 
2421     
2422     g_list_free(sorted_op_list);
2423 
2424     process_rsc_state(rsc, node, on_fail, migrate_op, data_set);
2425 
2426     if (get_target_role(rsc, &req_role)) {
2427         if (rsc->next_role == RSC_ROLE_UNKNOWN || req_role < rsc->next_role) {
2428             pe__set_next_role(rsc, req_role, XML_RSC_ATTR_TARGET_ROLE);
2429 
2430         } else if (req_role > rsc->next_role) {
2431             pe_rsc_info(rsc, "%s: Not overwriting calculated next role %s"
2432                         " with requested next role %s",
2433                         rsc->id, role2text(rsc->next_role), role2text(req_role));
2434         }
2435     }
2436 
2437     if (saved_role > rsc->role) {
2438         rsc->role = saved_role;
2439     }
2440 
2441     return rsc;
2442 }
2443 
2444 static void
2445 handle_orphaned_container_fillers(xmlNode * lrm_rsc_list, pe_working_set_t * data_set)
     
2446 {
2447     xmlNode *rsc_entry = NULL;
2448     for (rsc_entry = pcmk__xe_first_child(lrm_rsc_list); rsc_entry != NULL;
2449          rsc_entry = pcmk__xe_next(rsc_entry)) {
2450 
2451         pe_resource_t *rsc;
2452         pe_resource_t *container;
2453         const char *rsc_id;
2454         const char *container_id;
2455 
2456         if (!pcmk__str_eq((const char *)rsc_entry->name, XML_LRM_TAG_RESOURCE, pcmk__str_casei)) {
2457             continue;
2458         }
2459 
2460         container_id = crm_element_value(rsc_entry, XML_RSC_ATTR_CONTAINER);
2461         rsc_id = crm_element_value(rsc_entry, XML_ATTR_ID);
2462         if (container_id == NULL || rsc_id == NULL) {
2463             continue;
2464         }
2465 
2466         container = pe_find_resource(data_set->resources, container_id);
2467         if (container == NULL) {
2468             continue;
2469         }
2470 
2471         rsc = pe_find_resource(data_set->resources, rsc_id);
2472         if (rsc == NULL ||
2473             !pcmk_is_set(rsc->flags, pe_rsc_orphan_container_filler) ||
2474             rsc->container != NULL) {
2475             continue;
2476         }
2477 
2478         pe_rsc_trace(rsc, "Mapped container of orphaned resource %s to %s",
2479                      rsc->id, container_id);
2480         rsc->container = container;
2481         container->fillers = g_list_append(container->fillers, rsc);
2482     }
2483 }
2484 
2485 
2486 
2487 
2488 
2489 
2490 
2491 
2492 
2493 static void
2494 unpack_node_lrm(pe_node_t *node, xmlNode *xml, pe_working_set_t *data_set)
     
2495 {
2496     bool found_orphaned_container_filler = false;
2497 
2498     
2499     xml = find_xml_node(xml, XML_CIB_TAG_LRM, FALSE);
2500     if (xml == NULL) {
2501         return;
2502     }
2503     xml = find_xml_node(xml, XML_LRM_TAG_RESOURCES, FALSE);
2504     if (xml == NULL) {
2505         return;
2506     }
2507 
2508     
2509     for (xmlNode *rsc_entry = first_named_child(xml, XML_LRM_TAG_RESOURCE);
2510          rsc_entry != NULL; rsc_entry = crm_next_same_xml(rsc_entry)) {
2511 
2512         pe_resource_t *rsc = unpack_lrm_resource(node, rsc_entry, data_set);
2513 
2514         if ((rsc != NULL)
2515             && pcmk_is_set(rsc->flags, pe_rsc_orphan_container_filler)) {
2516             found_orphaned_container_filler = true;
2517         }
2518     }
2519 
2520     
2521 
2522 
2523     if (found_orphaned_container_filler) {
2524         handle_orphaned_container_fillers(xml, data_set);
2525     }
2526 }
2527 
2528 static void
2529 set_active(pe_resource_t * rsc)
     
2530 {
2531     pe_resource_t *top = uber_parent(rsc);
2532 
2533     if (top && pcmk_is_set(top->flags, pe_rsc_promotable)) {
2534         rsc->role = RSC_ROLE_UNPROMOTED;
2535     } else {
2536         rsc->role = RSC_ROLE_STARTED;
2537     }
2538 }
2539 
2540 static void
2541 set_node_score(gpointer key, gpointer value, gpointer user_data)
     
2542 {
2543     pe_node_t *node = value;
2544     int *score = user_data;
2545 
2546     node->weight = *score;
2547 }
2548 
2549 #define STATUS_PATH_MAX 1024
2550 static xmlNode *
2551 find_lrm_op(const char *resource, const char *op, const char *node, const char *source,
     
2552             bool success_only, pe_working_set_t *data_set)
2553 {
2554     int offset = 0;
2555     char xpath[STATUS_PATH_MAX];
2556     xmlNode *xml = NULL;
2557 
2558     offset += snprintf(xpath + offset, STATUS_PATH_MAX - offset, "//node_state[@uname='%s']", node);
2559     offset +=
2560         snprintf(xpath + offset, STATUS_PATH_MAX - offset, "//" XML_LRM_TAG_RESOURCE "[@id='%s']",
2561                  resource);
2562 
2563     
2564     if (source && pcmk__str_eq(op, CRMD_ACTION_MIGRATE, pcmk__str_casei)) {
2565         offset +=
2566             snprintf(xpath + offset, STATUS_PATH_MAX - offset,
2567                      "/" XML_LRM_TAG_RSC_OP "[@operation='%s' and @migrate_target='%s']", op,
2568                      source);
2569     } else if (source && pcmk__str_eq(op, CRMD_ACTION_MIGRATED, pcmk__str_casei)) {
2570         offset +=
2571             snprintf(xpath + offset, STATUS_PATH_MAX - offset,
2572                      "/" XML_LRM_TAG_RSC_OP "[@operation='%s' and @migrate_source='%s']", op,
2573                      source);
2574     } else {
2575         offset +=
2576             snprintf(xpath + offset, STATUS_PATH_MAX - offset,
2577                      "/" XML_LRM_TAG_RSC_OP "[@operation='%s']", op);
2578     }
2579 
2580     CRM_LOG_ASSERT(offset > 0);
2581     xml = get_xpath_object(xpath, data_set->input, LOG_DEBUG);
2582 
2583     if (xml && success_only) {
2584         int rc = PCMK_OCF_UNKNOWN_ERROR;
2585         int status = PCMK_EXEC_ERROR;
2586 
2587         crm_element_value_int(xml, XML_LRM_ATTR_RC, &rc);
2588         crm_element_value_int(xml, XML_LRM_ATTR_OPSTATUS, &status);
2589         if ((rc != PCMK_OCF_OK) || (status != PCMK_EXEC_DONE)) {
2590             return NULL;
2591         }
2592     }
2593     return xml;
2594 }
2595 
2596 static int
2597 pe__call_id(xmlNode *op_xml)
     
2598 {
2599     int id = 0;
2600 
2601     if (op_xml) {
2602         crm_element_value_int(op_xml, XML_LRM_ATTR_CALLID, &id);
2603     }
2604     return id;
2605 }
2606 
2607 
2608 
2609 
2610 
2611 
2612 
2613 
2614 
2615 
2616 
2617 
2618 
2619 
2620 
2621 
2622 
2623 static bool
2624 stop_happened_after(pe_resource_t *rsc, pe_node_t *node, xmlNode *xml_op,
     
2625                     pe_working_set_t *data_set)
2626 {
2627     xmlNode *stop_op = find_lrm_op(rsc->id, CRMD_ACTION_STOP,
2628                                    node->details->uname, NULL, TRUE, data_set);
2629 
2630     return (stop_op && (pe__call_id(stop_op) > pe__call_id(xml_op)));
2631 }
2632 
2633 static void
2634 unpack_migrate_to_success(pe_resource_t *rsc, pe_node_t *node, xmlNode *xml_op,
     
2635                           pe_working_set_t *data_set)
2636 {
2637     
2638 
2639 
2640 
2641 
2642 
2643 
2644 
2645 
2646 
2647 
2648 
2649 
2650 
2651 
2652 
2653 
2654     int from_rc = 0;
2655     int from_status = 0;
2656     pe_node_t *target_node = NULL;
2657     pe_node_t *source_node = NULL;
2658     xmlNode *migrate_from = NULL;
2659     const char *source = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_SOURCE);
2660     const char *target = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_TARGET);
2661 
2662     
2663     CRM_CHECK(source && target && !strcmp(source, node->details->uname), return);
2664 
2665     if (stop_happened_after(rsc, node, xml_op, data_set)) {
2666         return;
2667     }
2668 
2669     
2670     rsc->role = RSC_ROLE_STARTED;
2671 
2672     target_node = pe_find_node(data_set->nodes, target);
2673     source_node = pe_find_node(data_set->nodes, source);
2674 
2675     
2676     migrate_from = find_lrm_op(rsc->id, CRMD_ACTION_MIGRATED, target,
2677                                source, FALSE, data_set);
2678     if (migrate_from) {
2679         crm_element_value_int(migrate_from, XML_LRM_ATTR_RC, &from_rc);
2680         crm_element_value_int(migrate_from, XML_LRM_ATTR_OPSTATUS, &from_status);
2681         pe_rsc_trace(rsc, "%s op on %s exited with status=%d, rc=%d",
2682                      ID(migrate_from), target, from_status, from_rc);
2683     }
2684 
2685     if (migrate_from && from_rc == PCMK_OCF_OK
2686         && (from_status == PCMK_EXEC_DONE)) {
2687         
2688 
2689 
2690 
2691         pe_rsc_trace(rsc, "Detected dangling migration op: %s on %s", ID(xml_op),
2692                      source);
2693         rsc->role = RSC_ROLE_STOPPED;
2694         rsc->dangling_migrations = g_list_prepend(rsc->dangling_migrations, node);
2695 
2696     } else if (migrate_from && (from_status != PCMK_EXEC_PENDING)) { 
2697         if (target_node && target_node->details->online) {
2698             pe_rsc_trace(rsc, "Marking active on %s %p %d", target, target_node,
2699                          target_node->details->online);
2700             native_add_running(rsc, target_node, data_set, TRUE);
2701         }
2702 
2703     } else { 
2704         if (target_node && target_node->details->online) {
2705             pe_rsc_trace(rsc, "Marking active on %s %p %d", target, target_node,
2706                          target_node->details->online);
2707 
2708             native_add_running(rsc, target_node, data_set, FALSE);
2709             if (source_node && source_node->details->online) {
2710                 
2711 
2712 
2713 
2714 
2715 
2716                 rsc->partial_migration_target = target_node;
2717                 rsc->partial_migration_source = source_node;
2718             }
2719         } else {
2720             
2721             pe__set_resource_flags(rsc, pe_rsc_failed|pe_rsc_stop);
2722             pe__clear_resource_flags(rsc, pe_rsc_allow_migrate);
2723         }
2724     }
2725 }
2726 
2727 
2728 static bool
2729 newer_op(pe_resource_t *rsc, const char *action_name, const char *node_name,
     
2730          int call_id, pe_working_set_t *data_set)
2731 {
2732     xmlNode *action = find_lrm_op(rsc->id, action_name, node_name, NULL, TRUE,
2733                                   data_set);
2734 
2735     return pe__call_id(action) > call_id;
2736 }
2737 
2738 static void
2739 unpack_migrate_to_failure(pe_resource_t *rsc, pe_node_t *node, xmlNode *xml_op,
     
2740                           pe_working_set_t *data_set)
2741 {
2742     int target_stop_id = 0;
2743     int target_migrate_from_id = 0;
2744     xmlNode *target_stop = NULL;
2745     xmlNode *target_migrate_from = NULL;
2746     const char *source = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_SOURCE);
2747     const char *target = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_TARGET);
2748 
2749     
2750     CRM_CHECK(source && target && !strcmp(source, node->details->uname), return);
2751 
2752     
2753 
2754 
2755     rsc->role = RSC_ROLE_STARTED;
2756 
2757     
2758     target_stop = find_lrm_op(rsc->id, CRMD_ACTION_STOP, target, NULL,
2759                               TRUE, data_set);
2760     target_stop_id = pe__call_id(target_stop);
2761 
2762     
2763     target_migrate_from = find_lrm_op(rsc->id, CRMD_ACTION_MIGRATED, target,
2764                                       source, TRUE, data_set);
2765     target_migrate_from_id = pe__call_id(target_migrate_from);
2766 
2767     if ((target_stop == NULL) || (target_stop_id < target_migrate_from_id)) {
2768         
2769 
2770 
2771 
2772         pe_node_t *target_node = pe_find_node(data_set->nodes, target);
2773 
2774         pe_rsc_trace(rsc, "stop (%d) + migrate_from (%d)",
2775                      target_stop_id, target_migrate_from_id);
2776         if (target_node && target_node->details->online) {
2777             native_add_running(rsc, target_node, data_set, FALSE);
2778         }
2779 
2780     } else if (target_migrate_from == NULL) {
2781         
2782 
2783 
2784 
2785 
2786 
2787 
2788 
2789 
2790 
2791         int source_migrate_to_id = pe__call_id(xml_op);
2792 
2793         if (newer_op(rsc, CRMD_ACTION_MIGRATED, source, source_migrate_to_id,
2794                      data_set)
2795             || newer_op(rsc, CRMD_ACTION_START, source, source_migrate_to_id,
2796                      data_set)
2797             || newer_op(rsc, CRMD_ACTION_STOP, source, source_migrate_to_id,
2798                      data_set)) {
2799             return;
2800         }
2801 
2802         
2803         rsc->dangling_migrations = g_list_prepend(rsc->dangling_migrations, node);
2804     }
2805 }
2806 
2807 static void
2808 unpack_migrate_from_failure(pe_resource_t *rsc, pe_node_t *node,
     
2809                             xmlNode *xml_op, pe_working_set_t *data_set)
2810 {
2811     xmlNode *source_stop = NULL;
2812     xmlNode *source_migrate_to = NULL;
2813     const char *source = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_SOURCE);
2814     const char *target = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_TARGET);
2815 
2816     
2817     CRM_CHECK(source && target && !strcmp(target, node->details->uname), return);
2818 
2819     
2820 
2821 
2822     rsc->role = RSC_ROLE_STARTED;
2823 
2824     
2825     source_stop = find_lrm_op(rsc->id, CRMD_ACTION_STOP, source, NULL,
2826                               TRUE, data_set);
2827 
2828     
2829     source_migrate_to = find_lrm_op(rsc->id, CRMD_ACTION_MIGRATE,
2830                                     source, target, TRUE, data_set);
2831 
2832     if ((source_stop == NULL)
2833         || (pe__call_id(source_stop) < pe__call_id(source_migrate_to))) {
2834         
2835 
2836 
2837 
2838         pe_node_t *source_node = pe_find_node(data_set->nodes, source);
2839 
2840         if (source_node && source_node->details->online) {
2841             native_add_running(rsc, source_node, data_set, TRUE);
2842         }
2843     }
2844 }
2845 
2846 static void
2847 record_failed_op(xmlNode *op, const pe_node_t *node,
     
2848                  const pe_resource_t *rsc, pe_working_set_t *data_set)
2849 {
2850     xmlNode *xIter = NULL;
2851     const char *op_key = crm_element_value(op, XML_LRM_ATTR_TASK_KEY);
2852 
2853     if (node->details->online == FALSE) {
2854         return;
2855     }
2856 
2857     for (xIter = data_set->failed->children; xIter; xIter = xIter->next) {
2858         const char *key = crm_element_value(xIter, XML_LRM_ATTR_TASK_KEY);
2859         const char *uname = crm_element_value(xIter, XML_ATTR_UNAME);
2860 
2861         if(pcmk__str_eq(op_key, key, pcmk__str_casei) && pcmk__str_eq(uname, node->details->uname, pcmk__str_casei)) {
2862             crm_trace("Skipping duplicate entry %s on %s", op_key, node->details->uname);
2863             return;
2864         }
2865     }
2866 
2867     crm_trace("Adding entry %s on %s", op_key, node->details->uname);
2868     crm_xml_add(op, XML_ATTR_UNAME, node->details->uname);
2869     crm_xml_add(op, XML_LRM_ATTR_RSCID, rsc->id);
2870     add_node_copy(data_set->failed, op);
2871 }
2872 
2873 static const char *get_op_key(xmlNode *xml_op)
     
2874 {
2875     const char *key = crm_element_value(xml_op, XML_LRM_ATTR_TASK_KEY);
2876     if(key == NULL) {
2877         key = ID(xml_op);
2878     }
2879     return key;
2880 }
2881 
2882 static const char *
2883 last_change_str(xmlNode *xml_op)
     
2884 {
2885     time_t when;
2886     const char *when_s = NULL;
2887 
2888     if (crm_element_value_epoch(xml_op, XML_RSC_OP_LAST_CHANGE,
2889                                 &when) == pcmk_ok) {
2890         when_s = pcmk__epoch2str(&when);
2891         if (when_s) {
2892             
2893             when_s = strchr(when_s, ' ');
2894             if (when_s) {
2895                 ++when_s;
2896             }
2897         }
2898     }
2899     return ((when_s && *when_s)? when_s : "unknown time");
2900 }
2901 
2902 
2903 
2904 
2905 
2906 
2907 
2908 
2909 
2910 
2911 
2912 
2913 
2914 static int
2915 cmp_on_fail(enum action_fail_response first, enum action_fail_response second)
     
2916 {
2917     switch (first) {
2918         case action_fail_demote:
2919             switch (second) {
2920                 case action_fail_ignore:
2921                     return 1;
2922                 case action_fail_demote:
2923                     return 0;
2924                 default:
2925                     return -1;
2926             }
2927             break;
2928 
2929         case action_fail_reset_remote:
2930             switch (second) {
2931                 case action_fail_ignore:
2932                 case action_fail_demote:
2933                 case action_fail_recover:
2934                     return 1;
2935                 case action_fail_reset_remote:
2936                     return 0;
2937                 default:
2938                     return -1;
2939             }
2940             break;
2941 
2942         case action_fail_restart_container:
2943             switch (second) {
2944                 case action_fail_ignore:
2945                 case action_fail_demote:
2946                 case action_fail_recover:
2947                 case action_fail_reset_remote:
2948                     return 1;
2949                 case action_fail_restart_container:
2950                     return 0;
2951                 default:
2952                     return -1;
2953             }
2954             break;
2955 
2956         default:
2957             break;
2958     }
2959     switch (second) {
2960         case action_fail_demote:
2961             return (first == action_fail_ignore)? -1 : 1;
2962 
2963         case action_fail_reset_remote:
2964             switch (first) {
2965                 case action_fail_ignore:
2966                 case action_fail_demote:
2967                 case action_fail_recover:
2968                     return -1;
2969                 default:
2970                     return 1;
2971             }
2972             break;
2973 
2974         case action_fail_restart_container:
2975             switch (first) {
2976                 case action_fail_ignore:
2977                 case action_fail_demote:
2978                 case action_fail_recover:
2979                 case action_fail_reset_remote:
2980                     return -1;
2981                 default:
2982                     return 1;
2983             }
2984             break;
2985 
2986         default:
2987             break;
2988     }
2989     return first - second;
2990 }
2991 
2992 static void
2993 unpack_rsc_op_failure(pe_resource_t * rsc, pe_node_t * node, int rc, xmlNode * xml_op, xmlNode ** last_failure,
     
2994                       enum action_fail_response * on_fail, pe_working_set_t * data_set)
2995 {
2996     bool is_probe = false;
2997     pe_action_t *action = NULL;
2998 
2999     const char *key = get_op_key(xml_op);
3000     const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK);
3001     const char *exit_reason = crm_element_value(xml_op,
3002                                                 XML_LRM_ATTR_EXIT_REASON);
3003 
3004     CRM_ASSERT(rsc);
3005     CRM_CHECK(task != NULL, return);
3006 
3007     *last_failure = xml_op;
3008 
3009     is_probe = pcmk_xe_is_probe(xml_op);
3010 
3011     if (exit_reason == NULL) {
3012         exit_reason = "";
3013     }
3014 
3015     if (!pcmk_is_set(data_set->flags, pe_flag_symmetric_cluster)
3016         && (rc == PCMK_OCF_NOT_INSTALLED)) {
3017         crm_trace("Unexpected result (%s%s%s) was recorded for "
3018                   "%s of %s on %s at %s " CRM_XS " rc=%d id=%s",
3019                   services_ocf_exitcode_str(rc),
3020                   (*exit_reason? ": " : ""), exit_reason,
3021                   (is_probe? "probe" : task), rsc->id, node->details->uname,
3022                   last_change_str(xml_op), rc, ID(xml_op));
3023     } else {
3024         crm_warn("Unexpected result (%s%s%s) was recorded for "
3025                   "%s of %s on %s at %s " CRM_XS " rc=%d id=%s",
3026                  services_ocf_exitcode_str(rc),
3027                  (*exit_reason? ": " : ""), exit_reason,
3028                  (is_probe? "probe" : task), rsc->id, node->details->uname,
3029                  last_change_str(xml_op), rc, ID(xml_op));
3030 
3031         if (is_probe && (rc != PCMK_OCF_OK)
3032             && (rc != PCMK_OCF_NOT_RUNNING)
3033             && (rc != PCMK_OCF_RUNNING_PROMOTED)) {
3034 
3035             
3036 
3037 
3038             crm_notice("If it is not possible for %s to run on %s, see "
3039                        "the resource-discovery option for location constraints",
3040                        rsc->id, node->details->uname);
3041         }
3042 
3043         record_failed_op(xml_op, node, rsc, data_set);
3044     }
3045 
3046     action = custom_action(rsc, strdup(key), task, NULL, TRUE, FALSE, data_set);
3047     if (cmp_on_fail(*on_fail, action->on_fail) < 0) {
3048         pe_rsc_trace(rsc, "on-fail %s -> %s for %s (%s)", fail2text(*on_fail),
3049                      fail2text(action->on_fail), action->uuid, key);
3050         *on_fail = action->on_fail;
3051     }
3052 
3053     if (!strcmp(task, CRMD_ACTION_STOP)) {
3054         resource_location(rsc, node, -INFINITY, "__stop_fail__", data_set);
3055 
3056     } else if (!strcmp(task, CRMD_ACTION_MIGRATE)) {
3057         unpack_migrate_to_failure(rsc, node, xml_op, data_set);
3058 
3059     } else if (!strcmp(task, CRMD_ACTION_MIGRATED)) {
3060         unpack_migrate_from_failure(rsc, node, xml_op, data_set);
3061 
3062     } else if (!strcmp(task, CRMD_ACTION_PROMOTE)) {
3063         rsc->role = RSC_ROLE_PROMOTED;
3064 
3065     } else if (!strcmp(task, CRMD_ACTION_DEMOTE)) {
3066         if (action->on_fail == action_fail_block) {
3067             rsc->role = RSC_ROLE_PROMOTED;
3068             pe__set_next_role(rsc, RSC_ROLE_STOPPED,
3069                               "demote with on-fail=block");
3070 
3071         } else if(rc == PCMK_OCF_NOT_RUNNING) {
3072             rsc->role = RSC_ROLE_STOPPED;
3073 
3074         } else {
3075             
3076 
3077 
3078 
3079 
3080             rsc->role = RSC_ROLE_UNPROMOTED;
3081         }
3082     }
3083 
3084     if(is_probe && rc == PCMK_OCF_NOT_INSTALLED) {
3085         
3086         pe_rsc_trace(rsc, "Leaving %s stopped", rsc->id);
3087         rsc->role = RSC_ROLE_STOPPED;
3088 
3089     } else if (rsc->role < RSC_ROLE_STARTED) {
3090         pe_rsc_trace(rsc, "Setting %s active", rsc->id);
3091         set_active(rsc);
3092     }
3093 
3094     pe_rsc_trace(rsc, "Resource %s: role=%s, unclean=%s, on_fail=%s, fail_role=%s",
3095                  rsc->id, role2text(rsc->role),
3096                  pcmk__btoa(node->details->unclean),
3097                  fail2text(action->on_fail), role2text(action->fail_role));
3098 
3099     if (action->fail_role != RSC_ROLE_STARTED && rsc->next_role < action->fail_role) {
3100         pe__set_next_role(rsc, action->fail_role, "failure");
3101     }
3102 
3103     if (action->fail_role == RSC_ROLE_STOPPED) {
3104         int score = -INFINITY;
3105 
3106         pe_resource_t *fail_rsc = rsc;
3107 
3108         if (fail_rsc->parent) {
3109             pe_resource_t *parent = uber_parent(fail_rsc);
3110 
3111             if (pe_rsc_is_clone(parent)
3112                 && !pcmk_is_set(parent->flags, pe_rsc_unique)) {
3113                 
3114 
3115 
3116                 fail_rsc = parent;
3117             }
3118         }
3119         crm_notice("%s will not be started under current conditions",
3120                    fail_rsc->id);
3121         
3122         if (fail_rsc->allowed_nodes != NULL) {
3123             g_hash_table_destroy(fail_rsc->allowed_nodes);
3124         }
3125         fail_rsc->allowed_nodes = pe__node_list2table(data_set->nodes);
3126         g_hash_table_foreach(fail_rsc->allowed_nodes, set_node_score, &score);
3127     }
3128 
3129     pe_free_action(action);
3130 }
3131 
3132 
3133 
3134 
3135 
3136 
3137 
3138 
3139 
3140 
3141 
3142 
3143 
3144 
3145 
3146 
3147 
3148 
3149 
3150 
3151 
3152 
3153 
3154 
3155 
3156 
3157 
3158 
3159 static void
3160 remap_operation(xmlNode *xml_op, pe_resource_t *rsc, pe_node_t *node,
     
3161                 pe_working_set_t *data_set, enum action_fail_response *on_fail,
3162                 int target_rc, int *rc, int *status) {
3163     bool is_probe = false;
3164     const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK);
3165     const char *key = get_op_key(xml_op);
3166     const char *exit_reason = crm_element_value(xml_op,
3167                                                 XML_LRM_ATTR_EXIT_REASON);
3168 
3169     if (pcmk__str_eq(task, CRMD_ACTION_STATUS, pcmk__str_none)) {
3170         int remapped_rc = pcmk__effective_rc(*rc);
3171 
3172         if (*rc != remapped_rc) {
3173             crm_trace("Remapping monitor result %d to %d", *rc, remapped_rc);
3174             if (!node->details->shutdown || node->details->online) {
3175                 record_failed_op(xml_op, node, rsc, data_set);
3176             }
3177 
3178             *rc = remapped_rc;
3179         }
3180     }
3181 
3182     if (!pe_rsc_is_bundled(rsc) && pcmk_xe_mask_probe_failure(xml_op)) {
3183         *status = PCMK_EXEC_DONE;
3184         *rc = PCMK_OCF_NOT_RUNNING;
3185     }
3186 
3187     
3188 
3189 
3190 
3191 
3192     if (*status != PCMK_EXEC_DONE && *status != PCMK_EXEC_ERROR) {
3193         return;
3194     }
3195 
3196     CRM_ASSERT(rsc);
3197     CRM_CHECK(task != NULL,
3198               *status = PCMK_EXEC_ERROR; return);
3199 
3200     *status = PCMK_EXEC_DONE;
3201 
3202     if (exit_reason == NULL) {
3203         exit_reason = "";
3204     }
3205 
3206     is_probe = pcmk_xe_is_probe(xml_op);
3207 
3208     if (is_probe) {
3209         task = "probe";
3210     }
3211 
3212     if (target_rc < 0) {
3213         
3214 
3215 
3216 
3217 
3218 
3219 
3220 
3221         *status = PCMK_EXEC_ERROR;
3222         crm_warn("Expected result not found for %s on %s (corrupt or obsolete CIB?)",
3223                  key, node->details->uname);
3224 
3225     } else if (target_rc != *rc) {
3226         *status = PCMK_EXEC_ERROR;
3227         pe_rsc_debug(rsc, "%s on %s: expected %d (%s), got %d (%s%s%s)",
3228                      key, node->details->uname,
3229                      target_rc, services_ocf_exitcode_str(target_rc),
3230                      *rc, services_ocf_exitcode_str(*rc),
3231                      (*exit_reason? ": " : ""), exit_reason);
3232     }
3233 
3234     switch (*rc) {
3235         case PCMK_OCF_OK:
3236             if (is_probe && (target_rc == PCMK_OCF_NOT_RUNNING)) {
3237                 *status = PCMK_EXEC_DONE;
3238                 pe_rsc_info(rsc, "Probe found %s active on %s at %s",
3239                             rsc->id, node->details->uname,
3240                             last_change_str(xml_op));
3241             }
3242             break;
3243 
3244         case PCMK_OCF_NOT_RUNNING:
3245             if (is_probe || (target_rc == *rc)
3246                 || !pcmk_is_set(rsc->flags, pe_rsc_managed)) {
3247 
3248                 *status = PCMK_EXEC_DONE;
3249                 rsc->role = RSC_ROLE_STOPPED;
3250 
3251                 
3252                 *on_fail = action_fail_ignore;
3253                 pe__set_next_role(rsc, RSC_ROLE_UNKNOWN, "not running");
3254             }
3255             break;
3256 
3257         case PCMK_OCF_RUNNING_PROMOTED:
3258             if (is_probe && (*rc != target_rc)) {
3259                 *status = PCMK_EXEC_DONE;
3260                 pe_rsc_info(rsc,
3261                             "Probe found %s active and promoted on %s at %s",
3262                             rsc->id, node->details->uname,
3263                             last_change_str(xml_op));
3264             }
3265             rsc->role = RSC_ROLE_PROMOTED;
3266             break;
3267 
3268         case PCMK_OCF_DEGRADED_PROMOTED:
3269         case PCMK_OCF_FAILED_PROMOTED:
3270             rsc->role = RSC_ROLE_PROMOTED;
3271             *status = PCMK_EXEC_ERROR;
3272             break;
3273 
3274         case PCMK_OCF_NOT_CONFIGURED:
3275             *status = PCMK_EXEC_ERROR_FATAL;
3276             break;
3277 
3278         case PCMK_OCF_UNIMPLEMENT_FEATURE: {
3279             guint interval_ms = 0;
3280             crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms);
3281 
3282             if (interval_ms > 0) {
3283                 *status = PCMK_EXEC_NOT_SUPPORTED;
3284                 break;
3285             }
3286             
3287         }
3288 
3289         case PCMK_OCF_NOT_INSTALLED:
3290         case PCMK_OCF_INVALID_PARAM:
3291         case PCMK_OCF_INSUFFICIENT_PRIV:
3292             if (!pe_can_fence(data_set, node)
3293                 && !strcmp(task, CRMD_ACTION_STOP)) {
3294                 
3295                 pe_proc_err("No further recovery can be attempted for %s "
3296                             "because %s on %s failed (%s%s%s) at %s "
3297                             CRM_XS " rc=%d id=%s", rsc->id, task,
3298                             node->details->uname, services_ocf_exitcode_str(*rc),
3299                             (*exit_reason? ": " : ""), exit_reason,
3300                             last_change_str(xml_op), *rc, ID(xml_op));
3301                 pe__clear_resource_flags(rsc, pe_rsc_managed);
3302                 pe__set_resource_flags(rsc, pe_rsc_block);
3303             }
3304             *status = PCMK_EXEC_ERROR_HARD;
3305             break;
3306 
3307         default:
3308             if (*status == PCMK_EXEC_DONE) {
3309                 crm_info("Treating unknown exit status %d from %s of %s "
3310                          "on %s at %s as failure",
3311                          *rc, task, rsc->id, node->details->uname,
3312                          last_change_str(xml_op));
3313                 *status = PCMK_EXEC_ERROR;
3314             }
3315             break;
3316     }
3317 
3318     pe_rsc_trace(rsc, "Remapped %s status to '%s'",
3319                  key, pcmk_exec_status_str(*status));
3320 }
3321 
3322 
3323 static bool
3324 should_clear_for_param_change(xmlNode *xml_op, const char *task,
     
3325                               pe_resource_t *rsc, pe_node_t *node,
3326                               pe_working_set_t *data_set)
3327 {
3328     if (!strcmp(task, "start") || !strcmp(task, "monitor")) {
3329 
3330         if (pe__bundle_needs_remote_name(rsc, data_set)) {
3331             
3332 
3333 
3334 
3335             pe__add_param_check(xml_op, rsc, node, pe_check_last_failure,
3336                                 data_set);
3337 
3338         } else {
3339             op_digest_cache_t *digest_data = NULL;
3340 
3341             digest_data = rsc_action_digest_cmp(rsc, xml_op, node, data_set);
3342             switch (digest_data->rc) {
3343                 case RSC_DIGEST_UNKNOWN:
3344                     crm_trace("Resource %s history entry %s on %s"
3345                               " has no digest to compare",
3346                               rsc->id, get_op_key(xml_op), node->details->id);
3347                     break;
3348                 case RSC_DIGEST_MATCH:
3349                     break;
3350                 default:
3351                     return TRUE;
3352             }
3353         }
3354     }
3355     return FALSE;
3356 }
3357 
3358 
3359 static void
3360 order_after_remote_fencing(pe_action_t *action, pe_resource_t *remote_conn,
     
3361                            pe_working_set_t *data_set)
3362 {
3363     pe_node_t *remote_node = pe_find_node(data_set->nodes, remote_conn->id);
3364 
3365     if (remote_node) {
3366         pe_action_t *fence = pe_fence_op(remote_node, NULL, TRUE, NULL,
3367                                          FALSE, data_set);
3368 
3369         order_actions(fence, action, pe_order_implies_then);
3370     }
3371 }
3372 
3373 static bool
3374 should_ignore_failure_timeout(pe_resource_t *rsc, xmlNode *xml_op,
     
3375                               const char *task, guint interval_ms,
3376                               bool is_last_failure, pe_working_set_t *data_set)
3377 {
3378     
3379 
3380 
3381 
3382 
3383 
3384 
3385 
3386 
3387 
3388 
3389 
3390 
3391 
3392 
3393 
3394 
3395 
3396 
3397 
3398     if (rsc->remote_reconnect_ms
3399         && pcmk_is_set(data_set->flags, pe_flag_stonith_enabled)
3400         && (interval_ms != 0) && pcmk__str_eq(task, CRMD_ACTION_STATUS, pcmk__str_casei)) {
3401 
3402         pe_node_t *remote_node = pe_find_node(data_set->nodes, rsc->id);
3403 
3404         if (remote_node && !remote_node->details->remote_was_fenced) {
3405             if (is_last_failure) {
3406                 crm_info("Waiting to clear monitor failure for remote node %s"
3407                          " until fencing has occurred", rsc->id);
3408             }
3409             return TRUE;
3410         }
3411     }
3412     return FALSE;
3413 }
3414 
3415 
3416 
3417 
3418 
3419 
3420 
3421 
3422 
3423 
3424 
3425 
3426 
3427 
3428 
3429 
3430 
3431 
3432 
3433 
3434 
3435 
3436 
3437 static bool
3438 check_operation_expiry(pe_resource_t *rsc, pe_node_t *node, int rc,
     
3439                        xmlNode *xml_op, pe_working_set_t *data_set)
3440 {
3441     bool expired = FALSE;
3442     bool is_last_failure = pcmk__ends_with(ID(xml_op), "_last_failure_0");
3443     time_t last_run = 0;
3444     guint interval_ms = 0;
3445     int unexpired_fail_count = 0;
3446     const char *task = crm_element_value(xml_op, XML_LRM_ATTR_TASK);
3447     const char *clear_reason = NULL;
3448 
3449     crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms);
3450 
3451     if ((rsc->failure_timeout > 0)
3452         && (crm_element_value_epoch(xml_op, XML_RSC_OP_LAST_CHANGE,
3453                                     &last_run) == 0)) {
3454 
3455         
3456 
3457         time_t now = get_effective_time(data_set);
3458         time_t last_failure = 0;
3459 
3460         
3461         if ((now >= (last_run + rsc->failure_timeout))
3462             && !should_ignore_failure_timeout(rsc, xml_op, task, interval_ms,
3463                                               is_last_failure, data_set)) {
3464             expired = TRUE;
3465         }
3466 
3467         
3468         unexpired_fail_count = pe_get_failcount(node, rsc, &last_failure,
3469                                                 pe_fc_effective, xml_op,
3470                                                 data_set);
3471 
3472         
3473         crm_trace("%s@%lld is %sexpired @%lld with unexpired_failures=%d timeout=%ds"
3474                   " last-failure@%lld",
3475                   ID(xml_op), (long long) last_run, (expired? "" : "not "),
3476                   (long long) now, unexpired_fail_count, rsc->failure_timeout,
3477                   (long long) last_failure);
3478         last_failure += rsc->failure_timeout + 1;
3479         if (unexpired_fail_count && (now < last_failure)) {
3480             pe__update_recheck_time(last_failure, data_set);
3481         }
3482     }
3483 
3484     if (expired) {
3485         if (pe_get_failcount(node, rsc, NULL, pe_fc_default, xml_op, data_set)) {
3486 
3487             
3488 
3489             if (unexpired_fail_count == 0) {
3490                 
3491                 clear_reason = "it expired";
3492 
3493             } else {
3494                 
3495 
3496 
3497 
3498 
3499 
3500                 expired = FALSE;
3501             }
3502 
3503         } else if (is_last_failure && rsc->remote_reconnect_ms) {
3504             
3505 
3506 
3507             clear_reason = "reconnect interval is set";
3508         }
3509     }
3510 
3511     if (!expired && is_last_failure
3512         && should_clear_for_param_change(xml_op, task, rsc, node, data_set)) {
3513         clear_reason = "resource parameters have changed";
3514     }
3515 
3516     if (clear_reason != NULL) {
3517         
3518         pe_action_t *clear_op = pe__clear_failcount(rsc, node, clear_reason,
3519                                                     data_set);
3520 
3521         if (pcmk_is_set(data_set->flags, pe_flag_stonith_enabled)
3522             && rsc->remote_reconnect_ms) {
3523             
3524 
3525 
3526 
3527 
3528 
3529 
3530 
3531             crm_info("Clearing %s failure will wait until any scheduled "
3532                      "fencing of %s completes", task, rsc->id);
3533             order_after_remote_fencing(clear_op, rsc, data_set);
3534         }
3535     }
3536 
3537     if (expired && (interval_ms == 0) && pcmk__str_eq(task, CRMD_ACTION_STATUS, pcmk__str_casei)) {
3538         switch(rc) {
3539             case PCMK_OCF_OK:
3540             case PCMK_OCF_NOT_RUNNING:
3541             case PCMK_OCF_RUNNING_PROMOTED:
3542             case PCMK_OCF_DEGRADED:
3543             case PCMK_OCF_DEGRADED_PROMOTED:
3544                 
3545                 expired = FALSE;
3546                 break;
3547         }
3548     }
3549 
3550     return expired;
3551 }
3552 
3553 int pe__target_rc_from_xml(xmlNode *xml_op)
     
3554 {
3555     int target_rc = 0;
3556     const char *key = crm_element_value(xml_op, XML_ATTR_TRANSITION_KEY);
3557 
3558     if (key == NULL) {
3559         return -1;
3560     }
3561     decode_transition_key(key, NULL, NULL, NULL, &target_rc);
3562     return target_rc;
3563 }
3564 
3565 static enum action_fail_response
3566 get_action_on_fail(pe_resource_t *rsc, const char *key, const char *task, pe_working_set_t * data_set) 
     
3567 {
3568     enum action_fail_response result = action_fail_recover;
3569     pe_action_t *action = custom_action(rsc, strdup(key), task, NULL, TRUE, FALSE, data_set);
3570 
3571     result = action->on_fail;
3572     pe_free_action(action);
3573 
3574     return result;
3575 }
3576 
3577 static void
3578 update_resource_state(pe_resource_t * rsc, pe_node_t * node, xmlNode * xml_op, const char * task, int rc,
     
3579                       xmlNode * last_failure, enum action_fail_response * on_fail, pe_working_set_t * data_set)
3580 {
3581     gboolean clear_past_failure = FALSE;
3582 
3583     CRM_ASSERT(rsc);
3584     CRM_ASSERT(xml_op);
3585 
3586     if (rc == PCMK_OCF_NOT_INSTALLED || (!pe_rsc_is_bundled(rsc) && pcmk_xe_mask_probe_failure(xml_op))) {
3587         rsc->role = RSC_ROLE_STOPPED;
3588 
3589     } else if (rc == PCMK_OCF_NOT_RUNNING) {
3590         clear_past_failure = TRUE;
3591 
3592     } else if (pcmk__str_eq(task, CRMD_ACTION_STATUS, pcmk__str_casei)) {
3593         if (last_failure) {
3594             const char *op_key = get_op_key(xml_op);
3595             const char *last_failure_key = get_op_key(last_failure);
3596 
3597             if (pcmk__str_eq(op_key, last_failure_key, pcmk__str_casei)) {
3598                 clear_past_failure = TRUE;
3599             }
3600         }
3601 
3602         if (rsc->role < RSC_ROLE_STARTED) {
3603             set_active(rsc);
3604         }
3605 
3606     } else if (pcmk__str_eq(task, CRMD_ACTION_START, pcmk__str_casei)) {
3607         rsc->role = RSC_ROLE_STARTED;
3608         clear_past_failure = TRUE;
3609 
3610     } else if (pcmk__str_eq(task, CRMD_ACTION_STOP, pcmk__str_casei)) {
3611         rsc->role = RSC_ROLE_STOPPED;
3612         clear_past_failure = TRUE;
3613 
3614     } else if (pcmk__str_eq(task, CRMD_ACTION_PROMOTE, pcmk__str_casei)) {
3615         rsc->role = RSC_ROLE_PROMOTED;
3616         clear_past_failure = TRUE;
3617 
3618     } else if (pcmk__str_eq(task, CRMD_ACTION_DEMOTE, pcmk__str_casei)) {
3619 
3620         if (*on_fail == action_fail_demote) {
3621             
3622             clear_past_failure = TRUE;
3623         }
3624         rsc->role = RSC_ROLE_UNPROMOTED;
3625 
3626     } else if (pcmk__str_eq(task, CRMD_ACTION_MIGRATED, pcmk__str_casei)) {
3627         rsc->role = RSC_ROLE_STARTED;
3628         clear_past_failure = TRUE;
3629 
3630     } else if (pcmk__str_eq(task, CRMD_ACTION_MIGRATE, pcmk__str_casei)) {
3631         unpack_migrate_to_success(rsc, node, xml_op, data_set);
3632 
3633     } else if (rsc->role < RSC_ROLE_STARTED) {
3634         pe_rsc_trace(rsc, "%s active on %s", rsc->id, node->details->uname);
3635         set_active(rsc);
3636     }
3637 
3638     
3639     if (clear_past_failure) {
3640         switch (*on_fail) {
3641             case action_fail_stop:
3642             case action_fail_fence:
3643             case action_fail_migrate:
3644             case action_fail_standby:
3645                 pe_rsc_trace(rsc, "%s.%s is not cleared by a completed stop",
3646                              rsc->id, fail2text(*on_fail));
3647                 break;
3648 
3649             case action_fail_block:
3650             case action_fail_ignore:
3651             case action_fail_demote:
3652             case action_fail_recover:
3653             case action_fail_restart_container:
3654                 *on_fail = action_fail_ignore;
3655                 pe__set_next_role(rsc, RSC_ROLE_UNKNOWN, "clear past failures");
3656                 break;
3657             case action_fail_reset_remote:
3658                 if (rsc->remote_reconnect_ms == 0) {
3659                     
3660 
3661 
3662 
3663 
3664 
3665                     *on_fail = action_fail_ignore;
3666                     pe__set_next_role(rsc, RSC_ROLE_UNKNOWN,
3667                                       "clear past failures and reset remote");
3668                 }
3669                 break;
3670         }
3671     }
3672 }
3673 
3674 static void
3675 unpack_rsc_op(pe_resource_t *rsc, pe_node_t *node, xmlNode *xml_op,
     
3676               xmlNode **last_failure, enum action_fail_response *on_fail,
3677               pe_working_set_t *data_set)
3678 {
3679     int rc = 0;
3680     int old_rc = 0;
3681     int task_id = 0;
3682     int target_rc = 0;
3683     int old_target_rc = 0;
3684     int status = PCMK_EXEC_UNKNOWN;
3685     guint interval_ms = 0;
3686     const char *task = NULL;
3687     const char *task_key = NULL;
3688     const char *exit_reason = NULL;
3689     bool expired = false;
3690     pe_resource_t *parent = rsc;
3691     enum action_fail_response failure_strategy = action_fail_recover;
3692     bool maskable_probe_failure = false;
3693 
3694     CRM_CHECK(rsc && node && xml_op, return);
3695 
3696     target_rc = pe__target_rc_from_xml(xml_op);
3697     task_key = get_op_key(xml_op);
3698     task = crm_element_value(xml_op, XML_LRM_ATTR_TASK);
3699     exit_reason = crm_element_value(xml_op, XML_LRM_ATTR_EXIT_REASON);
3700     if (exit_reason == NULL) {
3701         exit_reason = "";
3702     }
3703 
3704     crm_element_value_int(xml_op, XML_LRM_ATTR_RC, &rc);
3705     crm_element_value_int(xml_op, XML_LRM_ATTR_CALLID, &task_id);
3706     crm_element_value_int(xml_op, XML_LRM_ATTR_OPSTATUS, &status);
3707     crm_element_value_ms(xml_op, XML_LRM_ATTR_INTERVAL_MS, &interval_ms);
3708 
3709     CRM_CHECK(task != NULL, return);
3710     CRM_CHECK((status >= PCMK_EXEC_PENDING) && (status <= PCMK_EXEC_MAX),
3711               return);
3712 
3713     if (!strcmp(task, CRMD_ACTION_NOTIFY) ||
3714         !strcmp(task, CRMD_ACTION_METADATA)) {
3715         
3716         return;
3717     }
3718 
3719     if (!pcmk_is_set(rsc->flags, pe_rsc_unique)) {
3720         parent = uber_parent(rsc);
3721     }
3722 
3723     pe_rsc_trace(rsc, "Unpacking task %s/%s (call_id=%d, status=%d, rc=%d) on %s (role=%s)",
3724                  task_key, task, task_id, status, rc, node->details->uname, role2text(rsc->role));
3725 
3726     if (node->details->unclean) {
3727         pe_rsc_trace(rsc, "Node %s (where %s is running) is unclean."
3728                      " Further action depends on the value of the stop's on-fail attribute",
3729                      node->details->uname, rsc->id);
3730     }
3731 
3732     
3733 
3734 
3735 
3736 
3737 
3738 
3739 
3740 
3741 
3742 
3743 
3744     if ((status != PCMK_EXEC_NOT_INSTALLED)
3745         && check_operation_expiry(rsc, node, rc, xml_op, data_set)) {
3746         expired = true;
3747     }
3748 
3749     old_rc = rc;
3750     old_target_rc = target_rc;
3751 
3752     remap_operation(xml_op, rsc, node, data_set, on_fail, target_rc,
3753                     &rc, &status);
3754 
3755     maskable_probe_failure = !pe_rsc_is_bundled(rsc) && pcmk_xe_mask_probe_failure(xml_op);
3756 
3757     if (expired && maskable_probe_failure && old_rc != old_target_rc) {
3758         if (rsc->role <= RSC_ROLE_STOPPED) {
3759             rsc->role = RSC_ROLE_UNKNOWN;
3760         }
3761 
3762         goto done;
3763 
3764     } else if (expired && (rc != target_rc)) {
3765         const char *magic = crm_element_value(xml_op, XML_ATTR_TRANSITION_MAGIC);
3766 
3767         if (interval_ms == 0) {
3768             crm_notice("Ignoring expired %s failure on %s "
3769                        CRM_XS " actual=%d expected=%d magic=%s",
3770                        task_key, node->details->uname, rc, target_rc, magic);
3771             goto done;
3772 
3773         } else if(node->details->online && node->details->unclean == FALSE) {
3774             
3775 
3776 
3777 
3778 
3779 
3780 
3781 
3782 
3783 
3784             crm_notice("Rescheduling %s after failure expired on %s "
3785                        CRM_XS " actual=%d expected=%d magic=%s",
3786                        task_key, node->details->uname, rc, target_rc, magic);
3787             crm_xml_add(xml_op, XML_LRM_ATTR_RESTART_DIGEST, "calculated-failure-timeout");
3788             goto done;
3789         }
3790     }
3791 
3792     if (maskable_probe_failure) {
3793         crm_notice("Treating probe result '%s' for %s on %s as 'not running'",
3794                    services_ocf_exitcode_str(old_rc), rsc->id, node->details->uname);
3795         update_resource_state(rsc, node, xml_op, task, target_rc, *last_failure,
3796                               on_fail, data_set);
3797         crm_xml_add(xml_op, XML_ATTR_UNAME, node->details->uname);
3798 
3799         record_failed_op(xml_op, node, rsc, data_set);
3800         resource_location(parent, node, -INFINITY, "masked-probe-failure", data_set);
3801         goto done;
3802     }
3803 
3804     switch (status) {
3805         case PCMK_EXEC_CANCELLED:
3806             
3807             pe_err("Resource history contains cancellation '%s' "
3808                    "(%s of %s on %s at %s)",
3809                    ID(xml_op), task, rsc->id, node->details->uname,
3810                    last_change_str(xml_op));
3811             goto done;
3812 
3813         case PCMK_EXEC_PENDING:
3814             if (!strcmp(task, CRMD_ACTION_START)) {
3815                 pe__set_resource_flags(rsc, pe_rsc_start_pending);
3816                 set_active(rsc);
3817 
3818             } else if (!strcmp(task, CRMD_ACTION_PROMOTE)) {
3819                 rsc->role = RSC_ROLE_PROMOTED;
3820 
3821             } else if (!strcmp(task, CRMD_ACTION_MIGRATE) && node->details->unclean) {
3822                 
3823 
3824                 const char *migrate_target = crm_element_value(xml_op, XML_LRM_ATTR_MIGRATE_TARGET);
3825                 pe_node_t *target = pe_find_node(data_set->nodes, migrate_target);
3826                 if (target) {
3827                     stop_action(rsc, target, FALSE);
3828                 }
3829             }
3830 
3831             if (rsc->pending_task == NULL) {
3832                 if ((interval_ms != 0) || strcmp(task, CRMD_ACTION_STATUS)) {
3833                     rsc->pending_task = strdup(task);
3834                     rsc->pending_node = node;
3835                 } else {
3836                     
3837 
3838 
3839 
3840 
3841 #if 0
3842                     rsc->pending_task = strdup("probe");
3843                     rsc->pending_node = node;
3844 #endif
3845                 }
3846             }
3847             goto done;
3848 
3849         case PCMK_EXEC_DONE:
3850             pe_rsc_trace(rsc, "%s of %s on %s completed at %s " CRM_XS " id=%s",
3851                          task, rsc->id, node->details->uname,
3852                          last_change_str(xml_op), ID(xml_op));
3853             update_resource_state(rsc, node, xml_op, task, rc, *last_failure, on_fail, data_set);
3854             goto done;
3855 
3856         case PCMK_EXEC_NOT_INSTALLED:
3857             failure_strategy = get_action_on_fail(rsc, task_key, task, data_set);
3858             if (failure_strategy == action_fail_ignore) {
3859                 crm_warn("Cannot ignore failed %s of %s on %s: "
3860                          "Resource agent doesn't exist "
3861                          CRM_XS " status=%d rc=%d id=%s",
3862                          task, rsc->id, node->details->uname, status, rc,
3863                          ID(xml_op));
3864                 
3865                 *on_fail = action_fail_migrate;
3866             }
3867             resource_location(parent, node, -INFINITY, "hard-error", data_set);
3868             unpack_rsc_op_failure(rsc, node, rc, xml_op, last_failure, on_fail, data_set);
3869             goto done;
3870 
3871         case PCMK_EXEC_NOT_CONNECTED:
3872             if (pe__is_guest_or_remote_node(node)
3873                 && pcmk_is_set(node->details->remote_rsc->flags, pe_rsc_managed)) {
3874                 
3875 
3876 
3877 
3878 
3879 
3880                 pe__set_resource_flags(node->details->remote_rsc,
3881                                        pe_rsc_failed|pe_rsc_stop);
3882             }
3883             break; 
3884 
3885         case PCMK_EXEC_ERROR:
3886         case PCMK_EXEC_ERROR_HARD:
3887         case PCMK_EXEC_ERROR_FATAL:
3888         case PCMK_EXEC_TIMEOUT:
3889         case PCMK_EXEC_NOT_SUPPORTED:
3890         case PCMK_EXEC_INVALID:
3891             break; 
3892 
3893         case PCMK_EXEC_NO_FENCE_DEVICE:
3894         case PCMK_EXEC_NO_SECRETS:
3895             status = PCMK_EXEC_ERROR_HARD;
3896             break; 
3897     }
3898 
3899     failure_strategy = get_action_on_fail(rsc, task_key, task, data_set);
3900     if ((failure_strategy == action_fail_ignore)
3901         || (failure_strategy == action_fail_restart_container
3902             && !strcmp(task, CRMD_ACTION_STOP))) {
3903 
3904         crm_warn("Pretending failed %s (%s%s%s) of %s on %s at %s "
3905                  "succeeded " CRM_XS " rc=%d id=%s",
3906                  task, services_ocf_exitcode_str(rc),
3907                  (*exit_reason? ": " : ""), exit_reason, rsc->id,
3908                  node->details->uname, last_change_str(xml_op), rc,
3909                  ID(xml_op));
3910 
3911         update_resource_state(rsc, node, xml_op, task, target_rc, *last_failure,
3912                               on_fail, data_set);
3913         crm_xml_add(xml_op, XML_ATTR_UNAME, node->details->uname);
3914         pe__set_resource_flags(rsc, pe_rsc_failure_ignored);
3915 
3916         record_failed_op(xml_op, node, rsc, data_set);
3917 
3918         if ((failure_strategy == action_fail_restart_container)
3919             && cmp_on_fail(*on_fail, action_fail_recover) <= 0) {
3920             *on_fail = failure_strategy;
3921         }
3922 
3923     } else {
3924         unpack_rsc_op_failure(rsc, node, rc, xml_op, last_failure, on_fail,
3925                               data_set);
3926 
3927         if (status == PCMK_EXEC_ERROR_HARD) {
3928             do_crm_log(rc != PCMK_OCF_NOT_INSTALLED?LOG_ERR:LOG_NOTICE,
3929                        "Preventing %s from restarting on %s because "
3930                        "of hard failure (%s%s%s)" CRM_XS " rc=%d id=%s",
3931                        parent->id, node->details->uname,
3932                        services_ocf_exitcode_str(rc),
3933                        (*exit_reason? ": " : ""), exit_reason,
3934                        rc, ID(xml_op));
3935             resource_location(parent, node, -INFINITY, "hard-error", data_set);
3936 
3937         } else if (status == PCMK_EXEC_ERROR_FATAL) {
3938             crm_err("Preventing %s from restarting anywhere because "
3939                     "of fatal failure (%s%s%s) " CRM_XS " rc=%d id=%s",
3940                     parent->id, services_ocf_exitcode_str(rc),
3941                     (*exit_reason? ": " : ""), exit_reason,
3942                     rc, ID(xml_op));
3943             resource_location(parent, NULL, -INFINITY, "fatal-error", data_set);
3944         }
3945     }
3946 
3947 done:
3948     pe_rsc_trace(rsc, "Resource %s after %s: role=%s, next=%s",
3949                  rsc->id, task, role2text(rsc->role),
3950                  role2text(rsc->next_role));
3951 }
3952 
3953 static void
3954 add_node_attrs(xmlNode *xml_obj, pe_node_t *node, bool overwrite,
     
3955                pe_working_set_t *data_set)
3956 {
3957     const char *cluster_name = NULL;
3958 
3959     pe_rule_eval_data_t rule_data = {
3960         .node_hash = NULL,
3961         .role = RSC_ROLE_UNKNOWN,
3962         .now = data_set->now,
3963         .match_data = NULL,
3964         .rsc_data = NULL,
3965         .op_data = NULL
3966     };
3967 
3968     g_hash_table_insert(node->details->attrs,
3969                         strdup(CRM_ATTR_UNAME), strdup(node->details->uname));
3970 
3971     g_hash_table_insert(node->details->attrs, strdup(CRM_ATTR_ID),
3972                         strdup(node->details->id));
3973     if (pcmk__str_eq(node->details->id, data_set->dc_uuid, pcmk__str_casei)) {
3974         data_set->dc_node = node;
3975         node->details->is_dc = TRUE;
3976         g_hash_table_insert(node->details->attrs,
3977                             strdup(CRM_ATTR_IS_DC), strdup(XML_BOOLEAN_TRUE));
3978     } else {
3979         g_hash_table_insert(node->details->attrs,
3980                             strdup(CRM_ATTR_IS_DC), strdup(XML_BOOLEAN_FALSE));
3981     }
3982 
3983     cluster_name = g_hash_table_lookup(data_set->config_hash, "cluster-name");
3984     if (cluster_name) {
3985         g_hash_table_insert(node->details->attrs, strdup(CRM_ATTR_CLUSTER_NAME),
3986                             strdup(cluster_name));
3987     }
3988 
3989     pe__unpack_dataset_nvpairs(xml_obj, XML_TAG_ATTR_SETS, &rule_data,
3990                                node->details->attrs, NULL, overwrite, data_set);
3991 
3992     if (pe_node_attribute_raw(node, CRM_ATTR_SITE_NAME) == NULL) {
3993         const char *site_name = pe_node_attribute_raw(node, "site-name");
3994 
3995         if (site_name) {
3996             g_hash_table_insert(node->details->attrs,
3997                                 strdup(CRM_ATTR_SITE_NAME),
3998                                 strdup(site_name));
3999 
4000         } else if (cluster_name) {
4001             
4002             g_hash_table_insert(node->details->attrs,
4003                                 strdup(CRM_ATTR_SITE_NAME),
4004                                 strdup(cluster_name));
4005         }
4006     }
4007 }
4008 
4009 static GList *
4010 extract_operations(const char *node, const char *rsc, xmlNode * rsc_entry, gboolean active_filter)
     
4011 {
4012     int counter = -1;
4013     int stop_index = -1;
4014     int start_index = -1;
4015 
4016     xmlNode *rsc_op = NULL;
4017 
4018     GList *gIter = NULL;
4019     GList *op_list = NULL;
4020     GList *sorted_op_list = NULL;
4021 
4022     
4023     op_list = NULL;
4024     sorted_op_list = NULL;
4025 
4026     for (rsc_op = pcmk__xe_first_child(rsc_entry);
4027          rsc_op != NULL; rsc_op = pcmk__xe_next(rsc_op)) {
4028 
4029         if (pcmk__str_eq((const char *)rsc_op->name, XML_LRM_TAG_RSC_OP,
4030                          pcmk__str_none)) {
4031             crm_xml_add(rsc_op, "resource", rsc);
4032             crm_xml_add(rsc_op, XML_ATTR_UNAME, node);
4033             op_list = g_list_prepend(op_list, rsc_op);
4034         }
4035     }
4036 
4037     if (op_list == NULL) {
4038         
4039         return NULL;
4040     }
4041 
4042     sorted_op_list = g_list_sort(op_list, sort_op_by_callid);
4043 
4044     
4045     if (active_filter == FALSE) {
4046         return sorted_op_list;
4047     }
4048 
4049     op_list = NULL;
4050 
4051     calculate_active_ops(sorted_op_list, &start_index, &stop_index);
4052 
4053     for (gIter = sorted_op_list; gIter != NULL; gIter = gIter->next) {
4054         xmlNode *rsc_op = (xmlNode *) gIter->data;
4055 
4056         counter++;
4057 
4058         if (start_index < stop_index) {
4059             crm_trace("Skipping %s: not active", ID(rsc_entry));
4060             break;
4061 
4062         } else if (counter < start_index) {
4063             crm_trace("Skipping %s: old", ID(rsc_op));
4064             continue;
4065         }
4066         op_list = g_list_append(op_list, rsc_op);
4067     }
4068 
4069     g_list_free(sorted_op_list);
4070     return op_list;
4071 }
4072 
4073 GList *
4074 find_operations(const char *rsc, const char *node, gboolean active_filter,
     
4075                 pe_working_set_t * data_set)
4076 {
4077     GList *output = NULL;
4078     GList *intermediate = NULL;
4079 
4080     xmlNode *tmp = NULL;
4081     xmlNode *status = find_xml_node(data_set->input, XML_CIB_TAG_STATUS, TRUE);
4082 
4083     pe_node_t *this_node = NULL;
4084 
4085     xmlNode *node_state = NULL;
4086 
4087     for (node_state = pcmk__xe_first_child(status); node_state != NULL;
4088          node_state = pcmk__xe_next(node_state)) {
4089 
4090         if (pcmk__str_eq((const char *)node_state->name, XML_CIB_TAG_STATE, pcmk__str_none)) {
4091             const char *uname = crm_element_value(node_state, XML_ATTR_UNAME);
4092 
4093             if (node != NULL && !pcmk__str_eq(uname, node, pcmk__str_casei)) {
4094                 continue;
4095             }
4096 
4097             this_node = pe_find_node(data_set->nodes, uname);
4098             if(this_node == NULL) {
4099                 CRM_LOG_ASSERT(this_node != NULL);
4100                 continue;
4101 
4102             } else if (pe__is_guest_or_remote_node(this_node)) {
4103                 determine_remote_online_status(data_set, this_node);
4104 
4105             } else {
4106                 determine_online_status(node_state, this_node, data_set);
4107             }
4108 
4109             if (this_node->details->online
4110                 || pcmk_is_set(data_set->flags, pe_flag_stonith_enabled)) {
4111                 
4112 
4113 
4114 
4115                 xmlNode *lrm_rsc = NULL;
4116 
4117                 tmp = find_xml_node(node_state, XML_CIB_TAG_LRM, FALSE);
4118                 tmp = find_xml_node(tmp, XML_LRM_TAG_RESOURCES, FALSE);
4119 
4120                 for (lrm_rsc = pcmk__xe_first_child(tmp); lrm_rsc != NULL;
4121                      lrm_rsc = pcmk__xe_next(lrm_rsc)) {
4122 
4123                     if (pcmk__str_eq((const char *)lrm_rsc->name,
4124                                      XML_LRM_TAG_RESOURCE, pcmk__str_none)) {
4125 
4126                         const char *rsc_id = crm_element_value(lrm_rsc, XML_ATTR_ID);
4127 
4128                         if (rsc != NULL && !pcmk__str_eq(rsc_id, rsc, pcmk__str_casei)) {
4129                             continue;
4130                         }
4131 
4132                         intermediate = extract_operations(uname, rsc_id, lrm_rsc, active_filter);
4133                         output = g_list_concat(output, intermediate);
4134                     }
4135                 }
4136             }
4137         }
4138     }
4139 
4140     return output;
4141 }