IPALLOCATION : If the node is held pinned down in "init" state
[sahlberg/ctdb.git] / tcp / tcp_init.c
index 603812632d4566557842602f288200f53b22cb95..95141d5610d8b283d84412c4208b9413f7d1d250 100644 (file)
@@ -5,7 +5,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
 #include "lib/tdb/include/tdb.h"
-#include "lib/events/events.h"
+#include "lib/tevent/tevent.h"
 #include "system/network.h"
 #include "system/filesys.h"
 #include "../include/ctdb_private.h"
 #include "ctdb_tcp.h"
 
+static int tnode_destructor(struct ctdb_tcp_node *tnode)
+{
+  //   struct ctdb_node *node = talloc_find_parent_bytype(tnode, struct ctdb_node);
+
+       if (tnode->fd != -1) {
+               close(tnode->fd);
+               tnode->fd = -1;
+       }
+
+       return 0;
+}
 
 /*
   initialise tcp portion of a ctdb node 
 */
 static int ctdb_tcp_add_node(struct ctdb_node *node)
 {
-       struct ctdb_tcp *ctcp = talloc_get_type(node->ctdb->private_data,
-                                               struct ctdb_tcp);
        struct ctdb_tcp_node *tnode;
-       tnode = talloc_zero(ctcp, struct ctdb_tcp_node);
+       tnode = talloc_zero(node, struct ctdb_tcp_node);
        CTDB_NO_MEMORY(node->ctdb, tnode);
 
        tnode->fd = -1;
        node->private_data = tnode;
+       talloc_set_destructor(tnode, tnode_destructor);
 
-       tnode->out_queue = ctdb_queue_setup(node->ctdb, ctcp, tnode->fd, CTDB_TCP_ALIGNMENT,
-                                       ctdb_tcp_tnode_cb, node);
+       tnode->out_queue = ctdb_queue_setup(node->ctdb, node, tnode->fd, CTDB_TCP_ALIGNMENT,
+                                           ctdb_tcp_tnode_cb, node, "to-node-%s", node->name);
        
        return 0;
 }
@@ -55,11 +64,17 @@ static int ctdb_tcp_initialise(struct ctdb_context *ctdb)
        int i;
 
        /* listen on our own address */
-       if (ctdb_tcp_listen(ctdb) != 0) return -1;
+       if (ctdb_tcp_listen(ctdb) != 0) {
+               DEBUG(DEBUG_CRIT, (__location__ " Failed to start listening on the CTDB socket\n"));
+               exit(1);
+       }
 
-       for (i=0; i<ctdb->num_nodes; i++) {
+       for (i=0; i < ctdb->num_nodes; i++) {
+               if (ctdb->nodes[i]->flags & NODE_FLAGS_DELETED) {
+                       continue;
+               }
                if (ctdb_tcp_add_node(ctdb->nodes[i]) != 0) {
-                       DEBUG(0, ("methods->add_node failed at %d\n", i));
+                       DEBUG(DEBUG_CRIT, ("methods->add_node failed at %d\n", i));
                        return -1;
                }
        }
@@ -70,25 +85,40 @@ static int ctdb_tcp_initialise(struct ctdb_context *ctdb)
 /*
   start the protocol going
 */
-static int ctdb_tcp_start(struct ctdb_context *ctdb)
+static int ctdb_tcp_connect_node(struct ctdb_node *node)
 {
-       int i;
+       struct ctdb_context *ctdb = node->ctdb;
+       struct ctdb_tcp_node *tnode = talloc_get_type(
+               node->private_data, struct ctdb_tcp_node);
 
-       /* startup connections to the other servers - will happen on
+       /* startup connection to the other server - will happen on
           next event loop */
-       for (i=0;i<ctdb->num_nodes;i++) {
-               struct ctdb_node *node = *(ctdb->nodes + i);
-               struct ctdb_tcp_node *tnode = talloc_get_type(
-                       node->private_data, struct ctdb_tcp_node);
-               if (!ctdb_same_address(&ctdb->address, &node->address)) {
-                       event_add_timed(ctdb->ev, tnode, timeval_zero(), 
-                                       ctdb_tcp_node_connect, node);
-               }
+       if (!ctdb_same_address(&ctdb->address, &node->address)) {
+               tnode->connect_te = event_add_timed(ctdb->ev, tnode, 
+                                                   timeval_zero(), 
+                                                   ctdb_tcp_node_connect, node);
        }
 
        return 0;
 }
 
+/*
+  shutdown and try to restart a connection to a node after it has been
+  disconnected
+*/
+static void ctdb_tcp_restart(struct ctdb_node *node)
+{
+       struct ctdb_tcp_node *tnode = talloc_get_type(
+               node->private_data, struct ctdb_tcp_node);
+
+       DEBUG(DEBUG_NOTICE,("Tearing down connection to dead node :%d\n", node->pnn));
+
+       ctdb_tcp_stop_connection(node);
+
+       tnode->connect_te = event_add_timed(node->ctdb->ev, tnode, timeval_zero(), 
+                                           ctdb_tcp_node_connect, node);
+}
+
 
 /*
   shutdown the transport
@@ -101,6 +131,23 @@ static void ctdb_tcp_shutdown(struct ctdb_context *ctdb)
        ctdb->private_data = NULL;
 }
 
+/*
+  start the transport
+*/
+static int ctdb_tcp_start(struct ctdb_context *ctdb)
+{
+       int i;
+
+       for (i=0; i < ctdb->num_nodes; i++) {
+               if (ctdb->nodes[i]->flags & NODE_FLAGS_DELETED) {
+                       continue;
+               }
+               ctdb_tcp_connect_node(ctdb->nodes[i]);
+       }
+
+       return 0;
+}
+
 
 /*
   transport packet allocator - allows transport to control memory for packets
@@ -120,10 +167,21 @@ static const struct ctdb_methods ctdb_tcp_methods = {
        .start        = ctdb_tcp_start,
        .queue_pkt    = ctdb_tcp_queue_pkt,
        .add_node     = ctdb_tcp_add_node,
+       .connect_node = ctdb_tcp_connect_node,
        .allocate_pkt = ctdb_tcp_allocate_pkt,
        .shutdown     = ctdb_tcp_shutdown,
+       .restart      = ctdb_tcp_restart,
 };
 
+static int tcp_ctcp_destructor(struct ctdb_tcp *ctcp)
+{
+       ctcp->ctdb->private_data = NULL;
+       ctcp->ctdb->methods = NULL;
+       
+       return 0;
+}
+
+               
 /*
   initialise tcp portion of ctdb 
 */
@@ -134,8 +192,11 @@ int ctdb_tcp_init(struct ctdb_context *ctdb)
        CTDB_NO_MEMORY(ctdb, ctcp);
 
        ctcp->listen_fd = -1;
+       ctcp->ctdb      = ctdb;
        ctdb->private_data = ctcp;
        ctdb->methods = &ctdb_tcp_methods;
+
+       talloc_set_destructor(ctcp, tcp_ctcp_destructor);
        return 0;
 }