[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


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

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

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

- 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.

- All PIDs shown should have at least a associated /proc/$PID
  (otherwise a "pidofproc $pathname > /dev/null" cannot be used for

- 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

- 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: ?



PS: See also bug 677744 "the behaviour of start_daemon is currently unclear"

[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