]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: fd: support stopping FDs during starting
authorWilly Tarreau <w@1wt.eu>
Fri, 15 Jul 2022 16:56:48 +0000 (18:56 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 15 Jul 2022 18:16:30 +0000 (20:16 +0200)
There's a nasty case during boot, which is the master process. It stops
all listeners from the main thread, and as such we're seeing calls to
fd_delete() from a thread that doesn't match the FD's mask, but more
importantly from a group that doesn't match either. Fortunately this
happens in a process that doesn't see the threads creation, so the FDs
are left intact in the table and we can overwrite the tgid there.

The approach is ugly, it probably shows that we should use a dummy
value for the tgid during boot, that would be replaced once the FDs
migrate to their target, but we also need a way to make sure not to
miss them. Also that doesn't solve the possibility of closing a
listener at run time from the wrong thread group.

src/fd.c

index ca0483f888121a57046c5ae6136b3af18de05589..5a850d0915e35e314536a04864727347f23085c6 100644 (file)
--- a/src/fd.c
+++ b/src/fd.c
@@ -355,6 +355,14 @@ void fd_delete(int fd)
         */
        BUG_ON(fd < 0 || fd >= global.maxsock);
 
+       /* NOTE: The master when going into reexec mode re-closes all FDs after
+        * they were already dispatched. But we know we didn't start the polling
+        * threads so we can still close them. The masks will probably not match
+        * however so we force the value and erase the refcount if any.
+        */
+       if (unlikely(global.mode & MODE_STARTING))
+               fdtab[fd].refc_tgid = ti->tgid;
+
        /* the tgid cannot change before a complete close so we should never
         * face the situation where we try to close an fd that was reassigned.
         */