version 1.2.200
[sahlberg/ctdb.git] / tcp / tcp_init.c
index 4f3c29a010a8806f7d32e5fe2bdbe061e527ca51..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 
@@ -38,9 +48,10 @@ static int ctdb_tcp_add_node(struct ctdb_node *node)
 
        tnode->fd = -1;
        node->private_data = tnode;
+       talloc_set_destructor(tnode, tnode_destructor);
 
-       tnode->queue = ctdb_queue_setup(node->ctdb, node, 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;
 }
@@ -53,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;
                }
        }
@@ -68,18 +85,64 @@ static int ctdb_tcp_initialise(struct ctdb_context *ctdb)
 /*
   start the protocol going
 */
+static int ctdb_tcp_connect_node(struct ctdb_node *node)
+{
+       struct ctdb_context *ctdb = node->ctdb;
+       struct ctdb_tcp_node *tnode = talloc_get_type(
+               node->private_data, struct ctdb_tcp_node);
+
+       /* startup connection to the other server - will happen on
+          next event loop */
+       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
+*/
+static void ctdb_tcp_shutdown(struct ctdb_context *ctdb)
+{
+       struct ctdb_tcp *ctcp = talloc_get_type(ctdb->private_data,
+                                               struct ctdb_tcp);
+       talloc_free(ctcp);
+       ctdb->private_data = NULL;
+}
+
+/*
+  start the transport
+*/
 static int ctdb_tcp_start(struct ctdb_context *ctdb)
 {
        int i;
 
-       /* startup connections to the other servers - will happen on
-          next event loop */
-       for (i=0;i<ctdb->num_nodes;i++) {
-               struct ctdb_node *node = *(ctdb->nodes + i);
-               if (!(ctdb->flags & CTDB_FLAG_SELF_CONNECT) &&
-                   ctdb_same_address(&ctdb->address, &node->address)) continue;
-               event_add_timed(ctdb->ev, node, timeval_zero(), 
-                               ctdb_tcp_node_connect, node);
+       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;
@@ -104,9 +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,
-       .allocate_pkt = ctdb_tcp_allocate_pkt
+       .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 
 */
@@ -117,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;
 }