diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-09-08 23:32:07 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2015-09-09 14:26:55 +0100 |
commit | 05d31fa1f56bd3d3d363a16a421d9ba7541d4293 (patch) | |
tree | d79694494c448be79d24dbcf0f7ac0627125f46c /lib/prserv | |
parent | 34974f5e30e9b09c016481e4c81c156a5f379784 (diff) | |
download | bitbake-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')
-rw-r--r-- | lib/prserv/serv.py | 34 |
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() |