From f54ddd0bc9a4d9a22e6f7a060fe76aa10f41eb4f Mon Sep 17 00:00:00 2001 From: Andreas Wrede Date: Fri, 4 Sep 2015 15:52:16 -0400 Subject: [PATCH] use daemon and PIDLock --- hbc | 130 +++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 71 insertions(+), 59 deletions(-) diff --git a/hbc b/hbc index dacffab..0378f59 100755 --- a/hbc +++ b/hbc @@ -1,9 +1,13 @@ #!/usr/bin/env python # $Id: hbc,v 1.9 2012/03/29 02:08:36 andreas Exp $ -# requre python-filelock on Linux -# require py27-lockfile on *bsd -# or run sudo easy_install-2.7 lockfile +# require on Linux +# python-filelock +# 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 time import socket @@ -14,24 +18,29 @@ import string import select import errno import traceback -from lockfile import FileLock +import lockfile +import daemon +import daemon.pidfile +import syslog + PORT=50003 INTERVAL=10 DBG = True -sock=None +sock = None +up = True +ackcount = 0 class NullDevice: def write(self, s): pass -def handler(signum, frame): - global up - if up == 0: - return - sys.exit(0) +def syslogtrace(note): + logm = '%s hbc died: \n%s' % (note, traceback.format_exc()) + for l in logm.split('\n'): + syslog.syslog(' tb: %s' % l) def getsock(host): @@ -46,35 +55,43 @@ def getsock(host): else: return None if verbose: - print "socktype: %s" % af_type + syslog.syslog("socktype: %s" % af_type) sock=socket.socket(af_type, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR, \ 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 + def socksend(msg, tohost): global sock if sock == None: sock=getsock(tohost[0]) sock.sendto(msg, tohost) - if verbose: print "msg %s sent" % msg + if verbose: syslog.syslog("msg %s sent" % msg) + def process(): + global up, sock, ackcount + + if sock == None: + sock=getsock(tohost[0]) + ackcount=0 lastT=time.time() while up: sleep=(lastT+interval) - time.time() - if verbose: print "sleep %s" % sleep + if verbose: syslog.syslog("sleep %s" % sleep) if sleep > 0: try: r=select.select([sock.fileno()],[],[],sleep) - # time.sleep(interval) except: + if up: + syslogtrace('select') break - if verbose: print r + if verbose: syslog.syslog("r is %s" % str(r)) if sock.fileno() in r[0]: data, addr = sock.recvfrom(1024) if data == "ACK": @@ -83,22 +100,35 @@ def process(): try: os.system(data) except: + syslogtrace('System') pass continue lastT=time.time() for hb_host in hb_hosts: try: 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)) except: 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 helpflag=False verbose=False -daemon=False +fdaemon=False optlist=[] args=[] msgboot=[] @@ -116,7 +146,7 @@ for o,a in optlist: elif o == '-c': configfile=a elif o == '-d': - daemon=True + fdaemon=True elif o == '-h': helpflag=True elif o == '-m': @@ -228,47 +258,29 @@ if msgonly: # # -if daemon: - pid=os.fork() - if pid > 0: - if verbose: - print "daemoinizing... pid=%d" % pid - sys.exit(0) +syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_DAEMON) +if fdaemon: + print "daemoinizing... %s" % os.getpid() + context = daemon.DaemonContext( + working_directory='/tmp', + umask=0o002, + pidfile=daemon.pidfile.TimeoutPIDLockFile('/tmp/hbc.pid', acquire_timeout=-1), + ) - if not DBG: - os.close(0) - os.close(1) - os.close(2) - sys.stdin.close() - sys.stdout = NullDevice() - sys.stderr = NullDevice() - os.chdir("/") - os.setsid() - os.umask(0) + context.signal_map = { + signal.SIGTERM: cleanup, + signal.SIGHUP: 'terminate', +# signal.SIGUSR1: reload_program_config, + } + context.files_preserve = [sock, sock.fileno()] + with context: + syslog.syslog('starting heartbeat to %s' % ','.join(hb_hosts)) + up = True + try: + process() + except: + syslogtrace('process') + cleanup(0, None) -lock = FileLock('/tmp/hbc.pid') -lock.acquire() - -up=1 -signal.signal(signal.SIGTERM, handler) -signal.signal(signal.SIGHUP, handler) - - - -try: - process() -except: - data='hbc died:\n'+traceback.format_exc() - open("/tmp/hbc.log","a").write(data) - 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()