[bitbake-devel] [PATCH] prserv: SIGTERM and deamonization fixes

Richard Purdie richard.purdie at linuxfoundation.org
Tue Sep 8 22:32:07 UTC 2015


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 at linuxfoundation.org>

diff --git a/bitbake/lib/prserv/serv.py b/bitbake/lib/prserv/serv.py
index 0507485..07a5115 100644
--- a/bitbake/lib/prserv/serv.py
+++ b/bitbake/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,25 @@ 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")
+        print os.getppid()
+        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 +242,6 @@ class PRServer(SimpleXMLRPCServer):
 
         self.work_forever()
         self.delpid()
-        os._exit(0)
 
 class PRServSingleton(object):
     def __init__(self, dbfile, logfile, interface):
@@ -223,7 +252,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()
 





More information about the bitbake-devel mailing list