pidofproc or pidof working from init.d but not from /usr/sbin
1
vote
0
answers
817
views
I have a Linux service I'm supporting. It offers the usual
start
and stop
commands. The designer created a wrapper command that is meant to control startup and retries of the main function. The wrapper includes a preliminary check to see if it is already running by calling pidofproc
on itself. The start and stop functions also use this for checking.
What I'm finding is that the start and stop functions in the init.d program have no problem using pidofproc after calling . /etc/init.d/functions
but the wrapper fails doing what appears to me to be the same thing.
I noticed a few things wrong with the original wrapper. Initially it wasn't invoking functions
. Then it wasn't testing the return value as a string correctly. I also noticed that the service script is a bash script and the wrapper was a shell, so I switched it to bash. None of those helped.
I created a MCVE of the problem. It seems to behave much like the real code, although the wrapper is just doing a useless while loop to remain running. The problem is that if you run myprog
when there is already an instance running, the trace clearly shows that the __pids_pidof
function in functions fails to get a return value from pidof
, while the start and stop scripts work fine.
What's the difference?
Wrapper script example /usr/sbin/safe_myprog:
#!/bin/bash
set -x
PROG_NAME=myprog
INSTALL_DIR=/var/www/${PROG_NAME}
PROG=${INSTALL_DIR}/bin/${PROG_NAME}
SAFE_PROG_NAME=safe_myprog
SAFE_MYPROG=/usr/sbin/${SAFE_PROG_NAME}
message() {
# echo "$1" >&2
logger -t safe_myprog[$$] "$1"
}
. /etc/init.d/functions
safe_myprog=pidofproc $SAFE_MYPROG
if [ -n "$safe_myprog" ]; then
if [ -n "$(ps -p $safe_myprog -o pid=)" ]; then
message "$SAFE_PROG_NAME: is already running. pid: $safe_myprog"
exit 0
fi
fi
while :; do
sleep 60
done
Service program /etc/init.d/myprog:
#!/bin/bash
set -x
# Source function library.
. /etc/init.d/functions
cd /
PROG_NAME=myprog
INSTALL_DIR=/var/www/${PROG_NAME}
SAFE_PROG_NAME=safe_myprog
SAFE_MYPROG=/usr/sbin/${SAFE_PROG_NAME}
PROG=${INSTALL_DIR}/bin/${PROG_NAME}
PROG_LOCK_FILE=/var/lock/subsys/${PROG_NAME}
PROG_PID_FILE=/var/lib/${PROG_NAME}/${PROG_NAME}.pid
RETVAL=0
txtgrn=$(tput setaf 2)
txtred=$(tput setaf 1)
txtrst=$(tput sgr0)
message() {
if [ $RETVAL -eq 0 ]; then
printf "%-45s[${txtgrn} OK ${txtrst}]\n" "$1"
else
printf "%-45s[${txtred}FAILED${txtrst}]\n" "$1"
fi
}
start() {
safe_myprog=pidofproc $SAFE_MYPROG
if [ -n "${safe_myprog}" ]; then
message $"$SAFE_PROG_NAME: is already running. pid: $safe_myprog"
return 0
fi
#$SAFE_MYPROG > /dev/null 2>&1
$SAFE_MYPROG &
RETVAL=$?
message $"Starting $PROG_NAME: "
if [ $RETVAL -eq 0 ]; then
touch $PROG_LOCK_FILE
fi
return $RETVAL
}
stop() {
safe_myprog=pidofproc $SAFE_MYPROG
if [ -n "${safe_myprog}" ]; then
/bin/kill $safe_myprog
fi
if [ -e $PROG_PID_FILE ]; then
pid=$(cat $PROG_PID_FILE)
if [ -n "$(ps -p $pid -o pid=)" ]; then
/bin/kill -9 "$pid"
RETVAL=$?
#if [ $# -eq 0 ]; then
message "Stopping $PROG_NAME: pid: $pid"
#fi
else
#if [ $# -eq 0 ]; then
message "$PROG_NAME is already stopped."
#fi
/bin/rm -f $PROG_PID_FILE
RETVAL=0
fi
fi
if [ -f $PROG_PID_FILE ]; then
/bin/rm -f $PROG_PID_FILE
fi
if [ -e $PROG_LOCK_FILE ]; then
/bin/rm -f $PROG_LOCK_FILE
fi
return $RETVAL
}
case "$1" in
start)
start
;;
stop)
stop
;;
esac
exit $RETVAL
If I do a service myprog start
twice and then run safe_myprog directly
the key part of the trace output from safe_myprog is:
++ __pids_pidof /usr/sbin/safe_myprog
++ pidof -c -m -o 14454 -o 30619 -o %PPID -x /usr/sbin/safe_myprog
++ pidof -c -m -o 14454 -o 30619 -o %PPID -x safe_myprog
++ return 3
+ safe_myprog=
+ '[' -n '' ']'
While the second call to start gave this output from what seems to be the same function call:
++ __pids_pidof /usr/sbin/safe_myprog
++ pidof -c -m -o 14406 -o 14399 -o %PPID -x /usr/sbin/safe_myprog
+ safe_myprog=14339
+ '[' -n 14339 ']'
+ message 'safe_myprog: is already running. pid: 14339'
If I run pidof -c -m -o 14454 -o 30619 -o %PPID -x /usr/sbin/safe_myprog
on the command line (after executing functions
) it provides the correct answer.
What is different about the wrapper shell using the pidofproc
function compared to the init.d shell using it, and specifically why is pidof
seeming to give different answers?
Asked by Sinc
(193 rep)
Jul 3, 2019, 08:24 PM
Last activity: Jul 5, 2019, 03:47 PM
Last activity: Jul 5, 2019, 03:47 PM