Search code examples
pythondaemonpython-daemon

python-daemon context fails to start when a stale PID file is present


I'm using python-daemon, and having the problem that when I kill -9 a process, it leaves a pidfile behind (ok) and the next time I run my program it doesn't work unless I have already removed the pidfile by hand (not ok).

I catch all exceptions in order that context.close() is called before terminating -- when this happens (e.g. on a kill) the /var/run/mydaemon.pid* files are removed and a subsequent daemon run succeeds. However, when using SIGKILL (kill -9), I don't have the chance to call context.close(), and the /var/run files remain. In this instance, the next time I run my program it does not start successfully -- the original process returns, but the daemonized process blocks at context.open().

It seems like python-daemon ought to be noticing that there is a pidfile for a process that no longer exists, and clearing it out, but that isn't happening. Am I supposed to be doing this by hand?

Note: I'm not using with because this code runs on Python 2.4

from daemon import DaemonContext
from daemon.pidlockfile import PIDLockFile

context = DaemonContext(pidfile = PIDLockFile("/var/run/mydaemon.pid"))
context.open()

try:
    retry_main_loop()
except Exception, e:
    pass
context.close()

Solution

  • If you are running linux, and process level locks are acceptable, read on.

    We try to acquire the lock. If it fails, check if the lock is acquired by a running process. If no, break the lock and continue.

    from lockfile.pidlockfile import PIDLockFile
    from lockfile import AlreadyLocked
    
    pidfile = PIDLockFile("/var/run/mydaemon.pid", timeout=-1)
    try:
        pidfile.acquire()
    except AlreadyLocked:
        try:
            os.kill(pidfile.read_pid(), 0)
            print 'Process already running!'
            exit(1)
        except OSError:  #No process with locked PID
            pidfile.break_lock()
    
    #pidfile can now be used to create DaemonContext
    

    Edit: Looks like PIDLockFile is available only on lockfile >= 0.9