aboutsummaryrefslogtreecommitdiffstats
path: root/lib/prserv/serv.py
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2015-09-08 23:32:07 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2015-09-09 14:26:55 +0100
commit05d31fa1f56bd3d3d363a16a421d9ba7541d4293 (patch)
treed79694494c448be79d24dbcf0f7ac0627125f46c /lib/prserv/serv.py
parent34974f5e30e9b09c016481e4c81c156a5f379784 (diff)
downloadbitbake-05d31fa1f56bd3d3d363a16a421d9ba7541d4293.tar.gz
prserv: SIGTERM and deamonization fixes
Worryingly, if you SIGKILL the bitbake cooker, an autostarted PR server will remain behind. It turns out there are a few things we should do: * The PR service doesn't need to daemonize when started from cooker, it just complicated the process lifecycle. Add a fork() method to handle this and use the non-daemon mode for the singleton. * Reset the sigterm and sigint handlers. Bitbake cooker installs its own which we inherit meaning PR server was ignoring SIGTERM. Installing our own handlers which include a sync makes most sense here. Since we're in the code, make it sync the database on SIGINT. * Use the new bb.utils.signal_on_parent_exit() call so that we get a SIGTERM when the parent (usually cooker) exits and we can shutdown too. Alternatives would be having an open pipe or polling os.getppid() for changes but this seems more effective. Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'lib/prserv/serv.py')
-rw-r--r--lib/prserv/serv.py34
1 files changed, 31 insertions, 3 deletions
diff --git a/lib/prserv/serv.py b/lib/prserv/serv.py
index 05074854a..5c0ffb992 100644
--- a/lib/prserv/serv.py
+++ b/lib/prserv/serv.py
@@ -97,6 +97,13 @@ class PRServer(SimpleXMLRPCServer):
self.table.sync()
self.table.sync_if_dirty()
+ def sigint_handler(self, signum, stack):
+ self.table.sync()
+
+ def sigterm_handler(self, signum, stack):
+ self.table.sync()
+ raise SystemExit
+
def process_request(self, request, client_address):
self.requestqueue.put((request, client_address))
@@ -147,7 +154,11 @@ class PRServer(SimpleXMLRPCServer):
return
def start(self):
- pid = self.daemonize()
+ if self.daemon:
+ pid = self.daemonize()
+ else:
+ pid = self.fork()
+
# Ensure both the parent sees this and the child from the work_forever log entry above
logger.info("Started PRServer with DBfile: %s, IP: %s, PORT: %s, PID: %s" %
(self.dbfile, self.host, self.port, str(pid)))
@@ -180,6 +191,24 @@ class PRServer(SimpleXMLRPCServer):
except OSError as e:
raise Exception("%s [%d]" % (e.strerror, e.errno))
+ self.cleanup_handles()
+ os._exit(0)
+
+ def fork(self):
+ try:
+ pid = os.fork()
+ if pid > 0:
+ return pid
+ except OSError as e:
+ raise Exception("%s [%d]" % (e.strerror, e.errno))
+
+ bb.utils.signal_on_parent_exit("SIGTERM")
+ self.cleanup_handles()
+ os._exit(0)
+
+ def cleanup_handles(self):
+ signal.signal(signal.SIGINT, self.sigint_handler)
+ signal.signal(signal.SIGTERM, self.sigterm_handler)
os.umask(0)
os.chdir("/")
@@ -212,7 +241,6 @@ class PRServer(SimpleXMLRPCServer):
self.work_forever()
self.delpid()
- os._exit(0)
class PRServSingleton(object):
def __init__(self, dbfile, logfile, interface):
@@ -223,7 +251,7 @@ class PRServSingleton(object):
self.port = None
def start(self):
- self.prserv = PRServer(self.dbfile, self.logfile, self.interface)
+ self.prserv = PRServer(self.dbfile, self.logfile, self.interface, daemon=False)
self.prserv.start()
self.host, self.port = self.prserv.getinfo()