[1/1] qemurunner.py: fix race condition at qemu startup

Submitted by Qi.Chen@windriver.com on July 12, 2019, 7:31 a.m. | Patch ID: 163011

Details

Message ID 91a0ced348fd2a0f619494079545d570d4d68e61.1562916644.git.Qi.Chen@windriver.com
State Accepted
Commit 170e59b203a02f8438b9aeab3a45f6fcd6608b1f
Headers show

Commit Message

Qi.Chen@windriver.com July 12, 2019, 7:31 a.m.
When handling pid file, qemu would first create the file, stat it,
lock it and then write actually contents to it.

So it's possbile that when reading the pid file, the content is empty.

[YOCTO #13390]

Signed-off-by: Chen Qi <Qi.Chen@windriver.com>
---
 meta/lib/oeqa/utils/qemurunner.py | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

Patch hide | download patch | download mbox

diff --git a/meta/lib/oeqa/utils/qemurunner.py b/meta/lib/oeqa/utils/qemurunner.py
index c16227f..68684ae 100644
--- a/meta/lib/oeqa/utils/qemurunner.py
+++ b/meta/lib/oeqa/utils/qemurunner.py
@@ -425,13 +425,20 @@  class QemuRunner:
         if not self.runqemu or self.runqemu.poll() is not None:
             return False
         if os.path.isfile(self.qemu_pidfile):
-            f = open(self.qemu_pidfile, 'r')
-            qemu_pid = f.read()
-            f.close()
-            qemupid = int(qemu_pid)
-            if os.path.exists("/proc/" + str(qemupid)):
-                self.qemupid = qemupid
-                return True
+            # when handling pidfile, qemu creates the file, stat it, lock it and then write to it
+            # so it's possible that the file has been created but the content is empty
+            pidfile_timeout = time.time() + 3
+            while time.time() < pidfile_timeout:
+                with open(self.qemu_pidfile, 'r') as f:
+                    qemu_pid = f.read().strip()
+                # file created but not yet written contents
+                if not qemu_pid:
+                    time.sleep(0.5)
+                    continue
+                else:
+                    if os.path.exists("/proc/" + qemu_pid):
+                        self.qemupid = int(qemu_pid)
+                        return True
         return False
 
     def run_serial(self, command, raw=False, timeout=60):