freebsd-dev/bin/pwait/pwait.1
Alexander V. Chernikov 5bdce6ff54 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
2021-01-21 21:36:37 +00:00

156 lines
3.8 KiB
Groff

.\"
.\" Copyright (c) 2004-2009, Jilles Tjoelker
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with
.\" or without modification, are permitted provided that the
.\" following conditions are met:
.\"
.\" 1. Redistributions of source code must retain the above
.\" copyright notice, this list of conditions and the
.\" following disclaimer.
.\" 2. Redistributions in binary form must reproduce the
.\" above copyright notice, this list of conditions and
.\" the following disclaimer in the documentation and/or
.\" other materials provided with the distribution.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
.\" CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
.\" WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
.\" PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
.\" COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
.\" USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
.\" OF SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd January 21, 2021
.Dt PWAIT 1
.Os
.Sh NAME
.Nm pwait
.Nd wait for processes to terminate
.Sh SYNOPSIS
.Nm
.Op Fl t Ar duration
.Op Fl ov
.Ar pid
\&...
.Sh DESCRIPTION
The
.Nm
utility will wait until each of the given processes has terminated.
.Pp
The following option is available:
.Bl -tag -width indent
.It Fl o
Exit when any of the given processes has terminated.
.It Fl t Ar duration
If any process is still running after
.Ar duration ,
.Nm
will exit.
The
.Ar duration
value can be integer or decimal numbers.
Values without unit symbols are interpreted as seconds.
.Pp
Supported unit symbols are:
.Bl -tag -width indent -compact
.It s
seconds
.It m
minutes
.It h
hours
.El
.It Fl v
Print the exit status when each process terminates or
.Ql timeout
if the timer goes off earlier.
.El
.Sh EXIT STATUS
The
.Nm
utility exits 0 on success, and >0 if an error occurs.
.Pp
If the
.Fl t
flag is specified and a timeout occurs, the exit status will be 124.
.Pp
Invalid pids elicit a warning message but are otherwise ignored.
.Sh EXAMPLES
Start two
.Xr sleep 1
processes in the background.
The first one will sleep for 30 seconds and the second one for one hour.
Wait for any of them to finish but no more than 5 seconds.
Since a timeout occurs the exit status is 124:
.Bd -literal -offset indent
$ sleep 30 & sleep 3600 &
[1] 1646
[2] 1647
$ pwait -o -t5 1646 1647
$?
124
.Ed
.Pp
Same as above but try to obtain the exit status of the processes.
In this case
.Ql timeout
is shown and the exit status is 124:
.Bd -literal -offset indent
$ sleep 30 & sleep 3600 &
[1] 1652
[2] 1653
$ pwait -v -t 5 1652 1653
timeout
$?
124
.Ed
.Pp
Start two
.Xr sleep 1
processes in the background sleeping for 30 and 40 seconds respectively.
Wait 60 seconds for any of them to finish and get their exit codes:
.Bd -literal -offset indent
$ sleep 30 & sleep 40 &
[1] 1674
[2] 1675
$ pwait -v -t 60 1674 1675
1674: exited with status 0.
1675: exited with status 0.
[1]- Done sleep 30
[2]+ Done sleep 40
$ echo $?
0
.Ed
.Sh SEE ALSO
.Xr kill 1 ,
.Xr pkill 1 ,
.Xr ps 1 ,
.Xr wait 1 ,
.Xr kqueue 2
.Sh NOTES
.Nm
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
command first appeared in SunOS 5.8.