-
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