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