#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 */
/*
#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);
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);
/* 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);
#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
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