Created
July 31, 2012 00:32
-
-
Save fdr/3212283 to your computer and use it in GitHub Desktop.
python port of postmaster pid file loop
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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