LSB initscripts: Problems with determining whether a process is running

Tobias Burnus <[email protected]>
Newsgroups gmane.linux.lsb.discuss
Message-ID <[email protected]>
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.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.