commit aa00c73849444f1c6d194fce574c54036c2f6d34
Author: Kazunori INOUE <inouekazu@intellilink.co.jp>
Date:   Mon Oct 30 18:14:38 2017 +0900

    Low: tools: set meta_timeout env when crm_resource --force-* executes RA (2)

Index: pacemaker/include/crm/pengine/internal.h
===================================================================
--- pacemaker.orig/include/crm/pengine/internal.h
+++ pacemaker/include/crm/pengine/internal.h
@@ -211,6 +211,9 @@ extern action_t *custom_action(resource_
 		rsc, demoted_key(rsc), CRMD_ACTION_DEMOTED, node,	\
 		optional, TRUE, data_set)
 
+extern int pe_get_configured_timeout(resource_t *rsc, const char *action,
+                                     pe_working_set_t *data_set);
+
 extern action_t *find_first_action(GListPtr input, const char *uuid, const char *task,
                                    node_t * on_node);
 extern enum action_tasks get_complex_task(resource_t * rsc, const char *name,
Index: pacemaker/lib/pengine/utils.c
===================================================================
--- pacemaker.orig/lib/pengine/utils.c
+++ pacemaker/lib/pengine/utils.c
@@ -576,6 +576,44 @@ custom_action(resource_t * rsc, char *ke
     return action;
 }
 
+int
+pe_get_configured_timeout(resource_t *rsc, const char *action, pe_working_set_t *data_set)
+{
+    xmlNode *child = NULL;
+    const char *timeout = NULL;
+    int timeout_ms = 0;
+
+    for (child = first_named_child(rsc->ops_xml, XML_ATTR_OP);
+         child != NULL; child = __xml_next(child)) {
+        if (safe_str_eq(action, crm_element_value(child, XML_NVPAIR_ATTR_NAME))) {
+            timeout = crm_element_value(child, XML_ATTR_TIMEOUT);
+            break;
+        }
+    }
+
+    if (timeout == NULL && data_set->op_defaults) {
+        GHashTable *action_meta = g_hash_table_new_full(crm_str_hash, g_str_equal, free, free);
+        unpack_instance_attributes(data_set->input, data_set->op_defaults, XML_TAG_META_SETS,
+                                   NULL, action_meta, NULL, FALSE, data_set->now);
+        timeout = g_hash_table_lookup(action_meta, XML_ATTR_TIMEOUT);
+    }
+
+    if (timeout == NULL && data_set->config_hash) {
+        timeout = pe_pref(data_set->config_hash, "default-action-timeout");
+    }
+
+    if (timeout == NULL) {
+        timeout = "20s";
+    }
+
+    timeout_ms = crm_get_msec(timeout);
+    if (timeout_ms < 0) {
+        timeout_ms = 0;
+    }
+
+    return timeout_ms;
+}
+
 static const char *
 unpack_operation_on_fail(action_t * action)
 {
Index: pacemaker/tools/crm_resource.c
===================================================================
--- pacemaker.orig/tools/crm_resource.c
+++ pacemaker/tools/crm_resource.c
@@ -338,7 +338,7 @@ static struct crm_option long_options[]
     },
     {
         "timeout", required_argument, NULL, 'T',
-        "\t(Advanced) Abort if command does not finish in this time (with --restart, --wait)"
+        "\t(Advanced) Abort if command does not finish in this time (with --restart, --wait, --force-*)"
     },
     {
         "force", no_argument, NULL, 'f',
@@ -823,7 +823,8 @@ main(int argc, char **argv)
         rc = wait_till_stable(timeout_ms, cib_conn);
 
     } else if (rsc_cmd == 0 && rsc_long_cmd) { /* force-(stop|start|check) */
-        rc = cli_resource_execute(rsc_id, rsc_long_cmd, override_params, cib_conn, &data_set);
+        rc = cli_resource_execute(rsc_id, rsc_long_cmd, override_params,
+                                  timeout_ms, cib_conn, &data_set);
         if (rc >= 0) {
             is_ocf_rc = 1;
         }
Index: pacemaker/tools/crm_resource.h
===================================================================
--- pacemaker.orig/tools/crm_resource.h
+++ pacemaker/tools/crm_resource.h
@@ -74,7 +74,8 @@ int cli_resource_search(const char *rsc,
 int cli_resource_delete(cib_t *cib_conn, crm_ipc_t * crmd_channel, const char *host_uname, resource_t * rsc, pe_working_set_t * data_set);
 int cli_resource_restart(resource_t * rsc, const char *host, int timeout_ms, cib_t * cib);
 int cli_resource_move(const char *rsc_id, const char *host_name, cib_t * cib, pe_working_set_t *data_set);
-int cli_resource_execute(const char *rsc_id, const char *rsc_action, GHashTable *override_hash, cib_t * cib, pe_working_set_t *data_set);
+int cli_resource_execute(const char *rsc_id, const char *rsc_action, GHashTable *override_hash,
+                         int timeout_ms, cib_t * cib, pe_working_set_t *data_set);
 
 int cli_resource_update_attribute(const char *rsc_id, const char *attr_set, const char *attr_id,
                                   const char *attr_name, const char *attr_value, bool recursive,
Index: pacemaker/tools/crm_resource_runtime.c
===================================================================
--- pacemaker.orig/tools/crm_resource_runtime.c
+++ pacemaker/tools/crm_resource_runtime.c
@@ -1450,7 +1450,8 @@ wait_till_stable(int timeout_ms, cib_t *
 }
 
 int
-cli_resource_execute(const char *rsc_id, const char *rsc_action, GHashTable *override_hash, cib_t * cib, pe_working_set_t *data_set)
+cli_resource_execute(const char *rsc_id, const char *rsc_action, GHashTable *override_hash,
+                     int timeout_ms, cib_t * cib, pe_working_set_t *data_set)
 {
     int rc = pcmk_ok;
     svc_action_t *op = NULL;
@@ -1461,10 +1462,6 @@ cli_resource_execute(const char *rsc_id,
     GHashTable *params = NULL;
     resource_t *rsc = pe_find_resource(data_set->resources, rsc_id);
 
-    xmlNode *child = NULL;
-    const char *timeout = NULL;
-    long timeout_ms = 0;
-
     if (rsc == NULL) {
         CMD_ERR("Must supply a resource id with -r");
         return -ENXIO;
@@ -1513,42 +1510,22 @@ cli_resource_execute(const char *rsc_id,
     params = generate_resource_params(rsc, data_set);
 
     /* add meta_timeout env needed by some resource agents */
-    child = first_named_child(rsc->xml, "operations");
-    for (child = first_named_child(child, XML_ATTR_OP);
-         child != NULL; child = crm_next_same_xml(child)) {
-        if (safe_str_eq(action, crm_element_value(child, XML_NVPAIR_ATTR_NAME))) {
-            timeout = crm_element_value(child, XML_ATTR_TIMEOUT);
-            break;
-        }
-    }
-    if (timeout == NULL && data_set->op_defaults) {
-        GHashTable *action_meta = crm_str_table_new();
-        unpack_instance_attributes(data_set->input, data_set->op_defaults, XML_TAG_META_SETS,
-                                   NULL, action_meta, NULL, FALSE, data_set->now);
-        timeout = g_hash_table_lookup(action_meta, XML_ATTR_TIMEOUT);
-    }
-    if (timeout == NULL && data_set->config_hash) {
-        timeout = pe_pref(data_set->config_hash, "default-action-timeout");
-    }
-    if (timeout == NULL) {
-        timeout = CRM_DEFAULT_OP_TIMEOUT_S;
-    }
-    timeout_ms = crm_get_msec(timeout);
-    if (timeout_ms < 0) {
-        timeout_ms = 0;
+    if (timeout_ms == 0) {
+        timeout_ms = pe_get_configured_timeout(rsc, action, data_set);
     }
     g_hash_table_insert(params, strdup("CRM_meta_timeout"),
-                        crm_strdup_printf("%ld", timeout_ms));
+                        crm_strdup_printf("%d", timeout_ms));
 
     /* add crm_feature_set env needed by some resource agents */
     g_hash_table_insert(params, strdup(XML_ATTR_CRM_VERSION), strdup(CRM_FEATURE_SET));
 
-    op = resources_action_create(rsc->id, rclass, rprov, rtype, action, 0, -1, params, 0);
+    op = resources_action_create(rsc->id, rclass, rprov, rtype, action, 0,
+                                 timeout_ms, params, 0);
     if (op == NULL) {
         /* Re-run with stderr enabled so we can display a sane error message */
         crm_enable_stderr(TRUE);
         op = resources_action_create(rsc->id, rclass, rprov, rtype, action, 0,
-                                     -1, params, 0);
+                                     timeout_ms, params, 0);
 
         /* We know op will be NULL, but this makes static analysis happy */
         services_action_free(op);
