Bug 789393

Summary: close(fd) failing with EINTR must keep fd open
Product: Red Hat Enterprise Linux 6 Reporter: Eric Blake <eblake>
Component: kernelAssignee: Red Hat Kernel Manager <kernel-mgr>
Status: CLOSED NOTABUG QA Contact: Red Hat Kernel QE team <kernel-qe>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 6.3CC: aviro, mitr, rwheeler
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
: 789395 (view as bug list) Environment:
Last Closed: 2012-02-29 17:51:43 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Bug Depends On:    
Bug Blocks: 789395    

Description Eric Blake 2012-02-10 16:54:24 UTC
Description of problem:
The next version of POSIX will require that if close(fd) returns -1 with errno set to EINTR, because the close operation was interrupted by a signal and can be resumed, then fd must be kept open.  For all other errno values (such as EIO), the current kernel behavior of closing fd in addition to reporting the error is appropriate.  I have not audited the kernel to find out if any of the file system drivers can ever return EINTR back to the kernel, but if they can, then the kernel has a bug for blindly closing fd during close().

Version-Release number of selected component (if applicable):
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=fs/open.c;h=77becc04114908fae2a45f655ed22996264723ad;hb=HEAD#l1063

How reproducible:


Steps to Reproduce:
1. determine if any file system can fail with EINTR (perhaps a long-running NFS situation, where a signal can return control to the user prior to the close completing)
2.
3.
  
Actual results:
if the kernel blindly closes fd and then returns EINTR failure, the application will assume according to POSIX that it can re-attempt close(fd), but the kernel may have opened another unrelated file to fd in the meantime, and the second close will do the wrong thing

Expected results:
Either the kernel must never fail close() with EINTR, or on EINTR failure (and just EINTR), the kernel must guarantee that fd stays open to the same file.

Additional info:
http://austingroupbugs.net/view.php?id=529#c1107

Comment 1 Eric Blake 2012-02-10 16:57:38 UTC
I also created bug 789395 against glibc, in case we decide to patch things there instead of (or in addition to) the kernel.

Comment 3 Eric Blake 2012-02-17 16:03:11 UTC
Update - the POSIX folks are still debating things, but the discussion has now shifted over to the notion of requiring that close() _never_ fails with EINTR, and must always close the fd for all other errors, and with a suggestion of mapping EINTR -> EINPROGRESS in kernels that used to fail with EINTR but closed the fd.  Furthermore, there is a suggestion to add posix_close(int fd, int flag), with a flag POSIX_CLOSE_RESTART, in order to obtain the restart semantics of keeping fd open if things fail with EINTR, but while still permitting an implementation that never fails with EINTR to effectively ignore the POSIX_CLOSE_RESTART flag.  That is, it may be possible to completely comply with the POSIX proposal by patching just glibc, although adding a working posix_close(int fd, int flag) to the kernel as a new syscall might have other benefits.

Comment 4 Ric Wheeler 2012-02-20 11:07:15 UTC
This isn't a behavior that we can change without persuading upstream to take it.

If the POSIX people are looking at this still, I would suggest we close it until it gets resolved.