Commit c1a4d6c4 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

fs: describe one more deadlock scenario

Change-Id: I43f09613acd119daefe64350a46f79d58b2e4b6a
parent 5b76a74a
...@@ -145,14 +145,30 @@ ...@@ -145,14 +145,30 @@
// threads, and makes assumptions that some system calls do not // threads, and makes assumptions that some system calls do not
// block. When accessing a file system from the same process that // block. When accessing a file system from the same process that
// serves the file system (e.g. in unittests), this can lead to // serves the file system (e.g. in unittests), this can lead to
// deadlocks, especially when GOMAXPROCS=1. The following deadlocks // deadlocks, especially when GOMAXPROCS=1, when the Go runtime
// are known: // assumes a system call does not block, but actually is served by the
// Go-FUSE process.
// //
// 1. Spawning a subprocess uses a fork/exec sequence. In this // The following deadlocks are known:
// sequence, the child process uses dup3() to remap file //
// descriptors. If the destination fd happens to be backed by Go-FUSE, // 1. Spawning a subprocess uses a fork/exec sequence: the process
// the dup3() call will implicitly close the fd, generating a FLUSH // forks itself into a parent and child. The parent waits for the
// operation. If there is no thread left to respond, the process is deadlocked. // child to signal that the exec failed or succeeded, while the child
// prepares for calling exec(). Any setup step in the child that
// triggers a FUSE request can cause a deadlock.
//
// 1a. If the subprocess has a directory specified, the child will
// chdir into that directory. This generates an ACCESS operation on
// the directory.
//
// This deadlock can be avoided by disabling the ACCESS
// operation: return syscall.ENOSYS in the Access implementation, and
// ensure it is triggered called before initiating the subprocess.
//
// 1b. If the subprocess inherits files, the child process uses dup3()
// to remap file descriptors. If the destination fd happens to be
// backed by Go-FUSE, the dup3() call will implicitly close the fd,
// generating a FLUSH operation, eg.
// //
// f1, err := os.Open("/fusemnt/file1") // f1, err := os.Open("/fusemnt/file1")
// // f1.Fd() == 3 // // f1.Fd() == 3
...@@ -164,9 +180,10 @@ ...@@ -164,9 +180,10 @@
// // f2 (fd 4) is moved to fd 3. Deadlocks with GOMAXPROCS=1. // // f2 (fd 4) is moved to fd 3. Deadlocks with GOMAXPROCS=1.
// cmd.Start() // cmd.Start()
// //
// This can be avoided by ensuring that file descriptors pointing into // This deadlock can be avoided by ensuring that file descriptors
// FUSE mounts and file descriptors passed into subprocesses do not // pointing into FUSE mounts and file descriptors passed into
// overlap, e.g. inserting the following before the above example: // subprocesses do not overlap, e.g. inserting the following before
// the above example:
// //
// for { // for {
// f, _ := os.Open("/dev/null") // f, _ := os.Open("/dev/null")
...@@ -176,14 +193,12 @@ ...@@ -176,14 +193,12 @@
// } // }
// } // }
// //
// 2. The Go runtime uses the epoll system call to schedule // 2. The Go runtime uses the epoll system call to understand which
// goroutines, and assumes that epoll does not block. However, the // goroutines can respond to I/O. The runtime assumes that epoll does
// FUSE kernel module implements the POLL opcode. If the Go runtime // not block, but if files are on a FUSE filesystem, the kernel will
// calls epoll() with files opened on a FUSE mount, and if there is // generate a POLL operation. To prevent this from happening, Go-FUSE
// only one thread available for execution, there is no thread left to // disables the POLL opcode on mount. To ensure this has happened, call
// respond to the POLL opcode, leading to deadlock. To prevent this // WaitMount.
// from happening, Go-FUSE centrally disables the POLL opcode. (See
// commit 4f10e248ebabd3cdf9c0aa3ae58fd15235f82a79)
// //
// # Dynamically discovered file systems // # Dynamically discovered file systems
// //
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment