update how the NATGW configuration works.
authorRonnie Sahlberg <ronniesahlberg@gmail.com>
Wed, 25 Mar 2009 02:37:57 +0000 (13:37 +1100)
committerRonnie Sahlberg <ronniesahlberg@gmail.com>
Wed, 25 Mar 2009 02:37:57 +0000 (13:37 +1100)
allow the cluster to be partitioned into multiple disjoint natgw subsets

config/ctdb.sysconfig
config/events.d/11.natgw
tools/ctdb.c

index c3b5f16b1473d505a56f4f9525317dfa45a21176..ef3b0dc3e0397ac1f4054b2d6721d2629cbbd893 100644 (file)
 # and thus no proper routes to the external world it will instead
 # route all packets through the nat-gw node.
 #
+# NATGW_NODES is the list of nodes that belong to this natgw group.
+# You can have multiple natgw groups in one cluster but each node
+# can only belong to one single natgw group.
+#
 # NATGW_PUBLIC_IP=10.0.0.227/24
 # NATGW_PUBLIC_IFACE=eth0
 # NATGW_DEFAULT_GATEWAY=10.0.0.1
 # NATGW_PRIVATE_IFACE=eth1
 # NATGW_PRIVATE_NETWORK=10.1.1.0/24
+# NATGW_NODES=/etc/ctdb/natgw_nodes
 
 # where to log messages
 # the default is /var/log/log.ctdb
index 254a8c1e87bd5212c8f67afe5bc9ff41657c3e5f..2d256ba81c173974767554d2c637f56073406945 100644 (file)
@@ -29,16 +29,14 @@ delete_all() {
 case $cmd in 
      recovered)
        MYPNN=`ctdb pnn | cut -d: -f2`
+       NATGWMASTER=`ctdb natgwlist | head -1`
+       NATGWIP=`ctdb natgwlist | tail --lines=+2 | head -1 | cut -d: -f3`
 
-       # Find the first connected node
-       FIRST=`ctdb status -Y | grep ":0:$" | head -1`
-       FIRSTNODE=`echo $FIRST | cut -d: -f2`
-       FIRSTIP=`echo $FIRST | cut -d: -f3`
        NATGW_PUBLIC_IP_HOST=`echo $NATGW_PUBLIC_IP | sed -e "s/\/.*/\/32/"`
 
        delete_all
 
-       if [ "$FIRSTNODE" == "$MYPNN" ]; then
+       if [ "$MYPNN" == "$NATGWMASTER" ]; then
                # This is the first node, set it up as the NAT GW
                echo 1 >/proc/sys/net/ipv4/ip_forward
                iptables -A POSTROUTING -t nat -s $NATGW_PRIVATE_NETWORK -d ! $NATGW_PRIVATE_NETWORK -j MASQUERADE
@@ -51,14 +49,12 @@ case $cmd in
                # We do this so that the ip address will exist on a
                # non-loopback interface so that samba may send it along in the
                # KDC requests.
-
-               # Set the scope up as host and make sure we dont respond to ARP
-               # for this ip
-               echo 3 > /proc/sys/net/ipv4/conf/all/arp_ignore
-               ip addr add $NATGW_PUBLIC_IP_HOST dev $NATGW_PRIVATE_IFACE scope host
-               
-               ip route add 0.0.0.0/0 via $FIRSTIP metric 10
+               ip addr add $NATGW_PUBLIC_IP_HOST dev $NATGW_PRIVATE_IFACE
+               ip route add 0.0.0.0/0 via $NATGWIP metric 10
        fi
+
+       # flush our route cache
+       echo 1 > /proc/sys/net/ipv4/route/flush
        ;;
 
      shutdown)
index 8fcf95bdac29920569f85a9297a023ba992c7f4b..1f17059f52598d2d10d24a4bee122405e3f97c6b 100644 (file)
@@ -472,6 +472,111 @@ static int control_status(struct ctdb_context *ctdb, int argc, const char **argv
 }
 
 
