-
Notifications
You must be signed in to change notification settings - Fork 17.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
os: recent FreeBSD update to sys/fusefs to allow kevents breaks go polling model #54100
Comments
Looking for the magic name Is there some way to check for a type as we already do for a FIFO? |
CC @golang/freebsd |
We could probably implement a function similar to devname(3), which is used by mount_fusefs(8) to check the device name. Hardcoding "kern.devname" MIB (which is [1, 2147483224] on 13.1-RELEASE) doesn't sound right so this approach would need runtime translation of the sysctl name to MIB. |
For example, it would be fine to add |
Change https://go.dev/cl/420235 mentions this issue: |
I've ended looking at this as well. I ran the
The relevant part is this:
Note how the file is registered under the netpoller, but fails to set the file into non-blocking mode. Corresponding to the following code: Lines 171 to 184 in 9a2001a
We don't unregister a pollable file if syscall.SetNonblock() failed. I think that is the bug in the runtime we should be fixing.
While this is addressed (or maybe wait for a kernel fix?), this is a simple workaround to bazil/fuse#280 diff --git a/mount_freebsd.go b/mount_freebsd.go
index 9106a18..52a1af0 100644
--- a/mount_freebsd.go
+++ b/mount_freebsd.go
@@ -56,10 +56,11 @@ func mount(dir string, conf *mountConfig) (*os.File, error) {
}
}
- f, err := os.OpenFile("/dev/fuse", os.O_RDWR, 0o000)
+ fd, err := syscall.Open("/dev/fuse", os.O_RDWR|syscall.O_CLOEXEC, 0o000)
if err != nil {
return nil, err
}
+ f := os.NewFile(uintptr(fd), "/dev/fuse")
cmd := exec.Command(
"/sbin/mount_fusefs", By using |
Change https://go.dev/cl/420334 mentions this issue: |
I've sent https://go.dev/cl/420334, with it the When the kernel fuse device ends up supporting SETFL, then we can return back to regular diff --git a/mount_freebsd.go b/mount_freebsd.go
index 9106a18..28d4ef1 100644
--- a/mount_freebsd.go
+++ b/mount_freebsd.go
@@ -8,6 +8,8 @@ import (
"strings"
"sync"
"syscall"
+
+ "golang.org/x/sys/unix"
)
func handleMountFusefsStderr(errCh chan<- error) func(line string) (ignore bool) {
@@ -56,10 +58,11 @@ func mount(dir string, conf *mountConfig) (*os.File, error) {
}
}
- f, err := os.OpenFile("/dev/fuse", os.O_RDWR, 0o000)
+ fd, err := unix.Open("/dev/fuse", unix.O_RDWR|unix.O_NONBLOCK|unix.O_CLOEXEC, 0o000)
if err != nil {
return nil, err
}
+ f := os.NewFile(uintptr(fd), "/dev/fuse")
cmd := exec.Command(
"/sbin/mount_fusefs", |
Update: I believe there's a kernel issue here with the fuse device. However the mere initial attempt to set the file descriptor into non-blocking mode, which reports an error: If we skip this initial attempt, for example by explicitly starting from a blocking file descriptor #54100 (comment). Then the device doesn't enter non-blocking mode, and never returns |
Apply bazil/fuse workaround from [1], bump PORTREVISION. [1] golang/go#54100 (comment) PR: 258056 Approved by: Ralf van der Enden <tremere@cainites.net> (maintainer)
…he netpoller Either ones where kind == kindNonBlock or those we've successfully called syscall.SetNonblock() on. Restore blocking behavior if we detect an error registering with the netpoller and our flow was successful in setting the inital syscall.SetNonblock(). Update #54100 Change-Id: I08934e4107c7fb36c15a7ca23ac880490b4df235 Reviewed-on: https://go-review.googlesource.com/c/go/+/420334 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Dmitri Goutnik <dgoutnik@gmail.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Run-TryBot: Yuval Pavel Zholkover <paulzhol@gmail.com> Reviewed-by: Than McIntosh <thanm@google.com> Auto-Submit: Ian Lance Taylor <iant@golang.org>
Apply bazil/fuse workaround from [1], bump PORTREVISION. [1] golang/go#54100 (comment) PR: 258056 Approved by: Ralf van der Enden <tremere@cainites.net> (maintainer)
Remaining FreeBSD fuse(4) fcntl issue is tracked here: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=265736 |
That FreeBSD bug, which actually turned out not to be in fusefs, is now fixed. The fix will be included in the next builds of 14.0-CURRENT. |
@asomers Thank you! |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes, but it's dependent on the FreeBSD release. i.e. issue present on FreeBSD 13.1 and greater.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Tried to use the rclone program https://github.com/rclone/rclone to mount a remote filesystem. (rclone uses fuse behind the scenes.)
What did you expect to see?
(nothing) the rclone mount command should complete without error.
What did you see instead?
Discussion
The issue is discussed in FreeBSD bug 258056 https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=258056
That *BSD does not map regular files to polling is covered here #19093
Possible patch
Patch below adds "/dev/fuse" as another pollable = false exception.
The text was updated successfully, but these errors were encountered: