[master 2/4] Ignore EINTR from os.close instead of retrying the call
dashea
installerbot-noreply at redhat.com
Tue Jun 23 14:54:01 UTC 2015
From: David Shea <dshea at redhat.com>
Retrying close in Linux is considered a bad idea, it turns out.
---
blivet/devicelibs/edd.py | 2 +-
blivet/devices/file.py | 2 +-
blivet/devices/optical.py | 2 +-
blivet/fcoe.py | 2 +-
blivet/iscsi.py | 4 ++--
blivet/util.py | 18 ++++++++++++++++--
6 files changed, 22 insertions(+), 8 deletions(-)
diff --git a/blivet/devicelibs/edd.py b/blivet/devicelibs/edd.py
index 08a713f..7c99bb1 100644
--- a/blivet/devicelibs/edd.py
+++ b/blivet/devicelibs/edd.py
@@ -165,7 +165,7 @@ def collect_mbrs(devices):
# The signature is the unsigned integer at byte 440:
os.lseek(fd, 440, 0)
mbrsig = struct.unpack('I', util.eintr_retry_call(os.read, fd, 4))
- util.eintr_retry_call(os.close, fd)
+ util.eintr_ignore(os.close, fd)
except OSError as e:
log.warning("edd: error reading mbrsig from disk %s: %s",
dev.name, str(e))
diff --git a/blivet/devices/file.py b/blivet/devices/file.py
index f104568..a2845eb 100644
--- a/blivet/devices/file.py
+++ b/blivet/devices/file.py
@@ -119,7 +119,7 @@ def _create(self):
size_target = zero * rem
util.eintr_retry_call(os.write, fd, size_target.encode("utf-8"))
- util.eintr_retry_call(os.close, fd)
+ util.eintr_ignore(os.close, fd)
def _destroy(self):
""" Destroy the device. """
diff --git a/blivet/devices/optical.py b/blivet/devices/optical.py
index 3f8fcd2..591fd01 100644
--- a/blivet/devices/optical.py
+++ b/blivet/devices/optical.py
@@ -63,7 +63,7 @@ def mediaPresent(self):
else:
return True
else:
- util.eintr_retry_call(os.close, fd)
+ util.eintr_ignore(os.close, fd)
return True
def eject(self):
diff --git a/blivet/fcoe.py b/blivet/fcoe.py
index 1723207..a7d7a4c 100644
--- a/blivet/fcoe.py
+++ b/blivet/fcoe.py
@@ -165,7 +165,7 @@ def write(self, root):
else:
config += 'AUTO_VLAN="no"\n'
util.eintr_retry_call(os.write, fd, config.encode('utf-8'))
- util.eintr_retry_call(os.close, fd)
+ util.eintr_ignore(os.close, fd)
return
diff --git a/blivet/iscsi.py b/blivet/iscsi.py
index 160a243..5aa3d4b 100644
--- a/blivet/iscsi.py
+++ b/blivet/iscsi.py
@@ -272,7 +272,7 @@ def startup(self):
fd = util.eintr_retry_call(os.open, INITIATOR_FILE, os.O_RDWR | os.O_CREAT)
initiator_name = "InitiatorName=%s\n" % self.initiator
util.eintr_retry_call(os.write, fd, initiator_name.encode("utf-8"))
- util.eintr_retry_call(os.close, fd)
+ util.eintr_ignore(os.close, fd)
self.initiatorSet = True
for fulldir in (os.path.join("/var/lib/iscsi", d) for d in \
@@ -493,7 +493,7 @@ def write(self, root, storage):
fd = util.eintr_retry_call(os.open, root + INITIATOR_FILE, os.O_RDWR | os.O_CREAT)
initiator_name = "InitiatorName=%s\n" % self.initiator
util.eintr_retry_call(os.write, fd, initiator_name.encode("utf-8"))
- util.eintr_retry_call(os.close, fd)
+ util.eintr_ignore(os.close, fd)
# copy "db" files. *sigh*
if os.path.isdir(root + "/var/lib/iscsi"):
diff --git a/blivet/util.py b/blivet/util.py
index b39308b..30db569 100644
--- a/blivet/util.py
+++ b/blivet/util.py
@@ -528,7 +528,7 @@ def create_sparse_tempfile(name, size):
:returns: the path to the newly created file
"""
(fd, path) = tempfile.mkstemp(prefix="blivet.", suffix="-%s" % name)
- eintr_retry_call(os.close, fd)
+ eintr_ignore(os.close, fd)
create_sparse_file(path, size)
return path
@@ -541,7 +541,7 @@ def create_sparse_file(path, size):
"""
fd = eintr_retry_call(os.open, path, os.O_WRONLY|os.O_CREAT|os.O_TRUNC)
eintr_retry_call(os.ftruncate, fd, size)
- eintr_retry_call(os.close, fd)
+ eintr_ignore(os.close, fd)
@contextmanager
def sparsetmpfile(name, size):
@@ -637,3 +637,17 @@ def eintr_retry_call(func, *args, **kwargs):
if e.errno == errno.EINTR:
continue
raise
+
+def eintr_ignore(func, *args, **kwargs):
+ """Call a function and ignore EINTR.
+
+ This is useful for calls to close() and dup2(), which can return EINTR
+ but which should *not* be retried, since by the time the return the
+ file descriptor is already closed.
+ """
+ try:
+ return func(*args, **kwargs)
+ except (OSError, IOError) as e:
+ if e.errno == errno.EINTR:
+ pass
+ raise
--
To view this commit on github, visit https://github.com/rhinstaller/blivet/commit/75cccc1d1453fdabc88fe5776d9dd4df4984b5f4
More information about the anaconda-patches
mailing list