ctdb-tcp: Make error handling for outbound connection consistent
authorMartin Schwenke <martin@meltin.net>
Tue, 28 Jan 2020 05:49:14 +0000 (16:49 +1100)
committerKarolin Seeger <kseeger@samba.org>
Mon, 17 Feb 2020 15:50:11 +0000 (15:50 +0000)
If we can't bind the local end of an outgoing connection then
something has gone wrong.  Retrying is better than failing into a
zombie state.  The interface might come back up and/or the address my
be reconfigured.

While here, do the same thing for the other (potentially transient)
failures.

The unknown address family failure is special but just handle it via a
retry.  Technically it can't happen because the node address parsing
can only return values with address family AF_INET or AF_INET6.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=14274
RN: Retry inter-node TCP connections on more transient failures

Reported-by: 耿纪超 <gengjichao@jd.com>
Signed-off-by: Martin Schwenke <martin@meltin.net>
Reviewed-by: Amitay Isaacs <amitay@gmail.com>
(cherry picked from commit a40fc709cc972dadb40efbf1394b10fae3cfcc07)

Autobuild-User(v4-10-test): Karolin Seeger <kseeger@samba.org>
Autobuild-Date(v4-10-test): Mon Feb 17 15:50:11 UTC 2020 on sn-devel-144

ctdb/tcp/tcp_connect.c

index 0b5d021480ad901bd8e16f2fd562b34960423e5d..e0167740602b656416d361eb0f2c414b59e938ed 100644 (file)
@@ -183,16 +183,14 @@ void ctdb_tcp_node_connect(struct tevent_context *ev, struct tevent_timer *te,
        tnode->out_fd = socket(sock_out.sa.sa_family, SOCK_STREAM, IPPROTO_TCP);
        if (tnode->out_fd == -1) {
                DBG_ERR("Failed to create socket\n");
-               return;
+               goto failed;
        }
 
        ret = set_blocking(tnode->out_fd, false);
        if (ret != 0) {
                DBG_ERR("Failed to set socket non-blocking (%s)\n",
                        strerror(errno));
-               close(tnode->out_fd);
-               tnode->out_fd = -1;
-               return;
+               goto failed;
        }
 
        set_close_on_exec(tnode->out_fd);
@@ -224,32 +222,22 @@ void ctdb_tcp_node_connect(struct tevent_context *ev, struct tevent_timer *te,
                sockout_size = sizeof(sock_out.ip6);
                break;
        default:
-               DEBUG(DEBUG_ERR, (__location__ " unknown family %u\n",
-                       sock_in.sa.sa_family));
-               close(tnode->out_fd);
-               tnode->out_fd = -1;
-               return;
+               DBG_ERR("Unknown address family %u\n", sock_in.sa.sa_family);
+               /* Can't happen to due to address parsing restrictions */
+               goto failed;
        }
 
        ret = bind(tnode->out_fd, (struct sockaddr *)&sock_in, sockin_size);
        if (ret == -1) {
                DBG_ERR("Failed to bind socket (%s)\n", strerror(errno));
-               close(tnode->out_fd);
-               tnode->out_fd = -1;
-               return;
+               goto failed;
        }
 
        ret = connect(tnode->out_fd,
                      (struct sockaddr *)&sock_out,
                      sockout_size);
        if (ret != 0 && errno != EINPROGRESS) {
-               ctdb_tcp_stop_connection(node);
-               tnode->connect_te = tevent_add_timer(ctdb->ev,
-                                                    tnode,
-                                                    timeval_current_ofs(1, 0),
-                                                    ctdb_tcp_node_connect,
-                                                    node);
-               return;
+               goto failed;
        }
 
        /* non-blocking connect - wait for write event */
@@ -268,6 +256,16 @@ void ctdb_tcp_node_connect(struct tevent_context *ev, struct tevent_timer *te,
                                             timeval_current_ofs(1, 0),
                                             ctdb_tcp_node_connect,
                                             node);
+
+       return;
+
+failed:
+       ctdb_tcp_stop_connection(node);
+       tnode->connect_te = tevent_add_timer(ctdb->ev,
+                                            tnode,
+                                            timeval_current_ofs(1, 0),
+                                            ctdb_tcp_node_connect,
+                                            node);
 }
 
 /*