Fix hanging of all threads when trying to access an inaccessible NFS server.

Also mask some macros in comments.
This commit is contained in:
Charalampos Stratakis 2017-12-11 13:35:09 +01:00
parent 3bebf16e16
commit cf221a53b1
2 changed files with 151 additions and 4 deletions

View File

@ -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);
}

View File

@ -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 <cstratak@redhat.com> - 2.7.14-4
- Fix hanging of all threads when trying to access an inaccessible NFS server.
* Thu Nov 09 2017 Miro Hrončok <mhroncok@redhat.com> - 2.7.14-3
- Make the -devel package require redhat-rpm-config
Resolves: rhbz#1496757