class AcquireRunLock(object): """ Establishes a lockfile to avoid duplicate runs for same config. """ def __init__(self, pidfile): """ Create exclusive app lock """ if pidfile.startswith("/"): piddir = os.path.dirname(pidfile) pidpath = pidfile # use explicit path else: piddir = "/var/lib/zabbixsrv/" pidpath = "{dir}{file}".format(dir=piddir, file=pidfile) # Check lockdir exists if not os.path.exists(piddir): raise PidlockConflict("directory {0} is missing or insufficient permission".format( piddir ) ) # Check for orphaned pids if os.path.isfile(pidpath): with open(pidpath) as f: conflictpid = f.read() raise PidlockConflict("process {0} has lock in {1}".format( conflictpid.strip(), pidpath ) ) # Acquire lock self.pidfile = PIDLockFile(pidpath) self.locked = False if not self.pidfile.is_locked(): self.pidfile.acquire() self.locked = True def release(self): """ Releases exclusive lock """ if self.pidfile.is_locked(): self.locked = False return self.pidfile.release() def islocked(self): """ Return true if exclusively locked """ return self.pidfile.is_locked()
def acquire_pidlock(pidfile): """Get the :class:`daemon.pidlockfile.PIDLockFile` handler for ``pidfile``. If the ``pidfile`` already exists, but the process is not running the ``pidfile`` will be removed, a ``"stale pidfile"`` message is emitted and execution continues as normally. However, if the process is still running the program will exit complaning that the program is already running in the background somewhere. """ from daemon.pidlockfile import PIDLockFile import errno pidlock = PIDLockFile(pidfile) if not pidlock.is_locked(): return pidlock pid = pidlock.read_pid() try: os.kill(pid, 0) except os.error, exc: if exc.errno == errno.ESRCH: sys.stderr.write("Stale pidfile exists. Removing it.\n") os.unlink(pidfile) return PIDLockFile(pidfile)