commit 8a1bf27335790d121baefad9c1b3da10caa4c098
Author: Ken Gaillot <kgaillot@redhat.com>
Date:   Thu May 10 15:33:29 2018 -0500

    Log: tools: improve error messages from crm_resource --move
    
    Previously, errors would typically result in two messages, at least one of
    which was completely misleading. Now, some new pcmk_err_* codes are added
    for richer return values, so that a single message can be printed.
    
    This conveniently avoids a portability issue where ENXIO is described as
    "No such device or address" on Linux and "Device not configured" on *BSD,
    generating different regression test output.

diff --git a/cts/cli/regression.tools.exp b/cts/cli/regression.tools.exp
index d3629b0c1..f8c7773c7 100644
--- a/cts/cli/regression.tools.exp
+++ b/cts/cli/regression.tools.exp
@@ -995,8 +995,7 @@ Error performing operation: Invalid argument
 =#=#=#= End test: Require a destination when migrating a resource that is stopped - Incorrect usage (64) =#=#=#=
 * Passed: crm_resource   - Require a destination when migrating a resource that is stopped
 =#=#=#= Begin test: Don't support migration to non-existent locations =#=#=#=
-Error performing operation: node 'i.dont.exist' is unknown
-Error performing operation: No such device or address
+Error performing operation: Node not found
 =#=#=#= Current cib after: Don't support migration to non-existent locations =#=#=#=
 <cib epoch="17" num_updates="0" admin_epoch="1">
   <configuration>
@@ -1149,8 +1148,7 @@ Online: [ node1 ]
 =#=#=#= End test: Bring resources online - OK (0) =#=#=#=
 * Passed: crm_simulate   - Bring resources online
 =#=#=#= Begin test: Try to move a resource to its existing location =#=#=#=
-Error performing operation: dummy is already active on node1
-Error performing operation: File exists
+Error performing operation: Situation already as requested
 =#=#=#= Current cib after: Try to move a resource to its existing location =#=#=#=
 <cib epoch="18" num_updates="4" admin_epoch="1">
   <configuration>
@@ -1731,8 +1729,7 @@ true
 =#=#=#= End test: Delete ticket standby state - OK (0) =#=#=#=
 * Passed: crm_ticket     - Delete ticket standby state
 =#=#=#= Begin test: Ban a resource on unknown node =#=#=#=
-Error performing operation: node 'host1' is unknown
-Error performing operation: No such device or address
+Error performing operation: Node not found
 =#=#=#= Current cib after: Ban a resource on unknown node =#=#=#=
 <cib epoch="20" num_updates="5" admin_epoch="1">
   <configuration>
diff --git a/include/crm/common/results.h b/include/crm/common/results.h
index 5569d348a..b6a586bee 100644
--- a/include/crm/common/results.h
+++ b/include/crm/common/results.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2018 Andrew Beekhof <andrew@beekhof.net>
+ * Copyright 2012-2018 Andrew Beekhof <andrew@beekhof.net>
  *
  * This source code is licensed under the GNU Lesser General Public License
  * version 2.1 or later (LGPLv2.1+) WITHOUT ANY WARRANTY.
