commit 6424a647dd160d7a0c8e13a0908297df1a5b2c6f
Author: Andrew Beekhof <andrew@beekhof.net>
Date:   Thu Feb 11 12:32:29 2016 +1100

    Feature: Allow cluster and remote LRM API versions to diverge
    
    Requiring the same version is not realistic.
    
    Common examples will be rolling upgrades (where typically you'd upgrade
    the cluster first) and guest introspection (where you may never upgrade
    the guest software).
    
    Normally you want the "server" to be the higher, however the
    client/sever roles are turned on their head here since the cluster is
    acting as the "client" connecting to pacemaker remote "server".
    
    However we generally want pacemaker-remote to be as dumb as possible
    which is consistent with how we'd do upgrades. So for this reason we
    require that the remote node's API version be less-than or equal to that
    of the cluster.

Index: pacemaker/lib/lrmd/lrmd_client.c
===================================================================
--- pacemaker.orig/lib/lrmd/lrmd_client.c
+++ pacemaker/lib/lrmd/lrmd_client.c
@@ -109,6 +109,7 @@ typedef struct lrmd_private_s {
     /* Internal IPC proxy msg passing for remote guests */
     void (*proxy_callback)(lrmd_t *lrmd, void *userdata, xmlNode *msg);
     void *proxy_callback_userdata;
+    char *peer_version;
 } lrmd_private_t;
 
 static lrmd_list_t *
@@ -907,6 +908,7 @@ lrmd_handshake(lrmd_t * lrmd, const char
         crm_err("Did not receive registration reply");
         rc = -EPROTO;
     } else {
+        const char *version = crm_element_value(reply, F_LRMD_PROTOCOL_VERSION);
         const char *msg_type = crm_element_value(reply, F_LRMD_OPERATION);
         const char *tmp_ticket = crm_element_value(reply, F_LRMD_CLIENTID);
 
@@ -914,7 +916,7 @@ lrmd_handshake(lrmd_t * lrmd, const char
 
         if (rc == -EPROTO) {
             crm_err("LRMD protocol mismatch client version %s, server version %s",
-                LRMD_PROTOCOL_VERSION, crm_element_value(reply, F_LRMD_PROTOCOL_VERSION));
+                LRMD_PROTOCOL_VERSION, version);
             crm_log_xml_err(reply, "Protocol Error");
 
         } else if (safe_str_neq(msg_type, CRM_OP_REGISTER)) {
@@ -928,6 +930,7 @@ lrmd_handshake(lrmd_t * lrmd, const char
         } else {
             crm_trace("Obtained registration token: %s", tmp_ticket);
             native->token = strdup(tmp_ticket);
+            native->peer_version = strdup(version?version:"1.0"); /* Included since 1.1 */
             rc = pcmk_ok;
         }
     }
Index: pacemaker/lrmd/lrmd.c
===================================================================
--- pacemaker.orig/lrmd/lrmd.c
+++ pacemaker/lrmd/lrmd.c
@@ -1382,13 +1382,16 @@ process_lrmd_signon(crm_client_t * clien
     const char *is_ipc_provider = crm_element_value(request, F_LRMD_IS_IPC_PROVIDER);
     const char *protocol_version = crm_element_value(request, F_LRMD_PROTOCOL_VERSION);
 
-    if (safe_str_neq(protocol_version, LRMD_PROTOCOL_VERSION)) {
+    if (compare_version(protocol_version, LRMD_PROTOCOL_VERSION) < 0) {
+        crm_err("Cluster API version must be greater than or equal to %s, not %s",
+                LRMD_PROTOCOL_VERSION, protocol_version);
         crm_xml_add_int(reply, F_LRMD_RC, -EPROTO);
         crm_xml_add(reply, F_LRMD_PROTOCOL_VERSION, LRMD_PROTOCOL_VERSION);
     }
 
     crm_xml_add(reply, F_LRMD_OPERATION, CRM_OP_REGISTER);
     crm_xml_add(reply, F_LRMD_CLIENTID, client->id);
+    crm_xml_add(reply, F_LRMD_PROTOCOL_VERSION, LRMD_PROTOCOL_VERSION);
     lrmd_server_send_reply(client, id, reply);
 
     if (crm_is_true(is_ipc_provider)) {
@@ -1685,6 +1688,7 @@ process_lrmd_message(crm_client_t * clie
     } else if (crm_str_eq(op, LRMD_OP_POKE, TRUE)) {
         do_notify = 1;
         do_reply = 1;
+    } else if (crm_str_eq(op, LRMD_OP_CHECK, TRUE)) {
     } else {
         rc = -EOPNOTSUPP;
         do_reply = 1;
Index: pacemaker/include/crm/lrmd.h
===================================================================
--- pacemaker.orig/include/crm/lrmd.h
+++ pacemaker/include/crm/lrmd.h
@@ -89,6 +89,7 @@ typedef struct lrmd_key_value_s {
 #define LRMD_OP_RSC_METADATA      "lrmd_rsc_metadata"
 #define LRMD_OP_POKE              "lrmd_rsc_poke"
 #define LRMD_OP_NEW_CLIENT        "lrmd_rsc_new_client"
+#define LRMD_OP_CHECK             "lrmd_check"
 
 #define LRMD_IPC_OP_NEW           "new"
 #define LRMD_IPC_OP_DESTROY       "destroy"
