]> git.ipfire.org Git - thirdparty/openembedded/openembedded-core-contrib.git/commitdiff
bitbake: server/process: Various server startup logging fixes
authorRichard Purdie <richard.purdie@linuxfoundation.org>
Tue, 4 Sep 2018 14:54:12 +0000 (15:54 +0100)
committerRichard Purdie <richard.purdie@linuxfoundation.org>
Wed, 5 Sep 2018 17:01:37 +0000 (18:01 +0100)
There were various problems in the server startup loggin:

a) stdout/stderr were not being flushed before forking which could potentially
   duplicate output

b) there were separate buffers for stdout/stderr leading to confusing logs
   where the entries could be reordered. This was particularly confusing
   due to the separator the logs use to idendify new messages

c) an fd wasn't being closed during server startup meaning if the
   server failed to start, the closed fd wasn't detected as it was held
   open by the other reference

d) If the pipe was detected as being closed, the code incorrectly retried
   server startup

e) The event code would remap stdout/stderr without flushing them, leading
   to lose log messages

(Bitbake rev: 0594faa0b52ce5dbd948d836d88617d38d9862d1)

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
bitbake/lib/bb/daemonize.py
bitbake/lib/bb/event.py
bitbake/lib/bb/server/process.py

index bf16793468e2b8aefab8f41a7e7ec7069e93be7e..613fb35536718ffa54d03748589b015690f1d164 100644 (file)
@@ -16,6 +16,10 @@ def createDaemon(function, logfile):
     background as a daemon, returning control to the caller.
     """
 
+    # Ensure stdout/stderror are flushed before forking to avoid duplicate output
+    sys.stdout.flush()
+    sys.stderr.flush()
+
     try:
         # Fork a child process so the parent can exit.  This returns control to
         # the command-line or shell.  It also guarantees that the child will not
@@ -66,12 +70,14 @@ def createDaemon(function, logfile):
 
     try:
         so = open(logfile, 'a+')
-        se = so
         os.dup2(so.fileno(), sys.stdout.fileno())
-        os.dup2(se.fileno(), sys.stderr.fileno())
+        os.dup2(so.fileno(), sys.stderr.fileno())
     except io.UnsupportedOperation:
         sys.stdout = open(logfile, 'a+')
-        sys.stderr = sys.stdout
+
+    # Have stdout and stderr be the same so log output matches chronologically
+    # and there aren't two seperate buffers
+    sys.stderr = sys.stdout
 
     try:
         function()
index c0ec605209a608194d453614112d4427a583a581..5b1b094a80686ab4f498b891a203403cefa1b54b 100644 (file)
@@ -141,6 +141,9 @@ def print_ui_queue():
     logger = logging.getLogger("BitBake")
     if not _uiready:
         from bb.msg import BBLogFormatter
+        # Flush any existing buffered content
+        sys.stdout.flush()
+        sys.stderr.flush()
         stdout = logging.StreamHandler(sys.stdout)
         stderr = logging.StreamHandler(sys.stderr)
         formatter = BBLogFormatter("%(levelname)s: %(message)s")
index 9e5e709f0486d2b3ffe15d22f67c6c26fa9480c4..38b923fe2dcd4b461567d945ef49b37bb62af11f 100644 (file)
@@ -395,11 +395,16 @@ class BitBakeServer(object):
         bb.daemonize.createDaemon(self._startServer, logfile)
         self.sock.close()
         self.bitbake_lock.close()
+        os.close(self.readypipein)
 
         ready = ConnectionReader(self.readypipe)
         r = ready.poll(30)
         if r:
-            r = ready.get()
+            try:
+                r = ready.get()
+            except EOFError:
+                # Trap the child exitting/closing the pipe and error out
+                r = None
         if not r or r != "ready":
             ready.close()
             bb.error("Unable to start bitbake server")
@@ -425,21 +430,16 @@ class BitBakeServer(object):
                         bb.error("Server log for this session (%s):\n%s" % (logfile, "".join(lines)))
             raise SystemExit(1)
         ready.close()
-        os.close(self.readypipein)
 
     def _startServer(self):
         print(self.start_log_format % (os.getpid(), datetime.datetime.now().strftime(self.start_log_datetime_format)))
         server = ProcessServer(self.bitbake_lock, self.sock, self.sockname)
         self.configuration.setServerRegIdleCallback(server.register_idle_function)
+        os.close(self.readypipe)
         writer = ConnectionWriter(self.readypipein)
-        try:
-            self.cooker = bb.cooker.BBCooker(self.configuration, self.featureset)
-            writer.send("ready")
-        except:
-            writer.send("fail")
-            raise
-        finally:
-            os.close(self.readypipein)
+        self.cooker = bb.cooker.BBCooker(self.configuration, self.featureset)
+        writer.send("ready")
+        writer.close()
         server.cooker = self.cooker
         server.server_timeout = self.configuration.server_timeout
         server.xmlrpcinterface = self.configuration.xmlrpcinterface