Created attachment 181726 [details]
Patch to not wait on our own pid.
pwait will deadlock when passed its own PID. I experienced this when kern.randompid was set with poudriere. The code was more or less this:
if do_the_thing ends before pwait starts, and do_the_thing and pwait get the same pid, pwait waits indefinitely.
I've attached a patch to warn and exit immediately if pwait is told to wait on its own pid.
Hmm, this is sort of a workaround for the shell reaping zombies quickly and not providing the script with a good way to detect this.
If code is executed like
sh -c '...; exec pwait $$'
it arguably should deadlock.
The patch seems a simple way to avoid the deadlock in poudriere, though.
(In reply to Jilles Tjoelker from comment #1)
Yeah, a literal reading of the documentation implies that it should hang. Personally I'd interpret pwait's own PID as invalid, though that's up for debate.
Is there any update regarding on this bug?
A similar patch got submitted to Phabricator: https://reviews.freebsd.org/D28240
A commit in branch main references this bug:
Author: Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2021-01-21 21:26:15 +0000
Commit: Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2021-01-21 21:36:37 +0000
Remove deadlock in rc caused by pwait waiting for itself.
The following situation can trigger the deadlock:
1) Long time ago a_service was started through rc.d
2) We want to restart a_service and issue service a_service restart
3) rc.subr reads current process PID (via file or process),
sends TERM signal and runs pwait with PID harvested
4) a_service process dies very quickly so it's PID becomes available.
It is possible that while original process was running,
PID counter overflowed and pwait got assigned a_service's PID.
This patch ignores pid(s) to wait that are equal to pwait PID.
Reported by: Dan McGregor, Boris Lytochkin
Submitted by: Boris Lytochkin <lytboris at gmail.com>
Reviewed By: 0mp
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D28240
bin/pwait/pwait.1 | 6 +++++-
bin/pwait/pwait.c | 4 ++++
2 files changed, 9 insertions(+), 1 deletion(-)