commit c52267dfbe67a89136d962a137e0973852b08a77
Author: Gao,Yan <ygao@suse.com>
Date:   Wed Apr 13 12:57:44 2016 +0200

    Fix: fencing: Record the last known names of nodes to make sure fencing requested with nodeid works
    
    dlm_controld invokes dlm_stonith which calls stonith_api_kick_helper()
    to request fencing by nodeid. We need to translate the nodeid into
    the nodename when handling the fencing. Previously if the node had been
    lost, fencing would fail since the peer cache entry had been autoreaped.
    
    This commit fixes it by recording the last known names of the nodes in a
    dedicated hash table. This commit also switches the invocations of
    crm_get_peer() to crm_find_peer() to avoid recreating a node entry in the
    peer cache.

Index: pacemaker/fencing/commands.c
===================================================================
--- pacemaker.orig/fencing/commands.c
+++ pacemaker/fencing/commands.c
@@ -1848,19 +1848,22 @@ stonith_fence(xmlNode * msg)
 
     } else {
         const char *host = crm_element_value(dev, F_STONITH_TARGET);
+        char *nodename = NULL;
 
         if (cmd->options & st_opt_cs_nodeid) {
             int nodeid = crm_atoi(host, NULL);
-            crm_node_t *node = crm_get_peer(nodeid, NULL);
 
-            if (node) {
-                host = node->uname;
+            nodename = stonith_get_peer_name(nodeid);
+            if (nodename) {
+                host = nodename;
             }
         }
 
         /* If we get to here, then self-fencing is implicitly allowed */
         get_capable_devices(host, cmd->action, cmd->default_timeout,
                             TRUE, cmd, stonith_fence_get_devices_cb);
+
+        free(nodename);
     }
 
     return -EINPROGRESS;
Index: pacemaker/fencing/internal.h
===================================================================
--- pacemaker.orig/fencing/internal.h
+++ pacemaker/fencing/internal.h
@@ -191,8 +191,12 @@ schedule_internal_command(const char *or
                           void (*done_cb) (GPid pid, int rc, const char *output,
                                            gpointer user_data));
 
+char *stonith_get_peer_name(unsigned int nodeid);
+
 extern char *stonith_our_uname;
 extern gboolean stand_alone;
 extern GHashTable *device_list;
 extern GHashTable *topology;
 extern long stonith_watchdog_timeout_ms;
+
+extern GHashTable *known_peer_names;
Index: pacemaker/fencing/main.c
===================================================================
--- pacemaker.orig/fencing/main.c
+++ pacemaker/fencing/main.c
@@ -62,6 +62,8 @@ gboolean stonith_shutdown_flag = FALSE;
 qb_ipcs_service_t *ipcs = NULL;
 xmlNode *local_cib = NULL;
 
+GHashTable *known_peer_names = NULL;
+
 static cib_t *cib_api = NULL;
 static void *cib_library = NULL;
 
@@ -1115,6 +1117,10 @@ stonith_cleanup(void)
     if (ipcs) {
         qb_ipcs_destroy(ipcs);
     }
+
+    g_hash_table_destroy(known_peer_names);
+    known_peer_names = NULL;
+
     crm_peer_destroy();
     crm_client_cleanup();
     free(stonith_our_uname);
@@ -1192,6 +1198,10 @@ st_peer_update_callback(enum crm_status_
         return;
     }
 
+    if (node->id && node->uname) {
+        g_hash_table_insert(known_peer_names, GUINT_TO_POINTER(node->id), strdup(node->uname));
+    }
+
     /*
      * This is a hack until we can send to a nodeid and/or we fix node name lookups
      * These messages are ignored in stonith_peer_callback()
@@ -1375,6 +1385,7 @@ main(int argc, char **argv)
     mainloop_add_signal(SIGTERM, stonith_shutdown);
 
     crm_peer_init();
+    known_peer_names = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, free);
 
     if (stand_alone == FALSE) {
 #if SUPPORT_HEARTBEAT
Index: pacemaker/fencing/remote.c
===================================================================
--- pacemaker.orig/fencing/remote.c
+++ pacemaker/fencing/remote.c
@@ -604,6 +604,30 @@ stonith_manual_ack(xmlNode * msg, remote
     return -EINPROGRESS;
 }
 
+char *
+stonith_get_peer_name(unsigned int nodeid)
+{
+    crm_node_t *node = crm_find_peer(nodeid, NULL);
+    char *nodename = NULL;
+
+    if (node && node->uname) {
+        return strdup(node->uname);
+
+    } else if ((nodename = get_node_name(nodeid))) {
+        return nodename;
+
+    } else {
+        const char *last_known_name = g_hash_table_lookup(known_peer_names, GUINT_TO_POINTER(nodeid));
+
+        if (last_known_name) {
+            crm_debug("Use the last known name %s for nodeid %u", last_known_name, nodeid);
+            return strdup(last_known_name);
+        }
+    }
+
+    return NULL;
+}
+
 /*!
  * \internal
  * \brief Create a new remote stonith op
@@ -685,16 +709,17 @@ create_remote_stonith_op(const char *cli
 
     if (op->call_options & st_opt_cs_nodeid) {
         int nodeid = crm_atoi(op->target, NULL);
-        crm_node_t *node = crm_get_peer(nodeid, NULL);
+        char *nodename = stonith_get_peer_name(nodeid);
 
         /* Ensure the conversion only happens once */
         op->call_options &= ~st_opt_cs_nodeid;
 
-        if (node && node->uname) {
+        if (nodename) {
             free(op->target);
-            op->target = strdup(node->uname);
+            op->target = nodename;
+
         } else {
-            crm_warn("Could not expand nodeid '%s' into a host name (%p)", op->target, node);
+            crm_warn("Could not expand nodeid '%s' into a host name", op->target);
         }
     }
 
@@ -1482,6 +1507,7 @@ stonith_fence_history(xmlNode * msg, xml
     int rc = 0;
     const char *target = NULL;
     xmlNode *dev = get_xpath_object("//@" F_STONITH_TARGET, msg, LOG_TRACE);
+    char *nodename = NULL;
 
     if (dev) {
         int options = 0;
@@ -1490,10 +1516,10 @@ stonith_fence_history(xmlNode * msg, xml
         crm_element_value_int(msg, F_STONITH_CALLOPTS, &options);
         if (target && (options & st_opt_cs_nodeid)) {
             int nodeid = crm_atoi(target, NULL);
-            crm_node_t *node = crm_get_peer(nodeid, NULL);
 
-            if (node) {
-                target = node->uname;
+            nodename = stonith_get_peer_name(nodeid);
+            if (nodename) {
+                target = nodename;
             }
         }
     }
@@ -1526,6 +1552,7 @@ stonith_fence_history(xmlNode * msg, xml
         }
     }
 
+    free(nodename);
     return rc;
 }
 
