MEDIUM: fd: support stopping FDs during starting

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.
This commit is contained in:
Willy Tarreau 2022-07-15 18:56:48 +02:00
parent 88c4c14050
commit 9baff4ffd9

View File

@ -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.
*/