summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/runqueue.py
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2014-03-09 10:00:17 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2014-03-10 11:09:58 -0700
commitbb335f96baf5f4cdaa42fd8856ab736d1f7b8d80 (patch)
tree1cd8e94241e25a925490600411f9dc300d1ba16a /bitbake/lib/bb/runqueue.py
parent15688798520896690561824b2fdc227c8a365c82 (diff)
downloadpoky-bb335f96baf5f4cdaa42fd8856ab736d1f7b8d80.tar.gz
bitbake: runqueue.py: Handle worker disappearing gracefully
If the worker (or fakeworker) process disappears for some reason, the system doesn't currently even notice. To fix this, we call waitpid periodically, looking for exit events of our children. If these occur, we can gracefully shutdown the server. (Bitbake rev: ee28ddadaa7ef91e4d4b7d22fc267382aaad6d01) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/runqueue.py')
-rw-r--r--bitbake/lib/bb/runqueue.py27
1 files changed, 22 insertions, 5 deletions
diff --git a/bitbake/lib/bb/runqueue.py b/bitbake/lib/bb/runqueue.py
index 241e387bd3..967e944963 100644
--- a/bitbake/lib/bb/runqueue.py
+++ b/bitbake/lib/bb/runqueue.py
@@ -869,7 +869,7 @@ class RunQueue:
869 else: 869 else:
870 worker = subprocess.Popen(["bitbake-worker", "decafbad"], stdout=subprocess.PIPE, stdin=subprocess.PIPE) 870 worker = subprocess.Popen(["bitbake-worker", "decafbad"], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
871 bb.utils.nonblockingfd(worker.stdout) 871 bb.utils.nonblockingfd(worker.stdout)
872 workerpipe = runQueuePipe(worker.stdout, None, self.cfgData, rqexec) 872 workerpipe = runQueuePipe(worker.stdout, None, self.cfgData, self, rqexec)
873 873
874 workerdata = { 874 workerdata = {
875 "taskdeps" : self.rqdata.dataCache.task_deps, 875 "taskdeps" : self.rqdata.dataCache.task_deps,
@@ -912,6 +912,7 @@ class RunQueue:
912 def start_worker(self): 912 def start_worker(self):
913 if self.worker: 913 if self.worker:
914 self.teardown_workers() 914 self.teardown_workers()
915 self.teardown = False
915 self.worker, self.workerpipe = self._start_worker() 916 self.worker, self.workerpipe = self._start_worker()
916 917
917 def start_fakeworker(self, rqexec): 918 def start_fakeworker(self, rqexec):
@@ -919,6 +920,7 @@ class RunQueue:
919 self.fakeworker, self.fakeworkerpipe = self._start_worker(True, rqexec) 920 self.fakeworker, self.fakeworkerpipe = self._start_worker(True, rqexec)
920 921
921 def teardown_workers(self): 922 def teardown_workers(self):
923 self.teardown = True
922 self._teardown_worker(self.worker, self.workerpipe) 924 self._teardown_worker(self.worker, self.workerpipe)
923 self.worker = None 925 self.worker = None
924 self.workerpipe = None 926 self.workerpipe = None
@@ -2067,7 +2069,7 @@ class runQueuePipe():
2067 """ 2069 """
2068 Abstraction for a pipe between a worker thread and the server 2070 Abstraction for a pipe between a worker thread and the server
2069 """ 2071 """
2070 def __init__(self, pipein, pipeout, d, rq): 2072 def __init__(self, pipein, pipeout, d, rq, rqexec):
2071 self.input = pipein 2073 self.input = pipein
2072 if pipeout: 2074 if pipeout:
2073 pipeout.close() 2075 pipeout.close()
@@ -2075,11 +2077,26 @@ class runQueuePipe():
2075 self.queue = "" 2077 self.queue = ""
2076 self.d = d 2078 self.d = d
2077 self.rq = rq 2079 self.rq = rq
2080 self.rqexec = rqexec
2078 2081
2079 def setrunqueueexec(self, rq): 2082 def setrunqueueexec(self, rqexec):
2080 self.rq = rq 2083 self.rqexec = rqexec
2081 2084
2082 def read(self): 2085 def read(self):
2086 try:
2087 pid, status = os.waitpid(-1, os.WNOHANG)
2088 if pid != 0 and not self.rq.teardown:
2089 if self.rq.worker and pid == self.rq.worker.pid:
2090 name = "Worker"
2091 elif self.rq.fakeworker and pid == self.rq.fakeworker.pid:
2092 name = "Fakeroot"
2093 else:
2094 name = "Unknown"
2095 bb.error("%s process (%s) exited unexpectedly (%s), shutting down..." % (name, pid, str(status)))
2096 self.rq.finish_runqueue(True)
2097 except OSError:
2098 pass
2099
2083 start = len(self.queue) 2100 start = len(self.queue)
2084 try: 2101 try:
2085 self.queue = self.queue + self.input.read(102400) 2102 self.queue = self.queue + self.input.read(102400)
@@ -2106,7 +2123,7 @@ class runQueuePipe():
2106 task, status = pickle.loads(self.queue[10:index]) 2123 task, status = pickle.loads(self.queue[10:index])
2107 except ValueError as e: 2124 except ValueError as e:
2108 bb.msg.fatal("RunQueue", "failed load pickle '%s': '%s'" % (e, self.queue[10:index])) 2125 bb.msg.fatal("RunQueue", "failed load pickle '%s': '%s'" % (e, self.queue[10:index]))
2109 self.rq.runqueue_process_waitpid(task, status) 2126 self.rqexec.runqueue_process_waitpid(task, status)
2110 found = True 2127 found = True
2111 self.queue = self.queue[index+11:] 2128 self.queue = self.queue[index+11:]
2112 index = self.queue.find("</exitcode>") 2129 index = self.queue.find("</exitcode>")