Skip to content

Instantly share code, notes, and snippets.

@fdr
Created July 31, 2012 00:32
Show Gist options
  • Save fdr/3212283 to your computer and use it in GitHub Desktop.
Save fdr/3212283 to your computer and use it in GitHub Desktop.
python port of postmaster pid file loop
#!/usr/bin/env python
import argparse
import collections
import daemon
import datetime
import errno
import os
import re
import subprocess
import sys
import time
def create_or_clean_pidfile(sentinel_path):
my_pid = os.getpid()
# adapted from misinit.c in postgresql
fd = None
# Retry lock-file cleanup/acquisition a large but finite number of
# times.
for i in xrange(100):
# Try to create a lockfile. If the lockfile is created
# successfully, write the current PID into it.
try:
fd = os.open(sentinel_path,
os.O_CREAT | os.O_EXCL | os.O_RDWR, 0600)
os.write(fd, str(my_pid) + '\n')
return True
except EnvironmentError as e:
if e.errno in (errno.EEXIST, errno.EACCES):
print >>sys.stderr, 'Sentinel file already exists.'
finally:
if fd is not None:
os.close(fd)
# Sentinel file was found to exist, so try reading it and
# seeing if it is stale or not.
try:
with open(sentinel_path, 'r') as f:
f.seek(0, os.SEEK_END)
if f.tell() > 8192:
raise Exception('Large (>8KB) pid file found; '
'that should not happen.')
f.seek(0, os.SEEK_SET)
pid = f.read(8192).split('\n')[0]
try:
os.kill(int(pid), 0)
raise Exception('Is another WAL-E running? pid={0}'
.format(pid))
except EnvironmentError as e:
if e.errno in (errno.ESRCH, errno.EPERM):
# No process found, unlink the file (aka
# cleanup). This is the case both if there is
# no pid in existence referenced by this
# pidfile, or if there is a permission
# problem, meaning an unrelated process from
# some other user has taken that pid (unless
# that other user is *also* running wal-e).
os.unlink(sentinel_path)
except EnvironmentError as e:
if e.errno == errno.ENOENT:
# File not found; this can happen in a race condition
# whereby another push-backup unlinks the sentinel
# file. Go ahead and try the entire sentinel file
# process again.
continue
raise Exception('Could not create, clean, nor confirm the liveness of '
'another WAL-E: giving up on retry-loop.')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment