diff --git a/00287-fix-thread-hanging-on-inaccessible-nfs-server.patch b/00287-fix-thread-hanging-on-inaccessible-nfs-server.patch new file mode 100644 index 0000000..1dbb62f --- /dev/null +++ b/00287-fix-thread-hanging-on-inaccessible-nfs-server.patch @@ -0,0 +1,135 @@ +diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c +index 4a71a57ec0d..2b40ada195a 100644 +--- a/Modules/_io/fileio.c ++++ b/Modules/_io/fileio.c +@@ -146,9 +146,15 @@ dircheck(fileio* self, PyObject *nameobj) + { + #if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR) + struct stat buf; ++ int res; + if (self->fd < 0) + return 0; +- if (fstat(self->fd, &buf) == 0 && S_ISDIR(buf.st_mode)) { ++ ++ Py_BEGIN_ALLOW_THREADS ++ res = fstat(self->fd, &buf); ++ Py_END_ALLOW_THREADS ++ ++ if (res == 0 && S_ISDIR(buf.st_mode)) { + errno = EISDIR; + PyErr_SetFromErrnoWithFilenameObject(PyExc_IOError, nameobj); + return -1; +@@ -162,17 +168,34 @@ check_fd(int fd) + { + #if defined(HAVE_FSTAT) + struct stat buf; +- if (!_PyVerify_fd(fd) || (fstat(fd, &buf) < 0 && errno == EBADF)) { +- PyObject *exc; +- char *msg = strerror(EBADF); +- exc = PyObject_CallFunction(PyExc_OSError, "(is)", +- EBADF, msg); +- PyErr_SetObject(PyExc_OSError, exc); +- Py_XDECREF(exc); +- return -1; ++ int res; ++ PyObject *exc; ++ char *msg; ++ ++ if (!_PyVerify_fd(fd)) { ++ goto badfd; + } +-#endif ++ ++ Py_BEGIN_ALLOW_THREADS ++ res = fstat(fd, &buf); ++ Py_END_ALLOW_THREADS ++ ++ if (res < 0 && errno == EBADF) { ++ goto badfd; ++ } ++ + return 0; ++ ++badfd: ++ msg = strerror(EBADF); ++ exc = PyObject_CallFunction(PyExc_OSError, "(is)", ++ EBADF, msg); ++ PyErr_SetObject(PyExc_OSError, exc); ++ Py_XDECREF(exc); ++ return -1; ++#else ++ return 0; ++#endif + } + + +@@ -519,9 +542,19 @@ new_buffersize(fileio *self, size_t currentsize) + #ifdef HAVE_FSTAT + off_t pos, end; + struct stat st; +- if (fstat(self->fd, &st) == 0) { ++ int res; ++ ++ Py_BEGIN_ALLOW_THREADS ++ res = fstat(self->fd, &st); ++ Py_END_ALLOW_THREADS ++ ++ if (res == 0) { + end = st.st_size; ++ ++ Py_BEGIN_ALLOW_THREADS + pos = lseek(self->fd, 0L, SEEK_CUR); ++ Py_END_ALLOW_THREADS ++ + /* Files claiming a size smaller than SMALLCHUNK may + actually be streaming pseudo-files. In this case, we + apply the more aggressive algorithm below. +diff --git a/Objects/fileobject.c b/Objects/fileobject.c +index 2f63c374d1e..8d1c5812f0d 100644 +--- a/Objects/fileobject.c ++++ b/Objects/fileobject.c +@@ -121,10 +121,15 @@ dircheck(PyFileObject* f) + { + #if defined(HAVE_FSTAT) && defined(S_IFDIR) && defined(EISDIR) + struct stat buf; ++ int res; + if (f->f_fp == NULL) + return f; +- if (fstat(fileno(f->f_fp), &buf) == 0 && +- S_ISDIR(buf.st_mode)) { ++ ++ Py_BEGIN_ALLOW_THREADS ++ res = fstat(fileno(f->f_fp), &buf); ++ Py_END_ALLOW_THREADS ++ ++ if (res == 0 && S_ISDIR(buf.st_mode)) { + char *msg = strerror(EISDIR); + PyObject *exc = PyObject_CallFunction(PyExc_IOError, "(isO)", + EISDIR, msg, f->f_name); +@@ -1010,7 +1015,13 @@ new_buffersize(PyFileObject *f, size_t currentsize) + #ifdef HAVE_FSTAT + off_t pos, end; + struct stat st; +- if (fstat(fileno(f->f_fp), &st) == 0) { ++ int res; ++ ++ Py_BEGIN_ALLOW_THREADS ++ res = fstat(fileno(f->f_fp), &st); ++ Py_END_ALLOW_THREADS ++ ++ if (res == 0) { + end = st.st_size; + /* The following is not a bug: we really need to call lseek() + *and* ftell(). The reason is that some stdio libraries +@@ -1021,7 +1032,11 @@ new_buffersize(PyFileObject *f, size_t currentsize) + works. We can't use the lseek() value either, because we + need to take the amount of buffered data into account. + (Yet another reason why stdio stinks. :-) */ ++ ++ Py_BEGIN_ALLOW_THREADS + pos = lseek(fileno(f->f_fp), 0L, SEEK_CUR); ++ Py_END_ALLOW_THREADS ++ + if (pos >= 0) { + pos = ftell(f->f_fp); + } diff --git a/python2.spec b/python2.spec index b822c79..70b5e16 100644 --- a/python2.spec +++ b/python2.spec @@ -112,7 +112,7 @@ Summary: An interpreted, interactive, object-oriented programming language Name: %{python} # Remember to also rebase python-docs when changing this: Version: 2.7.14 -Release: 3%{?dist} +Release: 4%{?dist} License: Python Group: Development/Languages Requires: %{python}-libs%{?_isa} = %{version}-%{release} @@ -355,7 +355,7 @@ Patch17: python-2.6.4-distutils-rpath.patch # for 2.7rc1 by dmalcolm: Patch55: 00055-systemtap.patch -# Only used when "%{_lib}" == "lib64" +# Only used when "%%{_lib}" == "lib64" # Fixup various paths throughout the build and in distutils from "lib" to "lib64", # and add the /usr/lib64/pythonMAJOR.MINOR/site-packages to sitedirs, in front of # /usr/lib/pythonMAJOR.MINOR/site-packages @@ -369,7 +369,7 @@ Patch102: 00102-2.7.13-lib64.patch Patch103: python-2.7-lib64-sysconfig.patch # 00104 # -# Only used when "%{_lib}" == "lib64" +# Only used when "%%{_lib}" == "lib64" # Another lib64 fix, for distutils/tests/test_install.py; not upstream: Patch104: 00104-lib64-fix-for-test_install.patch @@ -745,6 +745,14 @@ Patch284: 00284-add-PYTHONSHOWREFCOUNT-env-var.patch # Fixed upstream: https://bugs.python.org/issue31158 Patch285: 00285-fix-non-deterministic-read-in-test_pty.patch +# 00287 # +# On the creation of io.FileIO() and builtin file() objects the GIL is now released +# when checking the file descriptor. io.FileIO.readall(), io.FileIO.read(), and +# file.read() also now release the GIL when getting the file size, which fixes hanging +# of all threads when trying to access an inaccessible NFS server. +# Fixed upstream: https://bugs.python.org/issue32186 +Patch287: 00287-fix-thread-hanging-on-inaccessible-nfs-server.patch + # (New patches go here ^^^) # # When adding new patches to "python2" and "python3" in Fedora, EL, etc., @@ -755,7 +763,7 @@ Patch285: 00285-fix-non-deterministic-read-in-test_pty.patch # https://fedoraproject.org/wiki/SIGs/Python/PythonPatches # This is the generated patch to "configure"; see the description of -# %{regenerate_autotooling_patch} +# %%{regenerate_autotooling_patch} # above: # Disable tk for modularity builds to break up build dependencies @@ -1062,6 +1070,7 @@ mv Modules/cryptmodule.c Modules/_cryptmodule.c %patch283 -p1 %patch284 -p1 %patch285 -p1 +%patch287 -p1 %if 0%{?_module_build} @@ -1942,6 +1951,9 @@ rm -fr %{buildroot} # ====================================================== %changelog +* Mon Dec 11 2017 Charalampos Stratakis - 2.7.14-4 +- Fix hanging of all threads when trying to access an inaccessible NFS server. + * Thu Nov 09 2017 Miro HronĨok - 2.7.14-3 - Make the -devel package require redhat-rpm-config Resolves: rhbz#1496757