File bug-972187_pacemaker-pengine-consider-resource-failed-if-any-configured-monitor-operations-failed.patch of Package pacemaker.9287

From bcf3347f205692a6cd65669ba089ef31d5360476 Mon Sep 17 00:00:00 2001
From: "Gao,Yan" <ygao@suse.com>
Date: Thu, 14 Apr 2016 14:16:25 +0200
Subject: [PATCH] Fix: pengine: Consider resource failed if any of the
 configured monitor operations failed

Previously with d87de1b, if not all the configured monitor operations
failed, the resource could be considered running well.

This commit fixes it by conditionally "clear_past_failure".
---
 lib/pengine/unpack.c | 38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)

Index: pacemaker/lib/pengine/unpack.c
===================================================================
--- pacemaker.orig/lib/pengine/unpack.c
+++ pacemaker/lib/pengine/unpack.c
@@ -42,7 +42,7 @@ CRM_TRACE_INIT_DATA(pe_status);
 	}								\
     } while(0)
 
-gboolean unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op,
+gboolean unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op, xmlNode ** last_failure,
                        enum action_fail_response *failed, pe_working_set_t * data_set);
 static gboolean determine_remote_online_status(node_t * this_node);
 
@@ -2004,6 +2004,7 @@ unpack_lrm_rsc_state(node_t * node, xmlN
 
     xmlNode *migrate_op = NULL;
     xmlNode *rsc_op = NULL;
+    xmlNode *last_failure = NULL;
 
     enum action_fail_response on_fail = FALSE;
     enum rsc_role_e saved_role = RSC_ROLE_UNKNOWN;
@@ -2047,7 +2048,7 @@ unpack_lrm_rsc_state(node_t * node, xmlN
             migrate_op = rsc_op;
         }
 
-        unpack_rsc_op(rsc, node, rsc_op, &on_fail, data_set);
+        unpack_rsc_op(rsc, node, rsc_op, &last_failure, &on_fail, data_set);
     }
 
     /* create active recurring operations as optional */
@@ -2406,7 +2407,8 @@ static const char *get_op_key(xmlNode *x
 }
 
 static void
-unpack_rsc_op_failure(resource_t *rsc, node_t *node, int rc, xmlNode *xml_op, enum action_fail_response *on_fail, pe_working_set_t * data_set) 
+unpack_rsc_op_failure(resource_t * rsc, node_t * node, int rc, xmlNode * xml_op, xmlNode ** last_failure,
+                      enum action_fail_response * on_fail, pe_working_set_t * data_set)
 {
     int interval = 0;
     bool is_probe = FALSE;
@@ -2417,6 +2419,9 @@ unpack_rsc_op_failure(resource_t *rsc, n
     const char *op_version = crm_element_value(xml_op, XML_ATTR_CRM_VERSION);
 
     CRM_ASSERT(rsc);
+
+    *last_failure = xml_op;
+
     crm_element_value_int(xml_op, XML_LRM_ATTR_INTERVAL, &interval);
     if(interval == 0 && safe_str_eq(task, CRMD_ACTION_STATUS)) {
         is_probe = TRUE;
@@ -2750,12 +2755,14 @@ get_action_on_fail(resource_t *rsc, cons
 }
 
 static void
-update_resource_state(resource_t *rsc, node_t * node, xmlNode * xml_op, const char *task, int rc,
-                      enum action_fail_response *on_fail, pe_working_set_t * data_set) 
+update_resource_state(resource_t * rsc, node_t * node, xmlNode * xml_op, const char * task, int rc,
+                      xmlNode * last_failure, enum action_fail_response * on_fail, pe_working_set_t * data_set)
 {
     gboolean clear_past_failure = FALSE;
 
     CRM_ASSERT(rsc);
+    CRM_ASSERT(xml_op);
+
     if (rc == PCMK_OCF_NOT_RUNNING) {
         clear_past_failure = TRUE;
 
@@ -2763,7 +2770,15 @@ update_resource_state(resource_t *rsc, n
         rsc->role = RSC_ROLE_STOPPED;
 
     } else if (safe_str_eq(task, CRMD_ACTION_STATUS)) {
-        clear_past_failure = TRUE;
+        if (last_failure) {
+            const char *op_key = get_op_key(xml_op);
+            const char *last_failure_key = get_op_key(last_failure);
+
+            if (safe_str_eq(op_key, last_failure_key)) {
+                clear_past_failure = TRUE;
+            }
+        }
+
         if (rsc->role < RSC_ROLE_STARTED) {
             set_active(rsc);
         }
@@ -2792,7 +2807,6 @@ update_resource_state(resource_t *rsc, n
         unpack_rsc_migration(rsc, node, xml_op, data_set);
 
     } else if (rsc->role < RSC_ROLE_STARTED) {
-        /* migrate_to and migrate_from will land here */
         pe_rsc_trace(rsc, "%s active on %s", rsc->id, node->details->uname);
         set_active(rsc);
     }
@@ -2823,7 +2837,7 @@ update_resource_state(resource_t *rsc, n
 }
 
 gboolean
-unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op,
+unpack_rsc_op(resource_t * rsc, node_t * node, xmlNode * xml_op, xmlNode ** last_failure,
               enum action_fail_response * on_fail, pe_working_set_t * data_set)
 {
     int task_id = 0;
@@ -2951,7 +2965,7 @@ unpack_rsc_op(resource_t * rsc, node_t *
 
         case PCMK_LRM_OP_DONE:
             pe_rsc_trace(rsc, "%s/%s completed on %s", rsc->id, task, node->details->uname);
-            update_resource_state(rsc, node, xml_op, task, rc, on_fail, data_set);
+            update_resource_state(rsc, node, xml_op, task, rc, *last_failure, on_fail, data_set);
             break;
 
         case PCMK_LRM_OP_NOT_INSTALLED:
@@ -2964,7 +2978,7 @@ unpack_rsc_op(resource_t * rsc, node_t *
                 *on_fail = action_fail_migrate;
             }
             resource_location(parent, node, -INFINITY, "hard-error", data_set);
-            unpack_rsc_op_failure(rsc, node, rc, xml_op, on_fail, data_set);
+            unpack_rsc_op_failure(rsc, node, rc, xml_op, last_failure, on_fail, data_set);
             break;
 
         case PCMK_LRM_OP_ERROR:
@@ -2981,7 +2995,7 @@ unpack_rsc_op(resource_t * rsc, node_t *
                 crm_warn("Pretending the failure of %s (rc=%d) on %s succeeded",
                          task_key, rc, node->details->uname);
 
-                update_resource_state(rsc, node, xml_op, task, target_rc, on_fail, data_set);
+                update_resource_state(rsc, node, xml_op, task, target_rc, *last_failure, on_fail, data_set);
                 crm_xml_add(xml_op, XML_ATTR_UNAME, node->details->uname);
                 set_bit(rsc->flags, pe_rsc_failure_ignored);
 
@@ -2995,7 +3009,7 @@ unpack_rsc_op(resource_t * rsc, node_t *
                 }
 
             } else {
-                unpack_rsc_op_failure(rsc, node, rc, xml_op, on_fail, data_set);
+                unpack_rsc_op_failure(rsc, node, rc, xml_op, last_failure, on_fail, data_set);
 
                 if(status == PCMK_LRM_OP_ERROR_HARD) {
                     do_crm_log(rc != PCMK_OCF_NOT_INSTALLED?LOG_ERR:LOG_NOTICE,
openSUSE Build Service is sponsored by