[lsb-discuss] LSB initscripts: Problems with determining whether a process is running
Tobias Burnus
tobias.burnus at physik.fu-berlin.de
Thu Jul 24 10:55:43 PDT 2003
Hi,
a thing which (on purpose?) has been a bit neglected in the LSB standard
is how to determine whether a process is running. This is needed for
start_daemon, killproc and pidofproc. Before I discuss what problems each
method has, here the current gLSB specification for finding a PID:
"If an entry is found in /var/run/basename.pid, then that value is
returned. If the -p option is used, the given pidfile is used instead.
[...] Compliant implementations of the LSB may attempt other mechanisms
for determining the pid(s), although this is not required (and not
recommended, since a user can trick startup scripts by creating processes
that appear to be system programs in the process list thus creating a
potential security exposure). Hence, LSB-complaint applications who wish
to use the pidofproc function in their init scripts must store the pid in
/var/run/basename.pid."
http://www.linuxbase.org/spec/gLSB/gLSB/iniscrptfunc.html
Well, this gives a PID but for start_daemon and the exit
status codes one needs to know whether a program is running or not.
This can be checked using one (or more) of the following procedures:
PIDFILE=$pidfile # -p $pidfile option
[ -z "$PIDFILE" ] PIDFILE=/var/run/$basename.pid
PIDS=`cat $PIDFILE`
Method A
foreach PID in PIDS: check -d /proc/$PID
Method B
foreach PID in PIDS: check /proc/$PID/exe -> $pathname
Method C
foreach PID in PIDS: check /proc/$PID/exe -> $pathname
foreach PID in PIDS: check /proc/$PID/exe -> $dirname
Method D
foreach PID in PIDS: check /proc/$PID/exe -> $pathname
foreach PID in PIDS: check /proc/$PID/cmdline <-> $pathname
foreach PID in PIDS: check /proc/$PID/exe -> $basename
foreach PID in PIDS: check /proc/$PID/cmdline <-> $basename
Method E, F, G, H
pidof $pathname # E, F, G, H
pidof $basename # F, G, H
pidof -x $pathname # G, H
pidof -x $basename # H
Currently used:
* start_daemon/killproc
SuSE: Method D
RedHat: Method A || E || F
Debian: Method E/F (depending whether pathname or basename has been given)
might use B/C in addition (documenation not 100% clear)
* pidofproc:
SuSE: Method D
RedHat: Method A || E || F
Debian: cat /var/run/$basename.pid || Method E/F
Observations:
- Some implementations look only at PIDs found in the pidfile while
others use in addition the complete /proc/ system
- Debian's pidofproc does not even check -d /proc/$PID
- If the daemon is a PERL (etc.) script, /proc/$PID/exe points to
/usr/bin/perl [1] and only /proc/$PID/cmdline contains the pathname.
Methods B, C, E and F yield therefore no PID.
Expected:
- All PIDs shown should have at least a associated /proc/$PID
(otherwise a "pidofproc $pathname > /dev/null" cannot be used for
"status".
- If /proc/$PID/exe is checked, also /proc/$PID/cmdline should be checked
This is needed for daemons written in script languages.
Note: If these checks are done using the complete /proc/*/ system this
also finds /usr/bin/vi $pathname which might not be neccessarily
desired. Therefore "pidof -x" should be used with care.
Suggested PID search algorithm (also known as very early version of a
specification):
- Complient applications have to write their PIDs into either
/var/run/$basename.pid or into the given (-p) pidfile (which should be
also in /var/run/*.pid) [No change to the gLSB spec]
- The pidofproc should return only those PIDs which have an associated
running process; i.e. either -d /proc/$PID, or
/proc/$PID/exe <-> $pathname/$basename _and_ /proc/$PID/cmdline <->
$pathname/$basename checking should be done.
- Complient implementations may use other mechanisms for determining the
pid(s) such as /proc/*/exe <-> $basename/$pathname.
(using /proc/*/cmdline <-> $basename/$pathname is not recommendated)
This would mean these changes for the current implementations:
- SuSE: none
- RedHat: none
- Debian: start_daemon/killproc: check also /proc/$PID/cmdline or use only /proc/$PID
pidofproc: Check /proc/$PID before printing the PIDs
- Others: ?
Comments?
Tobias
PS: See also bug 677744 "the behaviour of start_daemon is currently unclear"
http://sourceforge.net/tracker/index.php?func=detail&aid=677744&group_id=1107&atid=101107
[1] Since the LSB doesn't (yet) contain PERL, you may want to replace
/usr/bin/perl by /opt/lsb-zedv-perl/bin/perl in this example.
More information about the lsb-discuss
mailing list