git: 5bdce6ff546e - main - Remove deadlock in rc caused by pwait waiting for itself.

Alexander V. Chernikov melifaro at FreeBSD.org
Thu Jan 21 21:36:42 UTC 2021


The branch main has been updated by melifaro:

URL: https://cgit.FreeBSD.org/src/commit/?id=5bdce6ff546e00673f9f515d2165d02901e858aa

commit 5bdce6ff546e00673f9f515d2165d02901e858aa
Author:     Alexander V. Chernikov <melifaro at FreeBSD.org>
AuthorDate: 2021-01-21 21:26:15 +0000
Commit:     Alexander V. Chernikov <melifaro at 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
    PR:             218598
    Differential Revision: https://reviews.freebsd.org/D28240
---
 bin/pwait/pwait.1 | 6 +++++-
 bin/pwait/pwait.c | 4 ++++
 2 files changed, 9 insertions(+), 1 deletion(-)

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;


More information about the dev-commits-src-all mailing list