• Han-Wen Nienhuys's avatar
    fuse: fix tests for Go 1.9 · 4f10e248
    Han-Wen Nienhuys authored
    Go 1.9 uses epoll() for more efficient file I/O. File I/O causes a
    call to epoll, and the runtime makes this call take up a GOMAXPROCS
    slot.
    
    The FUSE kernel module also supports poll: polling on a file residing
    in a FUSE file system causes the kernel to sends a POLL request to the
    userspace process.  If the process responds with ENOSYS, the kernel
    will stop forwarding poll requests to the FUSE process.
    
    In a test for Go FUSE file systems, it is normal to serve the
    filesystem out of the same process that opens files in the file
    system. If this happens in Go 1.9, the epoll call can take the only
    GOMAXPROCS slot left, leaving the process unable to respond to the
    FUSE POLL opcode, deadlocking the process.
    
    This change add support for a magic file "/ .go-fuse-epoll-hack" with
    node ID uint64(-1), and on starting up the file system, the library
    calls poll() on this file, triggering the POLL opcode before the Go
    runtime had a chance to do so.
    
    There are two problem scenarios left:
    
    * File system tests that start I/O before calling WaitMount() still
      risk deadlocking themselves.
    
    * The Linux kernel keeps track of feature support in fuse_conn, which notes
    
             * The following bitfields are only for optimization purposes
             * and hence races in setting them will not cause malfunction
    
      if our forced ENOSYS gets lost due to a race condition in the
      kernel, this can still trigger.
    
    Fixes golang/go#21014 and #165
    4f10e248
opcode.go 21.1 KB