Hi Scott

On 4/9/21 12:16 PM, Scott Andrews wrote:

On 4/9/21 2:10 AM, Tim Tassonis wrote:
Hi Scott

On 4/9/21 2:40 AM, Scott Andrews wrote:
# Function:    pidofproc [-p pidfile] pathname
#   The pidofproc function shall return one or more process
#   identifiers for a particular daemon using the algorithm
#   given above. Only process identifiers of running
#   processes should be returned. Multiple process
#   identifiers shall be separated by a single space.
#   The pidofproc function shall return the LSB defined exit
#   status codes for "status". It shall return 0 if the
#   program is running and not 0 otherwise.
#
#   If the status action is requested, the init script will return
#   the following exit status codes.
#   0       program is running or service is OK
#   1       program is dead and /var/run pid file exists
#   2       program is dead and /var/lock lock file exists
#   3       program is not running
#   4       program or service status is unknown
#   5-99    reserved for future LSB use
#   100-149 reserved for distribution use
#   150-199 reserved for application use
#   200-254 reserved
function pidofproc {
     local pidfile=""
     local program=""
     local pid=""
     local pidlist=""
     local list=""
     local exitstatus=0
     # Process arguments
     while [[ $# -gt 0 ]]; do
         case "${1}" in
             -p) shift; pidfile="${1}" ;;
             *)    program="${1##*/}" ;;
         esac
         shift
     done
     # If a PID file is not specified, make one
     test -z "${pidfile}" && pidfile="/var/run/${program}.pid"
     # If a pid file exists and is readable, use it.
     if [[ -r "${pidfile}" ]]; then
         list=$(head -n1 "${pidfile}")
     else
         list=$(pidof "${program}")
         exitstatus=$?
         if [[ ${exitstatus} -gt 0 ]]; then exitstatus=4; fi
     fi
     if [[ exitstatus -eq 0 ]]; then
         # Figure out if all listed PIDs are running.
         for pid in ${list}; do
             if kill -0 "${pid}" 2> /dev/null; then
                 pidlist+="${pid} "
             else
                 exitstatus=1
             fi
         done
     fi
     if [[ -z "${pidlist}" ]]; then
         if [[ -f "${pidfile}" ]]; then
             exitstatus=1
         else
             exitstatus=3
         fi
     fi
     printf "%s" "${pidlist% }"
     return ${exitstatus}
}


Testing Function: pidofproc: Start
Testing pidofproc: valid program, no pidfile: running
     Returns pid and exit status of 0
     pidofproc /usr/sbin/dhcpcd: ---->:pid:[472] exit status:[0]
     pidofproc dhcpcd: ---->:pid:[472] exit status:[0]

Testing pidofproc: valid program, valid pidfile: running
     Returns pid and exit status of 0
     pidofproc -p /var/run/dhcpcd.pid /usr/sbin/dhcpcd: ---->:pid:[472] exit status:[0]      pidofproc /usr/sbin/dhcpcd -p /var/run/dhcpcd.pid: ---->:pid:[472] exit status:[0]      pidofproc -p /var/run/dhcpcd.pid dhcpcd: ---->:pid:[472] exit status:[0]      pidofproc dhcpcd -p /var/run/dhcpcd.pid: ---->: pid:[472] exit status:[0]

Testing pidofproc: invalid program, no pidfile
     Returns no pid and exit status of 3
     pidofproc /usr/sbin/barf: ---->: pid:[] exit status:[3]

Testing pidofproc: valid program, invalid pidfile: running
     Returns pid and exit status of 0
     pidofproc -p barf.pid /usr/sbin/dhcpcd: ---->: pid:[472] exit status:[0]      pidofproc /usr/sbin/dhcpcd -p barf.pid: ---->: pid:[472] exit status:[0]

Testing pidofproc: valid program, no pidfile: not running
     Returns no pid and exit status of 3
     pidofproc /bin/ls: ---->: pid:[] exit status:[3]

Testing pidofproc: valid program: valid pidfile: not running
     Returns no pid and exit status of 1

touch /var/run/ls.pid

     pidofproc /bin/ls: ---->: pid:[] exit status:[1]
     pidofproc -p /var/run/ls.pid /bin/ls: ---->: pid:[] exit status:[1]
rm /var/run/ls.pid


Looks great, tested it successfully with bash. Testing with busybox ash does not work, but naturally, this is not needed on an LFS system.


This script is not intended to run with ash, the she bang line is as follows

#!/bin/bash --posix


Fully agree.




I do have one question however:

Testing with invalid program and valid pidfile results in printing the pid and returning 0:

Test with vaild program and valid pidfile:


root@keegan:~# ./pidofproc -p /var/run/dhcpcd-eno1.pid /sbin/dhcpcd
3144root@keegan:~# echo $?
0

root@keegan:~# ./pidofproc -p /var/run/dhcpcd-eno1.pid /sbin/dhcpcf
3144root@keeganecho $?
0

In the second case, /sbin/dhcpcf does not exist, but the pidfile does, and belongs to /sbin/dhcpcd. Is this intended behaviour? Not that this really matters a lot in real-world, as the function certainly will not be called that way often.


It reads the pidfile and if the process is running with then

         for pid in ${list}; do
             if kill -0 "${pid}" 2> /dev/null;then
                 pidlist+="${pid} "
             else
                 exitstatus=1
             fi
         done

will return with an 0 exit status so yes it did return the correct status.

This function is not required to validate the parameters you passed to it, if you pass a pidfile from another process there really isn't a way to test for that.  See LSB-Core.

I really don't want to start a huge discussion about this, but I did write a test for that in certain scripts. The reason is that process id's can wrap during a kernel uptime, so the process might have ended abnormally, but the pid file contains a process id of another running process belonging to a totally different program.

Of course my solution is quite complicated: I call

ps --noheader -o cmd ${pid}

and compare this to the specified process name


So, my code would read:

if kill -0 "${pid}" 2> /dev/null;then
    pidexe="`ps --noheader -o comm "${pid}"| cut -f1 -d ' '`"
    if ! echo "${program}"|grep "$pidexe" >/dev/null; then
        exitstatus=1
    fi
else
    exitstatus=1
fi


Now, I won't really advocate for adding this, but it would solve the admittedly rare problem of wrapped process id's and killed services with pid files still there, containing process id's of another program.

Bye
Tim
--
http://lists.linuxfromscratch.org/listinfo/lfs-support
FAQ: http://www.linuxfromscratch.org/blfs/faq.html
Unsubscribe: See the above information page

Do not top post on this list.

A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing in e-mail?

http://en.wikipedia.org/wiki/Posting_style

Reply via email to