]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: protocol: replace ->pause(listener) with ->rx_suspend(receiver)
authorWilly Tarreau <w@1wt.eu>
Fri, 25 Sep 2020 15:12:32 +0000 (17:12 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 9 Oct 2020 09:27:30 +0000 (11:27 +0200)
The ->pause method is inappropriate since it doesn't exactly "pause" a
listener but rather temporarily disables it so that it's not visible at
all to let another process take its place. The term "suspend" is more
suitable, since the "pause" is actually what we'll need to apply to the
FULL and LIMITED states which really need to make a pause in the accept
process. And it goes well with the use of the "resume" function that
will also need to be made per-protocol.

Let's rename the function and make it act on the receiver since it's
already what it essentially does, hence the prefix "_rx" to make it
more explicit.

The protocol struct was a bit reordered because it was becoming a real
mess between the parts related to the listeners and those for the
receivers.

include/haproxy/proto_tcp.h
include/haproxy/proto_udp.h
include/haproxy/protocol-t.h
src/listener.c
src/proto_sockpair.c
src/proto_tcp.c
src/proto_udp.c
src/proto_uxst.c

index 8e57acfd6867353614e97458ea6ce504abae75b1..63bbb573387990f8a51119c89a4270241adc7d38 100644 (file)
@@ -29,7 +29,6 @@
 #include <haproxy/sample-t.h>
 
 int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct sockaddr_storage *remote);
-int tcp_pause_listener(struct listener *l);
 int tcp_connect_server(struct connection *conn, int flags);
 int tcp_is_foreign(int fd, sa_family_t family);
 
index f9069d16e3531a73f2f5ee43628fabe64ce61518..25c14235ea6be432519bb1fc3d273bc76efc17d5 100644 (file)
@@ -25,7 +25,6 @@
 #define _PROTO_PROTO_UDP_H
 
 int udp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct sockaddr_storage *remote);
-int udp_pause_listener(struct listener *l);
 
 #endif /* _PROTO_PROTO_UDP_H */
 
