aboutsummaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2021-01-21 21:26:15 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2021-01-21 21:36:37 +0000
commit5bdce6ff546e00673f9f515d2165d02901e858aa (patch)
tree2a3b853afcfe7cee2d80be5e23649f0563c76caa /bin
parent1ac7c34486ab9177c2472278739568d4607e1acc (diff)
downloadsrc-5bdce6ff546e00673f9f515d2165d02901e858aa.tar.gz
src-5bdce6ff546e00673f9f515d2165d02901e858aa.zip
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 PR: 218598 Differential Revision: https://reviews.freebsd.org/D28240
Diffstat (limited to 'bin')
-rw-r--r--bin/pwait/pwait.16
-rw-r--r--bin/pwait/pwait.c4
2 files changed, 9 insertions, 1 deletions
diff --git a/bin/pwait/pwait.1 b/bin/pwait/pwait.1
index 0452203eb4a1..b9b651bfc905 100644
--- a/bin/pwait/pwait.1
+++ b/bin/pwait/pwait.1
@@ -32,7 +32,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd October 5, 2020
+.Dd January 21, 2021
.Dt PWAIT 1
.Os
.Sh NAME
@@ -145,6 +145,10 @@ is not a substitute for the
.Xr wait 1
builtin
as it will not clean up any zombies or state in the parent process.
+.Pp
+To avoid deadlock,
+.Nm
+will ignore its own pid, if it is provided as a process id to wait for.
.Sh HISTORY
A
.Nm
diff --git a/bin/pwait/pwait.c b/bin/pwait/pwait.c
index f39922b48eb9..85cc6b994acf 100644
--- a/bin/pwait/pwait.c
+++ b/bin/pwait/pwait.c
@@ -146,6 +146,10 @@ main(int argc, char *argv[])
warnx("%s: bad process id", s);
continue;
}
+ if (pid == getpid()) {
+ warnx("%s: skiping my own pid", s);
+ continue;
+ }
for (i = 0; i < nleft; i++) {
if (e[i].ident == (uintptr_t)pid) {
break;