From f2f361de62d3c2a9d8515549d04f41f5fdac74bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sergiusz=20Baza=C5=84ski?= Date: Mon, 8 Apr 2013 12:05:06 +0200 Subject: [PATCH] Simple bouncing code. --- adsl.py | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ bouncer.py | 68 ++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 128 insertions(+), 9 deletions(-) create mode 100644 adsl.py diff --git a/adsl.py b/adsl.py new file mode 100644 index 0000000..213608f --- /dev/null +++ b/adsl.py @@ -0,0 +1,69 @@ +import os +import time +import sys +import subprocess + + +def _get_process_list(): + pids = [int(pid) for pid in os.listdir('/proc') if pid.isdigit()] + processes = [] + for pid in pids: + f = open("/proc/%i/cmdline" % pid, "r") + processes.append(f.read()) + f.close() + return zip(pids, processes) + + +def _start_pppd(): + p = subprocess.Popen(["/usr/sbin/pppd", "call", "neozdrada"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + if p.returncode != 0: + sys.stderr.write("Could not run pppd succesfully! Here is some debug data:\n") + sys.stderr.write(" STDOUT: %s\n" % stdout) + sys.stderr.write(" STDERR: %s\n" % stderr) + else: + sys.stdout.write("PPPd started succesfully.\n") + + +def _get_pppd_pid(): + for process, pid in _get_process_list(): + if process.startswith("pppd"): + return pid + + +def _kill_pppd(): + pid = _get_pppd_pid() + if pid: + os.kill(pid, 9) + sys.stdout.write("Killed PPPd.\n") + + +def _check_connectivity(): + p = subprocess.Popen(["/sbin/ping", "-W", "4", "-c", "1", "8.8.8.8"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p.communicate() + if p.returncode != 0: + sys.stderr.write("There seem to be some connectivity problems... Waiting 15 seconds, then giving it another shot...\n") + time.sleep(15) + + p = subprocess.Popen(["/sbin/ping", "-W", "4", "-c", "1", "8.8.8.8"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p.communicate() + if p.returncode != 0: + sys.stderr.write("Connectivity problems persisting! :(\n") + return False + else: + sys.stderr.write("Seems to be okay now.\n") + return True + + +def loop(): + while True: + pppd_pid = _get_pppd_pid() + if not pppd_pid: + _start_pppd() + time.sleep(60) + else: + if not _check_connectivity(): + sys.stderr.write("Restarting PPPd.\n") + _kill_pppd() + _start_pppd() + time.sleep(60) diff --git a/bouncer.py b/bouncer.py index 4392765..3a97f58 100644 --- a/bouncer.py +++ b/bouncer.py @@ -3,7 +3,9 @@ import os import time import sys -import subprocess +import argparse + +import adsl def doublefork(pidfile, logfile): @@ -21,7 +23,7 @@ def doublefork(pidfile, logfile): if pid == 0: # we are the first child - os.setsid() + #os.setsid() try: pid = os.fork() except OSError as e: @@ -42,12 +44,60 @@ def doublefork(pidfile, logfile): pid.write("%i" % os.getpid()) pid.close() - stdout = os.open(logfile, os.O_CREAT | os.O_WRONLY | os.O_APPEND) - os.dup2(stdout, sys.stdout.fileno()) - os.dup2(stdout, sys.stderr.fileno()) + class Unbuffered: + def __init__(self, stream): + self.stream = stream + + def write(self, data): + self.stream.write(data) + self.stream.flush() + + def __getattr__(self, attr): + return getattr(self.stream, attr) + + # redirect stdout and stderr to file - for subprocesses and whatever + f = os.open(logfile, os.O_APPEND | os.O_NDELAY | os.O_WRONLY) + os.dup2(f, sys.stdout.fileno()) + os.dup2(f, sys.stderr.fileno()) + + # python workaround - make stdout unbuffered + sys.stdout = Unbuffered(sys.stdout) + return True -doublefork("/tmp/pid", "/tmp/log") -while True: - time.sleep(2) - print "cocks" +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Make sure the ADSL network is up and display info on the FWA fron panel.") + parser.add_argument("--pidfile", default="/var/run/adsl-bouncer.pid", help="Path of file to write dameon PID to.") + parser.add_argument("--logfile", default="/var/log/adsl-bouncer.log", help="Path of log file.") + + args = parser.parse_args() + # see if daemon is already running + if os.path.exists(args.pidfile): + with open(args.pidfile, "r") as f: + try: + pid = int(f.read()) + except: + pass + else: + try: + os.kill(pid, 0) + except OSError: + pass + else: + # daemon is running + raise Exception("Daemon is already running on PID %i!" % pid) + # try to open logfile + try: + f = open(args.logfile, "aw") + f.write("Daemon starting...\n") + f.close() + except IOError as e: + raise Exception("Could not open logfile %s! %s" % (args.logfile, str(e))) + + if not doublefork(args.pidfile, args.logfile): + raise Exception("Could not doublefork! See logfile for details.") + + sys.stderr.write("Daemon running! PID %i.\n" % os.getpid()) + while True: + adsl.check() + time.sleep(60)