+struct natgw_node {
+       struct natgw_node *next;
+       const char *addr;
+};
+
+/*
+  display the list of nodes belonging to this natgw configuration
+ */
+static int control_natgwlist(struct ctdb_context *ctdb, int argc, const char **argv)
+{
+       int i, ret;
+       const char *natgw_list;
+       int nlines;
+       char **lines;
+       struct natgw_node *natgw_nodes = NULL;
+       struct natgw_node *natgw_node;
+       struct ctdb_node_map *nodemap=NULL;
+
+
+       /* read the natgw nodes file into a linked list */
+       natgw_list = getenv("NATGW_NODES");
+       if (natgw_list == NULL) {
+               natgw_list = "/etc/ctdb/natgw_nodes";
+       }
+       lines = file_lines_load(natgw_list, &nlines, ctdb);
+       if (lines == NULL) {
+               ctdb_set_error(ctdb, "Failed to load natgw node list '%s'\n", natgw_list);
+               return -1;
+       }
+       while (nlines > 0 && strcmp(lines[nlines-1], "") == 0) {
+               nlines--;
+       }
+       for (i=0;i<nlines;i++) {
+               char *node;
+
+               node = lines[i];
+               /* strip leading spaces */
+               while((*node == ' ') || (*node == '\t')) {
+                       node++;
+               }
+               if (*node == '#') {
+                       continue;
+               }
+               if (strcmp(node, "") == 0) {
+                       continue;
+               }
+               natgw_node = talloc(ctdb, struct natgw_node);
+               natgw_node->addr = talloc_strdup(natgw_node, node);
+               natgw_node->next = natgw_nodes;
+               natgw_nodes = natgw_node;
+       }
+
+       ret = ctdb_ctrl_getnodemap(ctdb, TIMELIMIT(), CTDB_CURRENT_NODE, ctdb, &nodemap);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR, ("Unable to get nodemap from local node.\n"));
+               return ret;
+       }
+
+       i=0;
+       while(i<nodemap->num) {
+               for(natgw_node=natgw_nodes;natgw_node;natgw_node=natgw_node->next) {
+                       if (!strcmp(natgw_node->addr, ctdb_addr_to_str(&nodemap->nodes[i].addr))) {
+                               break;
+                       }
+               }
+
+               /* this node was not in the natgw so we just remove it from
+                * the list
+                */
+               if ((natgw_node == NULL) 
+               ||  (nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED) ) {
+                       int j;
+
+                       for (j=i+1; j<nodemap->num; j++) {
+                               nodemap->nodes[j-1] = nodemap->nodes[j];
+                       }
+                       nodemap->num--;
+                       continue;
+               }
+
+               i++;
+       }               
+
+       /* print the natgw master */
+       for(i=0;i<nodemap->num;i++){
+               if (!(nodemap->nodes[i].flags & NODE_FLAGS_DISCONNECTED)) {
+                       printf("%d\n", nodemap->nodes[i].pnn);
+                       break;
+               }
+       }
+
+       /* print the pruned list of nodes belonging to this natgw list */
+       for(i=0;i<nodemap->num;i++){
+               printf(":%d:%s:%d:%d:%d:%d:\n", nodemap->nodes[i].pnn,
+                       ctdb_addr_to_str(&nodemap->nodes[i].addr),
+                      !!(nodemap->nodes[i].flags&NODE_FLAGS_DISCONNECTED),
+                      !!(nodemap->nodes[i].flags&NODE_FLAGS_BANNED),
+                      !!(nodemap->nodes[i].flags&NODE_FLAGS_PERMANENTLY_DISABLED),
+                      !!(nodemap->nodes[i].flags&NODE_FLAGS_UNHEALTHY));
+       }
+
+       return 0;
+}
+
+
 /*
   display the status of the monitoring scripts
  */
@@ -2686,6 +2791,7 @@ static const struct {
        { "recmaster",        control_recmaster,          false, "show the pnn for the recovery master."},
        { "setflags",        control_setflags,            false, "set flags for a node in the nodemap.", "<node> <flags>"},
        { "scriptstatus",        control_scriptstatus,    false, "show the status of the monitoring scripts"},
+       { "natgwlist",        control_natgwlist,    false, "show the nodes belonging to this natgw configuration"},
 };
 
 /*