update the client side of getnodemap and getpublicips controls to
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Tue, 14 Oct 2008 13:24:44 +0000 (00:24 +1100)
committerRonnie Sahlberg <ronniesahlberg@gmail.com>
Tue, 14 Oct 2008 13:24:44 +0000 (00:24 +1100)
fallback to the old-style ipv4-only controls if the new-style ipv4/ipv6
control fails.

this allows a 1.0.59+ (ipv4/ipv6) ctdb daemon being recmaster  to be
compatible with
pre-1.0.59  versions of ctdb that are ipv4 only.

client/ctdb_client.c
include/ctdb.h

index a4d2a2bbaf776dfc08bdaa0787bd93a821c88217..401830002bac03a7f838ed79051c88cda02b2501 100644 (file)
@@ -1221,7 +1221,7 @@ int ctdb_ctrl_getdbmap(struct ctdb_context *ctdb, struct timeval timeout, uint32
                           CTDB_CONTROL_GET_DBMAP, 0, tdb_null, 
                           mem_ctx, &outdata, &res, &timeout, NULL);
        if (ret != 0 || res != 0) {
-               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getdbmap failed\n"));
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getdbmap failed ret:%d res:%d\n", ret, res));
                return -1;
        }
 
@@ -1245,8 +1245,12 @@ int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
        ret = ctdb_control(ctdb, destnode, 0, 
                           CTDB_CONTROL_GET_NODEMAP, 0, tdb_null, 
                           mem_ctx, &outdata, &res, &timeout, NULL);
+       if (ret == 0 && res == -1 && outdata.dsize == 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed, falling back to ipv4-only control\n"));
+               return ctdb_ctrl_getnodemapv4(ctdb, timeout, destnode, mem_ctx, nodemap);
+       }
        if (ret != 0 || res != 0 || outdata.dsize == 0) {
-               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed\n"));
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed ret:%d res:%d\n", ret, res));
                return -1;
        }
 
@@ -1256,6 +1260,45 @@ int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
        return 0;
 }
 
+/*
+  old style ipv4-only get a list of nodes (vnn and flags ) from a remote node
+ */
+int ctdb_ctrl_getnodemapv4(struct ctdb_context *ctdb, 
+               struct timeval timeout, uint32_t destnode, 
+               TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
+{
+       int ret, i, len;
+       TDB_DATA outdata;
+       struct ctdb_node_mapv4 *nodemapv4;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_NODEMAPv4, 0, tdb_null, 
+                          mem_ctx, &outdata, &res, &timeout, NULL);
+       if (ret != 0 || res != 0 || outdata.dsize == 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodesv4 failed ret:%d res:%d\n", ret, res));
+               return -1;
+       }
+
+       nodemapv4 = (struct ctdb_node_mapv4 *)outdata.dptr;
+
+       len = offsetof(struct ctdb_node_map, nodes) + nodemapv4->num*sizeof(struct ctdb_node_and_flags);
+       (*nodemap) = talloc_zero_size(mem_ctx, len);
+       CTDB_NO_MEMORY(ctdb, (*nodemap));
+
+       (*nodemap)->num = nodemapv4->num;
+       for (i=0; i<nodemapv4->num; i++) {
+               (*nodemap)->nodes[i].pnn     = nodemapv4->nodes[i].pnn;
+               (*nodemap)->nodes[i].flags   = nodemapv4->nodes[i].flags;
+               (*nodemap)->nodes[i].addr.ip = nodemapv4->nodes[i].sin;
+               (*nodemap)->nodes[i].addr.sa.sa_family = AF_INET;
+       }
+               
+       talloc_free(outdata.dptr);
+                   
+       return 0;
+}
+
 /*
   drop the transport, reload the nodes file and restart the transport
  */
@@ -2254,8 +2297,12 @@ int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
        ret = ctdb_control(ctdb, destnode, 0, 
                           CTDB_CONTROL_GET_PUBLIC_IPS, 0, tdb_null, 
                           mem_ctx, &outdata, &res, &timeout, NULL);
+       if (ret == 0 && res == -1) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control to get public ips failed, falling back to ipv4-only version\n"));
+               return ctdb_ctrl_get_public_ipsv4(ctdb, timeout, destnode, mem_ctx, ips);
+       }
        if (ret != 0 || res != 0) {
-               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed\n"));
+         DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed ret:%d res:%d\n", ret, res));
                return -1;
        }
 
@@ -2286,6 +2333,7 @@ int ctdb_ctrl_get_public_ipsv4(struct ctdb_context *ctdb,
        len = offsetof(struct ctdb_all_public_ips, ips) +
                ipsv4->num*sizeof(struct ctdb_public_ip);
        *ips = talloc_zero_size(mem_ctx, len);
+       (*ips)->num = ipsv4->num;
        for (i=0; i<ipsv4->num; i++) {
                (*ips)->ips[i].pnn     = ipsv4->ips[i].pnn;
                (*ips)->ips[i].addr.ip = ipsv4->ips[i].sin;
index 60fa60be589eed34cf55ff10727d1eee8ef83373..fd5af20b9621f7ec8e77108367ef49ef0dc06a27 100644 (file)
@@ -303,6 +303,10 @@ int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb,
                    struct timeval timeout, uint32_t destnode, 
                    TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap);
 
+int ctdb_ctrl_getnodemapv4(struct ctdb_context *ctdb, 
+                   struct timeval timeout, uint32_t destnode, 
+                   TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap);
+
 int ctdb_ctrl_reload_nodes_file(struct ctdb_context *ctdb, 
                    struct timeval timeout, uint32_t destnode);