MINOR: sock: move the unused socket cleaning code into its own function
The startup code used to scan the list of unused sockets retrieved from
an older process, and to close them one by one. This also required that
the knowledge of the internal storage of these temporary sockets was
known from outside sock.c and that the code was copy-pasted at every
call place.
This patch moves this into sock.c under the name
sock_drop_unused_old_sockets(), and removes the xfer_sock_list
definition from sock.h since the rest of the code doesn't need to know
this.
This cleanup is minimal and preliminary to a future fix that will need
to be backported to all versions featuring FD transfers over the CLI.
(cherry picked from commit b510116fd2b9a676297a1d2bec7d0107bf3c7383)
Signed-off-by: William Lallemand <wlallemand@haproxy.org>
(cherry picked from commit 9575192a04144ba2590767ea7281d36ef30a4fdf)
Signed-off-by: Willy Tarreau <w@1wt.eu>
diff --git a/include/haproxy/sock-t.h b/include/haproxy/sock-t.h
index 1a49dfa..b843d44 100644
--- a/include/haproxy/sock-t.h
+++ b/include/haproxy/sock-t.h
@@ -27,23 +27,6 @@
#include <haproxy/api-t.h>
-#define SOCK_XFER_OPT_FOREIGN 0x000000001
-#define SOCK_XFER_OPT_V6ONLY 0x000000002
-#define SOCK_XFER_OPT_DGRAM 0x000000004
-
-/* The list used to transfer sockets between old and new processes */
-struct xfer_sock_list {
- int fd;
- int options; /* socket options as SOCK_XFER_OPT_* */
- char *iface;
- char *namespace;
- int if_namelen;
- int ns_namelen;
- struct xfer_sock_list *prev;
- struct xfer_sock_list *next;
- struct sockaddr_storage addr;
-};
-
#endif /* _HAPROXY_SOCK_T_H */
/*
diff --git a/include/haproxy/sock.h b/include/haproxy/sock.h
index 1a5b68c..49dffa9 100644
--- a/include/haproxy/sock.h
+++ b/include/haproxy/sock.h
@@ -30,8 +30,6 @@
#include <haproxy/listener-t.h>
#include <haproxy/sock-t.h>
-extern struct xfer_sock_list *xfer_sock_list;
-
int sock_create_server_socket(struct connection *conn);
void sock_enable(struct receiver *rx);
void sock_disable(struct receiver *rx);
@@ -40,6 +38,7 @@
int sock_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
int sock_get_old_sockets(const char *unixsocket);
int sock_find_compatible_fd(const struct receiver *rx);
+void sock_drop_unused_old_sockets();
int sock_accepting_conn(const struct receiver *rx);
struct connection *sock_accept_conn(struct listener *l, int *status);
void sock_accept_iocb(int fd);
diff --git a/src/haproxy.c b/src/haproxy.c
index ef5021a..a649d6a 100644
--- a/src/haproxy.c
+++ b/src/haproxy.c
@@ -3029,14 +3029,7 @@
/* Ok, all listeners should now be bound, close any leftover sockets
* the previous process gave us, we don't need them anymore
*/
- while (xfer_sock_list != NULL) {
- struct xfer_sock_list *tmpxfer = xfer_sock_list->next;
- close(xfer_sock_list->fd);
- free(xfer_sock_list->iface);
- free(xfer_sock_list->namespace);
- free(xfer_sock_list);
- xfer_sock_list = tmpxfer;
- }
+ sock_drop_unused_old_sockets();
/* prepare pause/play signals */
signal_register_fct(SIGTTOU, sig_pause, SIGTTOU);
diff --git a/src/sock.c b/src/sock.c
index 9d272cc..399f7b7 100644
--- a/src/sock.c
+++ b/src/sock.c
@@ -34,8 +34,24 @@
#include <haproxy/sock_inet.h>
#include <haproxy/tools.h>
+#define SOCK_XFER_OPT_FOREIGN 0x000000001
+#define SOCK_XFER_OPT_V6ONLY 0x000000002
+#define SOCK_XFER_OPT_DGRAM 0x000000004
+
/* the list of remaining sockets transferred from an older process */
-struct xfer_sock_list *xfer_sock_list = NULL;
+struct xfer_sock_list {
+ int fd;
+ int options; /* socket options as SOCK_XFER_OPT_* */
+ char *iface;
+ char *namespace;
+ int if_namelen;
+ int ns_namelen;
+ struct xfer_sock_list *prev;
+ struct xfer_sock_list *next;
+ struct sockaddr_storage addr;
+};
+
+static struct xfer_sock_list *xfer_sock_list;
/* Accept an incoming connection from listener <l>, and return it, as well as
@@ -595,6 +611,24 @@
return ret;
}
+/* After all protocols are bound, there may remain some old sockets that have
+ * been removed between the previous config and the new one. These ones must
+ * be dropped, otherwise they will remain open and may prevent a service from
+ * restarting.
+ */
+void sock_drop_unused_old_sockets()
+{
+ while (xfer_sock_list != NULL) {
+ struct xfer_sock_list *tmpxfer = xfer_sock_list->next;
+
+ close(xfer_sock_list->fd);
+ free(xfer_sock_list->iface);
+ free(xfer_sock_list->namespace);
+ free(xfer_sock_list);
+ xfer_sock_list = tmpxfer;
+ }
+}
+
/* Tests if the receiver supports accepting connections. Returns positive on
* success, 0 if not possible, negative if the socket is non-recoverable. The
* rationale behind this is that inherited FDs may be broken and that shared