Mitigation for spawn FD closing taking forever with a big FD limit (#10761)
commit0d29dfb9ddba7f3c5ae65ecac02f28bada5a9b06
authorCalvin Buckley <calvin@cmpct.info>
Mon, 8 Oct 2018 12:31:29 +0000 (8 09:31 -0300)
committerLudovic Henry <luhenry@microsoft.com>
Mon, 8 Oct 2018 12:31:29 +0000 (8 08:31 -0400)
tree7874fe5229c7880a69e3649a9f5bf6560af1d84a
parenta756fa0f4ae751c394f780af9a0022dbfe4e23cb
Mitigation for spawn FD closing taking forever with a big FD limit (#10761)

* Mitigation for spawn FD closing taking forever with a big FD limit

On systems with a large file descriptor limit, Mono takes a very
long time to spawn a new process; with informal testing on the AIX
CI builder, (with a POWER7) it took ~30 minutes. This is obviously
very undesirable, but hand our is forced - libraries the user might
be calling could be creating non-CLOEXEC files we're unaware of. As
such, we started from the FD limit and worked our way down until we
hit stdio. Using APIs such as posix_spawn aren't desirable as we do
some fiddling with the child before we exec; and even then, closing
FDs with posix_spawn relies on non-standard file actions like
Solaris' addclosefrom not present on many systems. (All of this is
unnecessary on Windows, of course.)

This presents an alternative way (currently only implemented on AIX
but with notes how for other platforms) to try to close the child's
loose FDs before exec; by trying to get the highest number FD in
use, then work our way down. In the event we can't, we simply fall
back to the old logic.

See #6555 for a discussion and the initial problem being mitigated.

* Use an another strategy of closing only known to be open handles

...on FreeBSD and AIX.

Use the kinfo_getfiles library call on FreeBSD and only close what's
safe to close. On AIX, use the third and fourth arguments to getprocs
to check what's open. However, the array to get all the handles takes
1 MB, so allocate it on the heap; like what kinfo_getfiles does. We
don't need to free these as the child will exec or exit, which blows
it all away.

The previous strategy from previous commit is still used and on AIX,
enhanced.

* Add Linux strategy to fork FD close

Tested on WSL, shows benefits with big FD ulimit.
configure.ac
mono/metadata/w32process-unix.c