index 138dbbb874138cc7ab03046aa37199c2c060dca0..75da65b4687b112b8d035ace16b6b7b12b48a212 100644 (file)
@@ -74,7 +74,8 @@ struct proto_fam {
 
 /* This structure contains all information needed to easily handle a protocol.
  * Its primary goal is to ease listeners maintenance. Specifically, the
- * bind() primitive must be used before any fork().
+ * bind() primitive must be used before any fork(). rx_* may be null if the
+ * protocol doesn't provide direct access to the receiver.
  */
 struct protocol {
        char name[PROTO_NAME_LEN];                      /* protocol name, zero-terminated */
@@ -83,12 +84,18 @@ struct protocol {
        int sock_domain;                                /* socket domain, as passed to socket()   */
        int sock_type;                                  /* socket type, as passed to socket()     */
        int sock_prot;                                  /* socket protocol, as passed to socket() */
-       void (*accept)(int fd);                         /* generic accept function */
+
+       /* functions acting on the listener */
+       void (*add)(struct listener *l, int port);      /* add a listener for this protocol and port */
        int (*listen)(struct listener *l, char *errmsg, int errlen); /* start a listener */
+
+       /* functions acting on the receiver */
+       int (*rx_suspend)(struct receiver *rx);         /* temporarily suspend this receiver for a soft restart */
+
+       /* functions acting on connections */
+       void (*accept)(int fd);                         /* generic accept function */
        int (*connect)(struct connection *, int flags); /* connect function if any, see below for flags values */
        int (*drain)(int fd);                           /* indicates whether we can safely close the fd */
-       int (*pause)(struct listener *l);               /* temporarily pause this listener for a soft restart */
-       void (*add)(struct listener *l, int port);      /* add a listener for this protocol and port */
 
        struct list receivers;                          /* list of receivers using this protocol (under proto_lock) */
        int nb_receivers;                               /* number of receivers (under proto_lock) */
index b24ee5636a0d90528573d96ff8433991c5f520bc..fae46c7157c283b35a79c42cafb381b801d62c3f 100644 (file)
@@ -330,11 +330,11 @@ int pause_listener(struct listener *l)
        if (l->state <= LI_PAUSED)
                goto end;
 
-       if (l->rx.proto->pause) {
+       if (l->rx.proto->rx_suspend) {
                /* Returns < 0 in case of failure, 0 if the listener
                 * was totally stopped, or > 0 if correctly paused.
                 */
-               ret = l->rx.proto->pause(l);
+               ret = l->rx.proto->rx_suspend(&l->rx);
 
                if (ret < 0) {
                        ret = 0;
index d46fa2794522ba50f69050185a331adb76efc248..b787f95fe88c91abbc40e3e9b33e58c1e1553042 100644 (file)
@@ -65,11 +65,10 @@ static struct protocol proto_sockpair = {
        .sock_domain = AF_CUST_SOCKPAIR,
        .sock_type = SOCK_STREAM,
        .sock_prot = 0,
+       .add = sockpair_add_listener,
+       .listen = sockpair_bind_listener,
        .accept = &listener_accept,
        .connect = &sockpair_connect_server,
-       .listen = sockpair_bind_listener,
-       .pause = NULL,
-       .add = sockpair_add_listener,
        .receivers = LIST_HEAD_INIT(proto_sockpair.receivers),
        .nb_receivers = 0,
 };
index 93daa5a800c517bd4ff41c8ed1275af0d0430d3d..b3dbdd467d06145db2567abd601a2939ebf3793a 100644 (file)
@@ -45,6 +45,7 @@
 
 
 static int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen);
+static int tcp_suspend_receiver(struct receiver *rx);
 static void tcpv4_add_listener(struct listener *listener, int port);
 static void tcpv6_add_listener(struct listener *listener, int port);
 
@@ -56,11 +57,11 @@ static struct protocol proto_tcpv4 = {
        .sock_domain = AF_INET,
        .sock_type = SOCK_STREAM,
        .sock_prot = IPPROTO_TCP,
+       .add = tcpv4_add_listener,
+       .listen = tcp_bind_listener,
+       .rx_suspend = tcp_suspend_receiver,
        .accept = &listener_accept,
        .connect = tcp_connect_server,
-       .listen = tcp_bind_listener,
-       .pause = tcp_pause_listener,
-       .add = tcpv4_add_listener,
        .receivers = LIST_HEAD_INIT(proto_tcpv4.receivers),
        .nb_receivers = 0,
 };
@@ -75,11 +76,11 @@ static struct protocol proto_tcpv6 = {
        .sock_domain = AF_INET6,
        .sock_type = SOCK_STREAM,
        .sock_prot = IPPROTO_TCP,
+       .add = tcpv6_add_listener,
+       .listen = tcp_bind_listener,
+       .rx_suspend = tcp_suspend_receiver,
        .accept = &listener_accept,
        .connect = tcp_connect_server,
-       .listen = tcp_bind_listener,
-       .pause = tcp_pause_listener,
-       .add = tcpv6_add_listener,
        .receivers = LIST_HEAD_INIT(proto_tcpv6.receivers),
        .nb_receivers = 0,
 };
@@ -725,23 +726,24 @@ static void tcpv6_add_listener(struct listener *listener, int port)
        proto_tcpv6.nb_receivers++;
 }
 
-/* Pause a listener. Returns < 0 in case of failure, 0 if the listener
- * was totally stopped, or > 0 if correctly paused.
+/* Suspend a receiver. Returns < 0 in case of failure, 0 if the receiver
+ * was totally stopped, or > 0 if correctly suspended.
  */
-int tcp_pause_listener(struct listener *l)
+static int tcp_suspend_receiver(struct receiver *rx)
 {
+       struct listener *l = LIST_ELEM(rx, struct listener *, rx);
        socklen_t opt_val, opt_len;
 
-       if (shutdown(l->rx.fd, SHUT_WR) != 0)
+       if (shutdown(rx->fd, SHUT_WR) != 0)
                goto check_already_done; /* usually Solaris fails here */
 
-       if (listen(l->rx.fd, listener_backlog(l)) != 0)
+       if (listen(rx->fd, listener_backlog(l)) != 0)
                goto check_already_done; /* Usually OpenBSD fails here */
 
-       if (shutdown(l->rx.fd, SHUT_RD) != 0)
+       if (shutdown(rx->fd, SHUT_RD) != 0)
                goto check_already_done; /* show always be OK */
 
-       fd_stop_recv(l->rx.fd);
+       fd_stop_recv(rx->fd);
        return 1;
 
  check_already_done:
@@ -751,13 +753,13 @@ int tcp_pause_listener(struct listener *l)
         */
        opt_val = 0;
        opt_len = sizeof(opt_val);
-       if (getsockopt(l->rx.fd, SOL_SOCKET, SO_ACCEPTCONN, &opt_val, &opt_len) == -1) {
-               fd_stop_recv(l->rx.fd);
+       if (getsockopt(rx->fd, SOL_SOCKET, SO_ACCEPTCONN, &opt_val, &opt_len) == -1) {
+               fd_stop_recv(rx->fd);
                return 0; /* the socket is really unrecoverable */
        }
 
        if (!opt_val) {
-               fd_stop_recv(l->rx.fd);
+               fd_stop_recv(rx->fd);
                return 1; /* already paused by another process */
        }
 
index 44593b90cae05ad5d7f1bb42f09b933fe28ee28f..1181d1adc40e0651aed0e2091c234b8bcabbe42e 100644 (file)
@@ -41,6 +41,7 @@
 #include <haproxy/task.h>
 
 static int udp_bind_listener(struct listener *listener, char *errmsg, int errlen);
+static int udp_suspend_receiver(struct receiver *rx);
 static void udp4_add_listener(struct listener *listener, int port);
 static void udp6_add_listener(struct listener *listener, int port);
 
@@ -52,11 +53,9 @@ static struct protocol proto_udp4 = {
        .sock_domain = AF_INET,
        .sock_type = SOCK_DGRAM,
        .sock_prot = IPPROTO_UDP,
-       .accept = NULL,
-       .connect = NULL,
-       .listen = udp_bind_listener,
-       .pause = udp_pause_listener,
        .add = udp4_add_listener,
+       .listen = udp_bind_listener,
+       .rx_suspend = udp_suspend_receiver,
        .receivers = LIST_HEAD_INIT(proto_udp4.receivers),
        .nb_receivers = 0,
 };
@@ -71,11 +70,9 @@ static struct protocol proto_udp6 = {
        .sock_domain = AF_INET6,
        .sock_type = SOCK_DGRAM,
        .sock_prot = IPPROTO_UDP,
-       .accept = NULL,
-       .connect = NULL,
-       .listen = udp_bind_listener,
-       .pause = udp_pause_listener,
        .add = udp6_add_listener,
+       .listen = udp_bind_listener,
+       .rx_suspend = udp_suspend_receiver,
        .receivers = LIST_HEAD_INIT(proto_udp6.receivers),
        .nb_receivers = 0,
 };
@@ -154,12 +151,12 @@ static void udp6_add_listener(struct listener *listener, int port)
        proto_udp6.nb_receivers++;
 }
 
-/* Pause a listener. Returns < 0 in case of failure, 0 if the listener
- * was totally stopped, or > 0 if correctly paused.
+/* Suspend a receiver. Returns < 0 in case of failure, 0 if the receiver
+ * was totally stopped, or > 0 if correctly suspended.
  */
-int udp_pause_listener(struct listener *l)
+static int udp_suspend_receiver(struct receiver *rx)
 {
-       /* we don't support pausing on UDP */
+       /* we don't support suspend on UDP */
        return -1;
 }
 
index 26109278ef31397cbd749a5225644e910c4b552a..7278d51b3ec03061c2b6a40abd478e78a12599c1 100644 (file)
@@ -43,7 +43,7 @@
 static int uxst_bind_listener(struct listener *listener, char *errmsg, int errlen);
 static int uxst_connect_server(struct connection *conn, int flags);
 static void uxst_add_listener(struct listener *listener, int port);
-static int uxst_pause_listener(struct listener *l);
+static int uxst_suspend_receiver(struct receiver *rx);
 
 /* Note: must not be declared <const> as its list will be overwritten */
 static struct protocol proto_unix = {
@@ -53,11 +53,11 @@ static struct protocol proto_unix = {
        .sock_domain = PF_UNIX,
        .sock_type = SOCK_STREAM,
        .sock_prot = 0,
+       .add = uxst_add_listener,
+       .listen = uxst_bind_listener,
+       .rx_suspend = uxst_suspend_receiver,
        .accept = &listener_accept,
        .connect = &uxst_connect_server,
-       .listen = uxst_bind_listener,
-       .pause = uxst_pause_listener,
-       .add = uxst_add_listener,
        .receivers = LIST_HEAD_INIT(proto_unix.receivers),
        .nb_receivers = 0,
 };
@@ -146,15 +146,17 @@ static void uxst_add_listener(struct listener *listener, int port)
        proto_unix.nb_receivers++;
 }
 
-/* Pause a listener. Returns < 0 in case of failure, 0 if the listener
- * was totally stopped, or > 0 if correctly paused. Nothing is done for
+/* Suspend a receiver. Returns < 0 in case of failure, 0 if the receiver
+ * was totally stopped, or > 0 if correctly suspended. Nothing is done for
  * plain unix sockets since currently it's the new process which handles
  * the renaming. Abstract sockets are completely unbound and closed so
  * there's no need to stop the poller.
  */
-static int uxst_pause_listener(struct listener *l)
+static int uxst_suspend_receiver(struct receiver *rx)
 {
-       if (((struct sockaddr_un *)&l->rx.addr)->sun_path[0])
+       struct listener *l = LIST_ELEM(rx, struct listener *, rx);
+
+       if (((struct sockaddr_un *)&rx->addr)->sun_path[0])
                return 1;
 
        /* Listener's lock already held. Call lockless version of