0

I'm starting a Python script that I've created using start-stop-daemon. It works perfectly in all cases, except when I've forgotten that I've already started it. It creates a new process, but is unable to kill the old processes automatically.

Here's the complete script:

PYTHONPATH=/usr/lib/python2.4

# path to app
APP_PATH=/var/spool/EARS

# path to paster bin
DAEMON=/var/spool/EARS/pymilter_test8.py

# startup args
#DAEMON_OPTS=" serve --log-file <my logfile> --server-name=main production.ini"

# script name
NAME=EARS_milter.sh

# app name
DESC='EARS_milter'

# pylons user
RUN_AS=postfix

PID_FILE=/var/run/milter.pid

############### END EDIT ME ##################

test -x $DAEMON || exit 0

set -e

case "$1" in
  start)
        echo -n "Starting $DESC: "
    start-stop-daemon -d $APP_PATH -c $RUN_AS --start --background --pidfile $PID_FILE  --make-pidfile --exec $DAEMON -- $DAEMON_OPTS
        echo "$NAME."
        ;;
  stop)
        echo -n "Stopping $DESC: "
        start-stop-daemon --stop --pidfile $PID_FILE
        echo "$NAME."
        ;;

  restart|force-reload)
        echo -n "Restarting $DESC: "
        start-stop-daemon --stop --pidfile $PID_FILE
        sleep 1
        start-stop-daemon -d $APP_PATH -c $RUN_AS --start --background --pidfile $PID_FILE  --make-pidfile --exec $DAEMON -- $DAEMON_OPTS
        echo "$NAME."
        ;;
  *)
        N=/etc/init.d/$NAME
        echo "Usage: $N {start|stop|restart|force-reload}" >&2
        exit 1
        ;;
esac

exit 0

Is there a way to have it check? I've tried the -S switch with no luck so far.

Thanks.

jeteon
  • 160
  • 8
  • Can you post the complete command? – Khaled Dec 05 '11 at 20:38
  • done. i'm thinking of adding in error-checking outside of start-stop-daemon, but it'd be great if it knew on its own. – Larry G. Wapnitsky Dec 05 '11 at 20:55
  • I wound up adding a bit of code to the script that checks for running processes with pymilter_test8.py (or whatever I rename it to eventually) via ps and grep prior to starting the daemon. If the processes exist, the service does not attempt to start. – Larry G. Wapnitsky Dec 06 '11 at 12:42
  • What user were you executing the above script as? Also, did the process appear in the process table under the PID in the file? I've had instances where this wasn't the case because the program I was running also did a fork of its own. – jeteon May 18 '16 at 12:58

3 Answers3

1

$PID_FILE will contain the process id only of the latest instance you started, so only this instance will be killed.

Something you could do to resolve this, is to grep the PIDs of the running instances of your daemon and terminate them using kill.

...or just check if there's another running instance of your script, before calling start-stop-daemon.

What is being spawned and ran is the Python interpreter, but start-stop-daemon checks for a process named pymilter_test8.py and obviously can't find it.

dkaragasidis
  • 745
  • 4
  • 11
1

I had an issue recently when I was starting a database server (Crate) using start-stop-daemon. The database was started with a bash script that then started java in a separate process. This was a problem because the actual server was always listed under the second PID. When I made the server itself create the PID file, I found that start-stop-daemon would still not recognize that the server was already running when I used the --pidfile argument. However, when I used --startas instead of --exec for the starting call, it seemed to resolve things for me and start-stop-daemon was able to manage the server process properly again.

You have to make sure that at the least, the PID file is correct as a forking server like I had would use a different running PID than that of the process that starts it. Whilst you're debugging, using the -t flag is helpful as you can manually run the start-stop-daemon commands in each case and monitor what it would do.

jeteon
  • 160
  • 8
0

You could use a lock file in /var/lock. Have the daemon check for a lock file before it starts, and fail with an error if the lock file exists. If it didn't fail, it would then create the lock file. That way two instances couldn't be running at the same time.

The only problem would be that if it crashes without having the ability to clean up its mess, you'd have to manually delete the lock file. Not a huge problem. The lock file location should be in the error message created when it fails to start.

In the start case, you'd put something like this:

if [ -f /var/lock/filename.lck ]; then
    echo "Lock file already present at /var/lock/filename.lck. Aborting"
    exit 1
else
    touch /var/lock/filename.lck
fi

And then in the stop case, something like this:

if [ -f /var/lock/filename.lck ]; then
    rm /var/lock/filename.lck
fi

It involves editing beyond the normal config editing section, but it should work.

dogoncouch
  • 176
  • 5