summaryrefslogtreecommitdiffstats
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:27:56 +0100
commit85256c8fa986f2a3258e75a22bb8d0656ffa41bf (patch)
treecb8626540c327fcd1c59c248ac8038a4a4b5b592
parent289007e5ebd82e7cf61a20c6afd0206e0037ce0d (diff)
downloadpoky-85256c8fa986f2a3258e75a22bb8d0656ffa41bf.tar.gz
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>
-rw-r--r--bitbake/lib/prserv/serv.py34
1 files changed, 31 insertions, 3 deletions
diff --git a/bitbake/lib/prserv/serv.py b/bitbake/lib/prserv/serv.py
index 05074854a2..5c0ffb9925 100644
--- a/bitbake/lib/prserv/serv.py
+++ b/bitbake/lib/prserv/serv.py
@@ -97,6 +97,13 @@ class PRServer(SimpleXMLRPCServer):
97 self.table.sync() 97 self.table.sync()
98 self.table.sync_if_dirty() 98 self.table.sync_if_dirty()
99 99
100 def sigint_handler(self, signum, stack):
101 self.table.sync()
102
103 def sigterm_handler(self, signum, stack):
104 self.table.sync()
105 raise SystemExit
106
100 def process_request(self, request, client_address): 107 def process_request(self, request, client_address):
101 self.requestqueue.put((request, client_address)) 108 self.requestqueue.put((request, client_address))
102 109
@@ -147,7 +154,11 @@ class PRServer(SimpleXMLRPCServer):
147 return 154 return
148 155
149 def start(self): 156 def start(self):
150 pid = self.daemonize() 157 if self.daemon:
158 pid = self.daemonize()
159 else:
160 pid = self.fork()
161
151 # Ensure both the parent sees this and the child from the work_forever log entry above 162 # Ensure both the parent sees this and the child from the work_forever log entry above
152 logger.info("Started PRServer with DBfile: %s, IP: %s, PORT: %s, PID: %s" % 163 logger.info("Started PRServer with DBfile: %s, IP: %s, PORT: %s, PID: %s" %
153 (self.dbfile, self.host, self.port, str(pid))) 164 (self.dbfile, self.host, self.port, str(pid)))
@@ -180,6 +191,24 @@ class PRServer(SimpleXMLRPCServer):
180 except OSError as e: 191 except OSError as e:
181 raise Exception("%s [%d]" % (e.strerror, e.errno)) 192 raise Exception("%s [%d]" % (e.strerror, e.errno))
182 193
194 self.cleanup_handles()
195 os._exit(0)
196
197 def fork(self):
198 try:
199 pid = os.fork()
200 if pid > 0:
201 return pid
202 except OSError as e:
203 raise Exception("%s [%d]" % (e.strerror, e.errno))
204
205 bb.utils.signal_on_parent_exit("SIGTERM")
206 self.cleanup_handles()
207 os._exit(0)
208
209 def cleanup_handles(self):
210 signal.signal(signal.SIGINT, self.sigint_handler)
211 signal.signal(signal.SIGTERM, self.sigterm_handler)
183 os.umask(0) 212 os.umask(0)
184 os.chdir("/") 213 os.chdir("/")
185 214
@@ -212,7 +241,6 @@ class PRServer(SimpleXMLRPCServer):
212 241
213 self.work_forever() 242 self.work_forever()
214 self.delpid() 243 self.delpid()
215 os._exit(0)
216 244
217class PRServSingleton(object): 245class PRServSingleton(object):
218 def __init__(self, dbfile, logfile, interface): 246 def __init__(self, dbfile, logfile, interface):
@@ -223,7 +251,7 @@ class PRServSingleton(object):
223 self.port = None 251 self.port = None
224 252
225 def start(self): 253 def start(self):
226 self.prserv = PRServer(self.dbfile, self.logfile, self.interface) 254 self.prserv = PRServer(self.dbfile, self.logfile, self.interface, daemon=False)
227 self.prserv.start() 255 self.prserv.start()
228 self.host, self.port = self.prserv.getinfo() 256 self.host, self.port = self.prserv.getinfo()
229 257