Nir Soffer has uploaded a new change for review.

Change subject: clusterlock: Fix double close on EINTR
......................................................................

clusterlock: Fix double close on EINTR

If os.close(fd) was interrupted by signal, we would try to close again -
this may lead to closing other thread file descriptor.

close(2) warns not to retry close() after EINTR:

    Note that the return value should be used only for diagnostics. In
    particular close() should not be retried after an EINTR since this
    may cause a reused descriptor from another thread to be closed.

See also this discussion about close and EINTR on linux:
http://lwn.net/Articles/576478/

This patch removes the utils.NoIntrCall around os.close() calls and
ignore EINTR instead. The behavior on other error is not changed, we
will raise the error.

Since we try os.close() inside the try block of the original error, we
have to keep the original exception for reraising it.

Change-Id: I3cae714af9646e268f40ff1ff3cdb3f6b048e6e9
Signed-off-by: Nir Soffer <nsof...@redhat.com>
---
M lib/vdsm/storage/clusterlock.py
1 file changed, 14 insertions(+), 3 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/39/60539/1

diff --git a/lib/vdsm/storage/clusterlock.py b/lib/vdsm/storage/clusterlock.py
index 9317b0a..30b4352 100644
--- a/lib/vdsm/storage/clusterlock.py
+++ b/lib/vdsm/storage/clusterlock.py
@@ -25,11 +25,13 @@
 import logging
 import os
 import subprocess
+import sys
 import threading
 
 from contextlib import nested
 
 import sanlock
+import six
 
 from vdsm import constants
 from vdsm import utils
@@ -458,12 +460,17 @@
                 utils.NoIntrCall(fcntl.flock, lockFile,
                                  fcntl.LOCK_EX | fcntl.LOCK_NB)
             except IOError as e:
-                utils.NoIntrCall(os.close, lockFile)
+                t, v, tb = sys.exec_info()
+                try:
+                    os.close(lockFile)
+                except OSError as ce:
+                    if ce.errno != errno.EINTR:
+                        raise
                 if e.errno in (errno.EACCES, errno.EAGAIN):
                     raise se.AcquireLockFailure(
                         self._sdUUID, e.errno, "Cannot acquire local lock",
                         str(e))
-                raise
+                six.reraise(t, v, tb)
             else:
                 self._globalLockMap[self._sdUUID] = (hostId, lockFile)
 
@@ -486,7 +493,11 @@
                                self._sdUUID)
                 return
 
-            utils.NoIntrCall(os.close, lockFile)
+            try:
+                os.close(lockFile)
+            except OSError as e:
+                if e.errno != errno.EINTR:
+                    raise
             self._globalLockMap[self._sdUUID] = (hostId, None)
 
             self.log.debug("Local lock for domain %s successfully released",


-- 
To view, visit https://gerrit.ovirt.org/60539
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3cae714af9646e268f40ff1ff3cdb3f6b048e6e9
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Nir Soffer <nsof...@redhat.com>
_______________________________________________
vdsm-patches mailing list
vdsm-patches@lists.fedorahosted.org
https://lists.fedorahosted.org/admin/lists/vdsm-patches@lists.fedorahosted.org

Reply via email to