diff mbox series

[02/11] runqemu: don't drop a held lock when acquire_portlock() fails

Message ID 20261011195949.2118607-3-adrian.freihofer@siemens.com
State New
Headers show
Series runqemu: use QMP for slirp host port allocation | expand

Commit Message

AdrianF Oct. 11, 2026, 7:59 p.m. UTC
From: Adrian Freihofer <adrian.freihofer@siemens.com>

acquire_portlock() stored the new file object in self.portlocks before
calling flock(). If the process already held that lock, the entry was
replaced, which closed the old file object and with it released the
lock. The flock() on the new file then succeeded, so a lock held by this
very process was reported as free.

Only record the descriptor once flock() succeeded and close just the new
one on failure.

The current callers never ask for the same lock file twice, so this is
latent, but it makes acquire_portlock() reliable for callers that do.

Signed-off-by: Adrian Freihofer <adrian.freihofer@siemens.com>
---
 scripts/runqemu | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/scripts/runqemu b/scripts/runqemu
index dee7710fb3..5f1af740c9 100755
--- a/scripts/runqemu
+++ b/scripts/runqemu
@@ -277,17 +277,17 @@  class BaseConfig(object):
 
     def acquire_portlock(self, lockfile):
         logger.debug("Acquiring lockfile %s..." % lockfile)
+        portlock_descriptor = None
         try:
             portlock_descriptor = open(lockfile, 'w')
-            self.portlocks.update({lockfile: portlock_descriptor})
-            fcntl.flock(self.portlocks[lockfile], fcntl.LOCK_EX|fcntl.LOCK_NB)
+            fcntl.flock(portlock_descriptor, fcntl.LOCK_EX|fcntl.LOCK_NB)
         except Exception as e:
             msg = "Acquiring lockfile %s failed: %s" % (lockfile, e)
             logger.info(msg)
-            if lockfile in self.portlocks.keys() and self.portlocks[lockfile]:
-                self.portlocks[lockfile].close()
-                del self.portlocks[lockfile]
+            if portlock_descriptor:
+                portlock_descriptor.close()
             return False
+        self.portlocks[lockfile] = portlock_descriptor
         return True
 
     def release_portlock(self, lockfile=None):