rclone/cmd/mount/mount.go
Nick Craig-Wood af8ba18580 mount: disable mount for freebsd
The upstream library rclone uses for rclone mount no longer supports
freebsd. Not only is it broken, but it no longer compiles.

This patch disables rclone mount for freebsd.

However all is not lost for freebsd users - compiling rclone with the
`cmount` tag, so `go install -tags cmount` will install a working
`rclone mount` command which uses cgofuse and the libfuse C library
directly.

Note that the binaries from rclone.org will not have mount support as
we don't have a freebsd build machine in CI and it is very hard to
cross compile cmount.

See: https://github.com/bazil/fuse/issues/280
Fixes #5843
2023-10-29 15:46:41 +00:00

116 lines
3 KiB
Go

//go:build linux
// +build linux
// Package mount implements a FUSE mounting system for rclone remotes.
package mount
import (
"fmt"
"runtime"
"bazil.org/fuse"
fusefs "bazil.org/fuse/fs"
"github.com/rclone/rclone/cmd/mountlib"
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/vfs"
)
func init() {
mountlib.NewMountCommand("mount", false, mount)
mountlib.AddRc("mount", mount)
}
// mountOptions configures the options from the command line flags
func mountOptions(VFS *vfs.VFS, device string, opt *mountlib.Options) (options []fuse.MountOption) {
options = []fuse.MountOption{
fuse.MaxReadahead(uint32(opt.MaxReadAhead)),
fuse.Subtype("rclone"),
fuse.FSName(device),
// Options from benchmarking in the fuse module
//fuse.MaxReadahead(64 * 1024 * 1024),
//fuse.WritebackCache(),
}
if opt.AsyncRead {
options = append(options, fuse.AsyncRead())
}
if opt.AllowOther {
options = append(options, fuse.AllowOther())
}
if opt.AllowRoot {
// options = append(options, fuse.AllowRoot())
fs.Errorf(nil, "Ignoring --allow-root. Support has been removed upstream - see https://github.com/bazil/fuse/issues/144 for more info")
}
if opt.DefaultPermissions {
options = append(options, fuse.DefaultPermissions())
}
if VFS.Opt.ReadOnly {
options = append(options, fuse.ReadOnly())
}
if opt.WritebackCache {
options = append(options, fuse.WritebackCache())
}
if opt.DaemonTimeout != 0 {
options = append(options, fuse.DaemonTimeout(fmt.Sprint(int(opt.DaemonTimeout.Seconds()))))
}
if len(opt.ExtraOptions) > 0 {
fs.Errorf(nil, "-o/--option not supported with this FUSE backend")
}
if len(opt.ExtraFlags) > 0 {
fs.Errorf(nil, "--fuse-flag not supported with this FUSE backend")
}
return options
}
// mount the file system
//
// The mount point will be ready when this returns.
//
// returns an error, and an error channel for the serve process to
// report an error when fusermount is called.
func mount(VFS *vfs.VFS, mountpoint string, opt *mountlib.Options) (<-chan error, func() error, error) {
f := VFS.Fs()
if runtime.GOOS == "darwin" {
fs.Logf(nil, "macOS users: please try \"rclone cmount\" as it will be the default in v1.54")
}
if err := mountlib.CheckOverlap(f, mountpoint); err != nil {
return nil, nil, err
}
if err := mountlib.CheckAllowNonEmpty(mountpoint, opt); err != nil {
return nil, nil, err
}
fs.Debugf(f, "Mounting on %q", mountpoint)
if opt.DebugFUSE {
fuse.Debug = func(msg interface{}) {
fs.Debugf("fuse", "%v", msg)
}
}
c, err := fuse.Mount(mountpoint, mountOptions(VFS, opt.DeviceName, opt)...)
if err != nil {
return nil, nil, err
}
filesys := NewFS(VFS, opt)
filesys.server = fusefs.New(c, nil)
// Serve the mount point in the background returning error to errChan
errChan := make(chan error, 1)
go func() {
err := filesys.server.Serve(filesys)
closeErr := c.Close()
if err == nil {
err = closeErr
}
errChan <- err
}()
unmount := func() error {
// Shutdown the VFS
filesys.VFS.Shutdown()
return fuse.Unmount(mountpoint)
}
return errChan, unmount, nil
}