use daemon and PIDLock

This commit is contained in:
2015-09-04 15:52:16 -04:00
parent 7355e40671
commit f54ddd0bc9
+70 -58
View File
@@ -1,9 +1,13 @@
#!/usr/bin/env python #!/usr/bin/env python
# $Id: hbc,v 1.9 2012/03/29 02:08:36 andreas Exp $ # $Id: hbc,v 1.9 2012/03/29 02:08:36 andreas Exp $
# requre python-filelock on Linux # require on Linux
# require py27-lockfile on *bsd # python-filelock
# or run sudo easy_install-2.7 lockfile # python-daemon vs 1.61 or >
# on *bsd
# py27-lockfile
# py-27-daemon
# or run sudo easy_install-2.7 lockfile daemon
import sys import sys
import time import time
import socket import socket
@@ -14,24 +18,29 @@ import string
import select import select
import errno import errno
import traceback import traceback
from lockfile import FileLock import lockfile
import daemon
import daemon.pidfile
import syslog
PORT=50003 PORT=50003
INTERVAL=10 INTERVAL=10
DBG = True DBG = True
sock=None sock = None
up = True
ackcount = 0
class NullDevice: class NullDevice:
def write(self, s): def write(self, s):
pass pass
def handler(signum, frame): def syslogtrace(note):
global up logm = '%s hbc died: \n%s' % (note, traceback.format_exc())
if up == 0: for l in logm.split('\n'):
return syslog.syslog(' tb: %s' % l)
sys.exit(0)
def getsock(host): def getsock(host):
@@ -46,35 +55,43 @@ def getsock(host):
else: else:
return None return None
if verbose: if verbose:
print "socktype: %s" % af_type syslog.syslog("socktype: %s" % af_type)
sock=socket.socket(af_type, socket.SOCK_DGRAM) sock=socket.socket(af_type, socket.SOCK_DGRAM)
sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, \ sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, \
sock.getsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR) | 1) sock.getsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR) | 1)
if verbose: print "get socket %s" % sock if verbose: syslog.syslog("get socket %s" % sock)
return sock return sock
def socksend(msg, tohost): def socksend(msg, tohost):
global sock global sock
if sock == None: if sock == None:
sock=getsock(tohost[0]) sock=getsock(tohost[0])
sock.sendto(msg, tohost) sock.sendto(msg, tohost)
if verbose: print "msg %s sent" % msg if verbose: syslog.syslog("msg %s sent" % msg)
def process(): def process():
global up, sock, ackcount
if sock == None:
sock=getsock(tohost[0])
ackcount=0 ackcount=0
lastT=time.time() lastT=time.time()
while up: while up:
sleep=(lastT+interval) - time.time() sleep=(lastT+interval) - time.time()
if verbose: print "sleep %s" % sleep if verbose: syslog.syslog("sleep %s" % sleep)
if sleep > 0: if sleep > 0:
try: try:
r=select.select([sock.fileno()],[],[],sleep) r=select.select([sock.fileno()],[],[],sleep)
# time.sleep(interval)
except: except:
if up:
syslogtrace('select')
break break
if verbose: print r if verbose: syslog.syslog("r is %s" % str(r))
if sock.fileno() in r[0]: if sock.fileno() in r[0]:
data, addr = sock.recvfrom(1024) data, addr = sock.recvfrom(1024)
if data == "ACK": if data == "ACK":
@@ -83,22 +100,35 @@ def process():
try: try:
os.system(data) os.system(data)
except: except:
syslogtrace('System')
pass pass
continue continue
lastT=time.time() lastT=time.time()
for hb_host in hb_hosts: for hb_host in hb_hosts:
try: try:
msg="interval=%s;name=%s;time=%s;acks=%s" % (interval, iam, time.time(), ackcount) msg="interval=%s;name=%s;time=%s;acks=%s" % (interval, iam, time.time(), ackcount)
if verbose: print "sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port) if verbose: syslog.syslog("sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port))
socksend(msg, (hb_host, hb_port)) socksend(msg, (hb_host, hb_port))
except: except:
pass pass
def cleanup(a, b):
global up, sock, ackcount
up = False
syslog.syslog('exit a=%s b=%s' % (str(a), str(b)))
msg="shutdown=1;name=%s;acks=%s" % (iam, ackcount)
for hb_host in hb_hosts:
if verbose: syslog.syslog("hbc: sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port))
socksend(msg, (hb_host, hb_port))
time.sleep(1)
sock.close()
msgonly=False msgonly=False
helpflag=False helpflag=False
verbose=False verbose=False
daemon=False fdaemon=False
optlist=[] optlist=[]
args=[] args=[]
msgboot=[] msgboot=[]
@@ -116,7 +146,7 @@ for o,a in optlist:
elif o == '-c': elif o == '-c':
configfile=a configfile=a
elif o == '-d': elif o == '-d':
daemon=True fdaemon=True
elif o == '-h': elif o == '-h':
helpflag=True helpflag=True
elif o == '-m': elif o == '-m':
@@ -228,47 +258,29 @@ if msgonly:
# #
# #
if daemon: syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_DAEMON)
pid=os.fork() if fdaemon:
if pid > 0: print "daemoinizing... %s" % os.getpid()
if verbose:
print "daemoinizing... pid=%d" % pid
sys.exit(0)
context = daemon.DaemonContext(
working_directory='/tmp',
umask=0o002,
pidfile=daemon.pidfile.TimeoutPIDLockFile('/tmp/hbc.pid', acquire_timeout=-1),
)
if not DBG: context.signal_map = {
os.close(0) signal.SIGTERM: cleanup,
os.close(1) signal.SIGHUP: 'terminate',
os.close(2) # signal.SIGUSR1: reload_program_config,
sys.stdin.close() }
sys.stdout = NullDevice()
sys.stderr = NullDevice()
os.chdir("/")
os.setsid()
os.umask(0)
context.files_preserve = [sock, sock.fileno()]
lock = FileLock('/tmp/hbc.pid') with context:
lock.acquire() syslog.syslog('starting heartbeat to %s' % ','.join(hb_hosts))
up = True
up=1 try:
signal.signal(signal.SIGTERM, handler)
signal.signal(signal.SIGHUP, handler)
try:
process() process()
except: except:
data='hbc died:\n'+traceback.format_exc() syslogtrace('process')
open("/tmp/hbc.log","a").write(data) cleanup(0, None)
sys.exit(1)
up=0
msg="shutdown=1;name=%s;acks=%s" % (iam, ackcount)
for hb_host in hb_hosts:
if verbose: print "hbc: sock.send('%s', (%s, %s))" % (msg, hb_host, hb_port)
socksend(msg, (hb_host, hb_port))
time.sleep(1)
sock.close()
lock.release()