ctdb-killtcp: Factor out ctdb_killtcp()
authorMartin Schwenke <martin@meltin.net>
Wed, 2 Mar 2016 05:06:58 +0000 (16:06 +1100)
committerAmitay Isaacs <amitay@samba.org>
Fri, 1 Apr 2016 02:42:11 +0000 (04:42 +0200)
This function knows nothing about CTDB contexts or VNNs, so it can be
used elsewhere.

Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
ctdb/server/ctdb_takeover.c

index 9c3569438737fb6d1e2904e57b8467303d6a5e4f..100fb95040ff5c8be7165d3c395caf0ad705f996 100644 (file)
@@ -2850,48 +2850,30 @@ static void *add_killtcp_callback(void *parm, void *data)
        return parm;
 }
 
-/*
-  add a tcp socket to the list of connections we want to RST
- */
-static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb, 
-                                      ctdb_sock_addr *s,
-                                      ctdb_sock_addr *d)
+/* Add a TCP socket to the list of connections we want to RST.  The
+ * list is attached to *killtcp_arg.  If this is NULL then allocate
+ * the structure.  */
+static int ctdb_killtcp(struct tevent_context *ev,
+                       TALLOC_CTX *mem_ctx,
+                       const char *iface,
+                       const ctdb_sock_addr *src,
+                       const ctdb_sock_addr *dst,
+                       struct ctdb_kill_tcp **killtcp_arg)
 {
-       ctdb_sock_addr src, dst;
        struct ctdb_kill_tcp *killtcp;
        struct ctdb_killtcp_con *con;
-       struct ctdb_vnn *vnn;
-       const char *iface;
-       struct ctdb_killtcp_destructor_data *dd;
-
-       ctdb_canonicalize_ip(s, &src);
-       ctdb_canonicalize_ip(d, &dst);
 
-       vnn = find_public_ip_vnn(ctdb, &dst);
-       if (vnn == NULL) {
-               vnn = find_public_ip_vnn(ctdb, &src);
-       }
-       if (vnn == NULL) {
-               /* if it is not a public ip   it could be our 'single ip' */
-               if (ctdb->single_ip_vnn) {
-                       if (ctdb_same_ip(&ctdb->single_ip_vnn->public_address, &dst)) {
-                               vnn = ctdb->single_ip_vnn;
-                       }
-               }
-       }
-       if (vnn == NULL) {
-               DEBUG(DEBUG_ERR,(__location__ " Could not killtcp, not a public address\n")); 
+       if (killtcp_arg == NULL) {
+               DEBUG(DEBUG_ERR, (__location__ " killtcp_arg is NULL!\n"));
                return -1;
        }
 
-       iface = ctdb_vnn_iface_string(vnn);
-       killtcp = vnn->killtcp;
+       killtcp = *killtcp_arg;
 
-       /* If this is the first connection to kill we must allocate
-          a new structure
-        */
+       /* Allocate a new structure if necessary.  The structure is
+        * only freed when mem_ctx is freed. */
        if (killtcp == NULL) {
-               killtcp = talloc_zero(vnn, struct ctdb_kill_tcp);
+               killtcp = talloc_zero(mem_ctx, struct ctdb_kill_tcp);
                if (killtcp == NULL) {
                        DEBUG(DEBUG_ERR, (__location__ " out of memory\n"));
                        return -1;
@@ -2899,12 +2881,9 @@ static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
 
                killtcp->capture_fd  = -1;
                killtcp->connections = trbt_create(killtcp, 0);
-
-               vnn->killtcp         = killtcp;
+               *killtcp_arg = killtcp;
        }
 
-
-
        /* create a structure that describes this connection we want to
           RST and store it in killtcp->connections
        */
@@ -2913,32 +2892,36 @@ static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
                DEBUG(DEBUG_ERR, (__location__ " out of memory\n"));
                return -1;
        }
-       con->src_addr = src;
-       con->dst_addr = dst;
+       con->src_addr = *src;
+       con->dst_addr = *dst;
        con->count    = 0;
        con->killtcp  = killtcp;
 
 
        trbt_insertarray32_callback(killtcp->connections,
-                       KILLTCP_KEYLEN, killtcp_key(&con->dst_addr, &con->src_addr),
-                       add_killtcp_callback, con);
+                                   KILLTCP_KEYLEN,
+                                   killtcp_key(&con->dst_addr,
+                                               &con->src_addr),
+                                   add_killtcp_callback, con);
 
-       /* 
+       /*
           If we don't have a socket to listen on yet we must create it
         */
        if (killtcp->capture_fd == -1) {
-               killtcp->capture_fd = ctdb_sys_open_capture_socket(iface, &killtcp->private_data);
+               killtcp->capture_fd =
+                       ctdb_sys_open_capture_socket(iface,
+                                                    &killtcp->private_data);
                if (killtcp->capture_fd == -1) {
                        DEBUG(DEBUG_CRIT,(__location__ " Failed to open capturing "
                                          "socket on iface '%s' for killtcp (%s)\n",
                                          iface, strerror(errno)));
-                       goto failed;
+                       return -1;
                }
        }
 
 
        if (killtcp->fde == NULL) {
-               killtcp->fde = tevent_add_fd(ctdb->ev, killtcp,
+               killtcp->fde = tevent_add_fd(ev, killtcp,
                                             killtcp->capture_fd,
                                             TEVENT_FD_READ,
                                             capture_tcp_handler, killtcp);
@@ -2947,7 +2930,7 @@ static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
                /* We also need to set up some events to tickle all these connections
                   until they are all reset
                */
-               tevent_add_timer(ctdb->ev, killtcp, timeval_current_ofs(1, 0),
+               tevent_add_timer(ev, killtcp, timeval_current_ofs(1, 0),
                                 ctdb_tickle_sentenced_connections, killtcp);
        }
 
@@ -2957,23 +2940,62 @@ static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
                &con->src_addr,
                0, 0, 0);
 
-       dd = talloc(killtcp, struct ctdb_killtcp_destructor_data);
+       return 0;
+}
+
+/*
+  add a tcp socket to the list of connections we want to RST
+ */
+static int ctdb_killtcp_add_connection(struct ctdb_context *ctdb,
+                                      ctdb_sock_addr *s,
+                                      ctdb_sock_addr *d)
+{
+       ctdb_sock_addr src, dst;
+       struct ctdb_vnn *vnn;
+       const char *iface;
+       struct ctdb_killtcp_destructor_data *dd;
+       int ret;
+
+       ctdb_canonicalize_ip(s, &src);
+       ctdb_canonicalize_ip(d, &dst);
+
+       vnn = find_public_ip_vnn(ctdb, &dst);
+       if (vnn == NULL) {
+               vnn = find_public_ip_vnn(ctdb, &src);
+       }
+       if (vnn == NULL) {
+               /* if it is not a public ip   it could be our 'single ip' */
+               if (ctdb->single_ip_vnn) {
+                       if (ctdb_same_ip(&ctdb->single_ip_vnn->public_address, &dst)) {
+                               vnn = ctdb->single_ip_vnn;
+                       }
+               }
+       }
+       if (vnn == NULL) {
+               DEBUG(DEBUG_ERR,(__location__ " Could not killtcp, not a public address\n"));
+               return -1;
+       }
+
+       iface = ctdb_vnn_iface_string(vnn);
+
+       ret = ctdb_killtcp(ctdb->ev, vnn, iface, &src, &dst, &vnn->killtcp);
+       if (ret != 0) {
+               return -1;
+       }
+
+       dd = talloc(vnn->killtcp, struct ctdb_killtcp_destructor_data);
        if (dd == NULL) {
                DEBUG(DEBUG_ERR, (__location__ " out of memory\n"));
-               goto failed;
+               TALLOC_FREE(vnn->killtcp);
+               return -1;
        }
 
        dd->vnn = vnn;
        dd->ctdb = ctdb;
-       killtcp->destructor_data = dd;
-       talloc_set_destructor(killtcp, ctdb_killtcp_destructor);
+       vnn->killtcp->destructor_data = dd;
+       talloc_set_destructor(vnn->killtcp, ctdb_killtcp_destructor);
 
        return 0;
-
-failed:
-       talloc_free(vnn->killtcp);
-       vnn->killtcp = NULL;
-       return -1;
 }
 
 /*