bitbake: 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.

(Bitbake rev: 05d31fa1f56bd3d3d363a16a421d9ba7541d4293)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Richard Purdie 2015-09-08 23:32:07 +01:00
parent 289007e5eb
commit 85256c8fa9
1 changed files with 31 additions and 3 deletions

View File

@ -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()