@@ -47,6 +47,9 @@ extern "C" {
 #  define pcmk_err_cib_save             210
 #  define pcmk_err_schema_unchanged     211
 #  define pcmk_err_cib_corrupt          212
+#  define pcmk_err_multiple             213
+#  define pcmk_err_node_unknown         214
+#  define pcmk_err_already              215
 
 /*
  * Exit status codes
diff --git a/lib/common/results.c b/lib/common/results.c
index 75f7c428b..1a77d15e9 100644
--- a/lib/common/results.c
+++ b/lib/common/results.c
@@ -173,6 +173,9 @@ pcmk_errorname(int rc)
         case pcmk_err_cib_backup: return "pcmk_err_cib_backup";
         case pcmk_err_cib_save: return "pcmk_err_cib_save";
         case pcmk_err_cib_corrupt: return "pcmk_err_cib_corrupt";
+        case pcmk_err_multiple: return "pcmk_err_multiple";
+        case pcmk_err_node_unknown: return "pcmk_err_node_unknown";
+        case pcmk_err_already: return "pcmk_err_already";
     }
     return "Unknown";
 }
@@ -211,7 +214,12 @@ pcmk_strerror(int rc)
             return "Could not save the new configuration to disk";
         case pcmk_err_cib_corrupt:
             return "Could not parse on-disk configuration";
-
+        case pcmk_err_multiple:
+            return "Resource active on multiple nodes";
+        case pcmk_err_node_unknown:
+            return "Node not found";
+        case pcmk_err_already:
+            return "Situation already as requested";
         case pcmk_err_schema_unchanged:
             return "Schema is already the latest available";
 
@@ -387,6 +395,7 @@ crm_errno2exit(int rc)
             return CRM_EX_DISCONNECT;
 
         case EEXIST:
+        case pcmk_err_already:
             return CRM_EX_EXISTS;
 
         case EIO:
@@ -396,9 +405,11 @@ crm_errno2exit(int rc)
             return CRM_EX_UNIMPLEMENT_FEATURE;
 
         case ENOTUNIQ:
+        case pcmk_err_multiple:
             return CRM_EX_MULTIPLE;
 
         case ENXIO:
+        case pcmk_err_node_unknown:
             return CRM_EX_NOSUCH;
 
         case ETIME:
diff --git a/tools/crm_resource.c b/tools/crm_resource.c
index 9818692b3..25e05980d 100644
--- a/tools/crm_resource.c
+++ b/tools/crm_resource.c
@@ -939,8 +939,7 @@ main(int argc, char **argv)
         if (host_uname) {
             dest = pe_find_node(data_set.nodes, host_uname);
             if (dest == NULL) {
-                CMD_ERR("Unknown node: %s", host_uname);
-                rc = -ENXIO;
+                rc = -pcmk_err_node_unknown;
                 goto bail;
             }
         }
@@ -953,8 +952,7 @@ main(int argc, char **argv)
         if (host_uname) {
             dest = pe_find_node(data_set.nodes, host_uname);
             if (dest == NULL) {
-                CMD_ERR("Unknown node: %s", host_uname);
-                rc = -ENXIO;
+                rc = -pcmk_err_node_unknown;
                 goto bail;
             }
             rc = cli_resource_clear(rsc_id, dest->details->uname, NULL, cib_conn);
@@ -970,8 +968,7 @@ main(int argc, char **argv)
         node_t *dest = pe_find_node(data_set.nodes, host_uname);
 
         if (dest == NULL) {
-            CMD_ERR("Error performing operation: node '%s' is unknown", host_uname);
-            rc = -ENXIO;
+            rc = -pcmk_err_node_unknown;
             goto bail;
         }
         rc = cli_resource_ban(rsc_id, dest->details->uname, NULL, cib_conn);
diff --git a/tools/crm_resource_runtime.c b/tools/crm_resource_runtime.c
index 61430c3d8..297b6f055 100644
--- a/tools/crm_resource_runtime.c
+++ b/tools/crm_resource_runtime.c
@@ -1826,13 +1826,11 @@ cli_resource_move(resource_t *rsc, const char *rsc_id, const char *host_name,
         count = g_list_length(rsc->running_on);
 
     } else if (g_list_length(rsc->running_on) > 1) {
-        CMD_ERR("Resource '%s' not moved: active on multiple nodes", rsc_id);
-        return -ENOTUNIQ;
+        return -pcmk_err_multiple;
     }
 
     if(dest == NULL) {
-        CMD_ERR("Error performing operation: node '%s' is unknown", host_name);
-        return -ENXIO;
+        return -pcmk_err_node_unknown;
     }
 
     if(g_list_length(rsc->running_on) == 1) {
@@ -1850,9 +1848,7 @@ cli_resource_move(resource_t *rsc, const char *rsc_id, const char *host_name,
             crm_info("%s is already %s on %s, reinforcing placement with location constraint.",
                      rsc_id, scope_master?"promoted":"active", dest->details->uname);
         } else {
-            CMD_ERR("Error performing operation: %s is already %s on %s",
-                    rsc_id, scope_master?"promoted":"active", dest->details->uname);
-            return -EEXIST;
+            return -pcmk_err_already;
         }
     }
 
