summaryrefslogtreecommitdiff
path: root/lib/ansible/compat
diff options
context:
space:
mode:
authorToshio Kuratomi <a.badger@gmail.com>2018-08-09 21:01:27 -0700
committerToshio Kuratomi <a.badger@gmail.com>2018-08-13 07:17:11 -0700
commite2e44f846cf408cc506de6ac94247023274fddd4 (patch)
tree08c69721700ecf72ce91649cc5fd4ec7b1979b96 /lib/ansible/compat
parent1fb0e11b560a7439cd0495bd7d5980e089acdef9 (diff)
downloadansible-e2e44f846cf408cc506de6ac94247023274fddd4.tar.gz
Fix the local and ssh plugins for a cornercase retrying a syscall
The bundled selectors library which is used by the local and ssh connection plugins had a bug which caused a traceback in a cornercase. If selectors were in use and a syscall was interrupted, selectors would attempt to restart the syscall after the interrupt was processed. if the attempt determined that the timeout for running the syscall had already expired, the code attempted to raise OSError. The raise was using a Python3-ism and needed to be ported to work on Python2. Fixes #41630
Diffstat (limited to 'lib/ansible/compat')
-rw-r--r--lib/ansible/compat/selectors/__init__.py8
-rw-r--r--lib/ansible/compat/selectors/_selectors2.py19
2 files changed, 19 insertions, 8 deletions
diff --git a/lib/ansible/compat/selectors/__init__.py b/lib/ansible/compat/selectors/__init__.py
index 6458438d6d..8d45ea5fbf 100644
--- a/lib/ansible/compat/selectors/__init__.py
+++ b/lib/ansible/compat/selectors/__init__.py
@@ -25,6 +25,14 @@ package exists on pypi to backport the functionality as far as python-2.6.
'''
# The following makes it easier for us to script updates of the bundled code
_BUNDLED_METADATA = {"pypi_name": "selectors2", "version": "1.1.0"}
+# Added these bugfix commits from 2.1.0:
+# * https://github.com/SethMichaelLarson/selectors2/commit/3bd74f2033363b606e1e849528ccaa76f5067590
+# Wrap kqueue.control so that timeout is a keyword arg
+# * https://github.com/SethMichaelLarson/selectors2/commit/6f6a26f42086d8aab273b30be492beecb373646b
+# Fix formatting of the kqueue.control patch for pylint
+# * https://github.com/SethMichaelLarson/selectors2/commit/f0c2c6c66cfa7662bc52beaf4e2d65adfa25e189
+# Fix use of OSError exception for py3 and use the wrapper of kqueue.control so retries of
+# interrupted syscalls work with kqueue
import os.path
import sys
diff --git a/lib/ansible/compat/selectors/_selectors2.py b/lib/ansible/compat/selectors/_selectors2.py
index c4c81d76d4..d935576baf 100644
--- a/lib/ansible/compat/selectors/_selectors2.py
+++ b/lib/ansible/compat/selectors/_selectors2.py
@@ -137,7 +137,7 @@ else:
if expires is not None:
current_time = monotonic()
if current_time > expires:
- raise OSError(errno=errno.ETIMEDOUT)
+ raise OSError(errno.ETIMEDOUT)
if recalc_timeout:
if "timeout" in kwargs:
kwargs["timeout"] = expires - current_time
@@ -342,7 +342,7 @@ if hasattr(select, "select"):
timeout = None if timeout is None else max(timeout, 0.0)
ready = []
r, w, _ = _syscall_wrapper(self._select, True, self._readers,
- self._writers, timeout)
+ self._writers, timeout=timeout)
r = set(r)
w = set(w)
for fd in r | w:
@@ -563,14 +563,14 @@ if hasattr(select, "kqueue"):
select.KQ_FILTER_READ,
select.KQ_EV_ADD)
- _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
+ _syscall_wrapper(self._wrap_control, False, [kevent], 0, 0)
if events & EVENT_WRITE:
kevent = select.kevent(key.fd,
select.KQ_FILTER_WRITE,
select.KQ_EV_ADD)
- _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
+ _syscall_wrapper(self._wrap_control, False, [kevent], 0, 0)
return key
@@ -581,7 +581,7 @@ if hasattr(select, "kqueue"):
select.KQ_FILTER_READ,
select.KQ_EV_DELETE)
try:
- _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
+ _syscall_wrapper(self._wrap_control, False, [kevent], 0, 0)
except SelectorError:
pass
if key.events & EVENT_WRITE:
@@ -589,7 +589,7 @@ if hasattr(select, "kqueue"):
select.KQ_FILTER_WRITE,
select.KQ_EV_DELETE)
try:
- _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
+ _syscall_wrapper(self._wrap_control, False, [kevent], 0, 0)
except SelectorError:
pass
@@ -602,8 +602,8 @@ if hasattr(select, "kqueue"):
max_events = len(self._fd_to_key) * 2
ready_fds = {}
- kevent_list = _syscall_wrapper(self._kqueue.control, True,
- None, max_events, timeout)
+ kevent_list = _syscall_wrapper(self._wrap_control, True,
+ None, max_events, timeout=timeout)
for kevent in kevent_list:
fd = kevent.ident
@@ -628,6 +628,9 @@ if hasattr(select, "kqueue"):
self._kqueue.close()
super(KqueueSelector, self).close()
+ def _wrap_control(self, changelist, max_events, timeout):
+ return self._kqueue.control(changelist, max_events, timeout)
+
__all__.append('KqueueSelector')