From 1aae43e32cadcfa182fc60777f20fb02673e8f82 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Fri, 22 Feb 2019 09:01:03 -0800 Subject: [PATCH] Mount: use device directly if we are root merged https://github.com/bazil/fuse/pull/195 --- mount_linux.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/mount_linux.go b/mount_linux.go index 197d1044..41d28949 100644 --- a/mount_linux.go +++ b/mount_linux.go @@ -55,10 +55,42 @@ func isBoringFusermountError(err error) bool { return false } +func mountdev(dir string, conf *mountConfig) (*os.File, error) { + f, err := os.OpenFile("/dev/fuse", os.O_RDWR, 0) + if err != nil { + return nil, err + } + + // no known use for conf in the system call *yet*. It took a while to find + // out what combination of strings would get past EINVAL. + data := fmt.Sprintf("fd=%d,rootmode=40000,user_id=0,group_id=0", f.Fd()) + mp := conf.options["fsname"] + st := conf.options["subtype"] + t := "fuse" + if st != "" { + t += "." + st + } + err = syscall.Mount(mp, dir, t, syscall.MS_NOSUID|syscall.MS_NODEV, data) + if err != nil { + return nil, err + } + return f, nil +} + func mount(dir string, conf *mountConfig, ready chan<- struct{}, errp *error) (fusefd *os.File, err error) { // linux mount is never delayed close(ready) + // if os.Getuid == 0, try mountdev. That could fail for all sorts of reasons, + // and if it does, just keep on this other path. + if os.Getuid() == 0 { + f, err := mountdev(dir, conf) + if err == nil { + return f, err + } + log.Printf("mount: mountdev failed with %v, trying fusermount", err) + } + fds, err := syscall.Socketpair(syscall.AF_FILE, syscall.SOCK_STREAM, 0) if err != nil { return nil, fmt.Errorf("socketpair error: %v", err)