diff options
author | Richard Purdie <richard.purdie@linuxfoundation.org> | 2020-07-12 21:29:00 +0100 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2020-07-13 12:53:22 +0100 |
commit | b0e2e954f226c5cd0e7b6645f4fd43913870da93 (patch) | |
tree | 7f041d422cfee43840ca483ed10c3ce29ff7223c /bitbake | |
parent | 71772fbaea840da03835782b8602613895cf02ce (diff) | |
download | poky-b0e2e954f226c5cd0e7b6645f4fd43913870da93.tar.gz |
bitbake: server/process: Ensure UI-less servers don't sit in infinite loops
If server startup is broken for some reason (e.g. lockfile issues)
and no UI connection is made, the server will just sit inifinitely
waiting.
Add a timeout upon startup in the non-memory resident case so that
such infinite waits are avoided. In the memory resident case, the
server wouldn't have shut down in the first place or will timeout
according to configuration.
Since any race may mean the socket file is no longer present, ensure
the unlink doesn't fault upon exit, thus ensuring any hashequiv or
PRServ is removed from memory, allowing all processes to exit
cleanly in such scenarios.
(Bitbake rev: 39888b750df12478e8bdea6727cca112dce1df85)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r-- | bitbake/lib/bb/server/process.py | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/bitbake/lib/bb/server/process.py b/bitbake/lib/bb/server/process.py index 475931a728..d4beac4379 100644 --- a/bitbake/lib/bb/server/process.py +++ b/bitbake/lib/bb/server/process.py | |||
@@ -48,7 +48,7 @@ class ProcessServer(multiprocessing.Process): | |||
48 | 48 | ||
49 | self.event_handle = None | 49 | self.event_handle = None |
50 | self.haveui = False | 50 | self.haveui = False |
51 | self.lastui = False | 51 | self.maxuiwait = 30 |
52 | self.xmlrpc = False | 52 | self.xmlrpc = False |
53 | 53 | ||
54 | self._idlefuns = {} | 54 | self._idlefuns = {} |
@@ -155,6 +155,7 @@ class ProcessServer(multiprocessing.Process): | |||
155 | print("No timeout, exiting.") | 155 | print("No timeout, exiting.") |
156 | self.quit = True | 156 | self.quit = True |
157 | 157 | ||
158 | self.lastui = time.time() | ||
158 | while not self.quit: | 159 | while not self.quit: |
159 | if self.sock in ready: | 160 | if self.sock in ready: |
160 | while select.select([self.sock],[],[],0)[0]: | 161 | while select.select([self.sock],[],[],0)[0]: |
@@ -191,11 +192,18 @@ class ProcessServer(multiprocessing.Process): | |||
191 | except (EOFError, OSError): | 192 | except (EOFError, OSError): |
192 | disconnect_client(self, fds) | 193 | disconnect_client(self, fds) |
193 | 194 | ||
194 | if not self.timeout == -1.0 and not self.haveui and self.lastui and self.timeout and \ | 195 | if not self.timeout == -1.0 and not self.haveui and self.timeout and \ |
195 | (self.lastui + self.timeout) < time.time(): | 196 | (self.lastui + self.timeout) < time.time(): |
196 | print("Server timeout, exiting.") | 197 | print("Server timeout, exiting.") |
197 | self.quit = True | 198 | self.quit = True |
198 | 199 | ||
200 | # If we don't see a UI connection within maxuiwait, its unlikely we're going to see | ||
201 | # one. We have had issue with processes hanging indefinitely so timing out UI-less | ||
202 | # servers is useful. | ||
203 | if not self.haveui and not self.timeout and (self.lastui + self.maxuiwait) < time.time(): | ||
204 | print("No UI connection within max timeout, exiting to avoid infinite loop.") | ||
205 | self.quit = True | ||
206 | |||
199 | if self.command_channel in ready: | 207 | if self.command_channel in ready: |
200 | try: | 208 | try: |
201 | command = self.command_channel.get() | 209 | command = self.command_channel.get() |
@@ -220,10 +228,13 @@ class ProcessServer(multiprocessing.Process): | |||
220 | 228 | ||
221 | print("Exiting") | 229 | print("Exiting") |
222 | # Remove the socket file so we don't get any more connections to avoid races | 230 | # Remove the socket file so we don't get any more connections to avoid races |
223 | os.unlink(self.sockname) | 231 | try: |
232 | os.unlink(self.sockname) | ||
233 | except: | ||
234 | pass | ||
224 | self.sock.close() | 235 | self.sock.close() |
225 | 236 | ||
226 | try: | 237 | try: |
227 | self.cooker.shutdown(True) | 238 | self.cooker.shutdown(True) |
228 | self.cooker.notifier.stop() | 239 | self.cooker.notifier.stop() |
229 | self.cooker.confignotifier.stop() | 240 | self.cooker.confignotifier.stop() |