Files
kopia/internal/mount/mount_fuse.go
Eng Zer Jun 73e492c9db refactor: move from io/ioutil to io and os package (#1360)
* refactor: move from io/ioutil to io and os package

The io/ioutil package has been deprecated as of Go 1.16, see
https://golang.org/doc/go1.16#ioutil. This commit replaces the existing
io/ioutil functions with their new definitions in io and os packages.

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>

* chore: remove //nolint:gosec for os.ReadFile

At the time of this commit, the G304 rule of gosec does not include the
`os.ReadFile` function. We remove `//nolint:gosec` temporarily until
https://github.com/securego/gosec/pull/706 is merged.

Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
2021-10-06 08:39:10 -07:00

107 lines
2.3 KiB
Go

//go:build !windows && !freebsd && !openbsd
// +build !windows,!freebsd,!openbsd
package mount
import (
"context"
"os"
"time"
gofusefs "github.com/hanwen/go-fuse/v2/fs"
"github.com/hanwen/go-fuse/v2/fuse"
"github.com/pkg/errors"
"github.com/kopia/kopia/fs"
"github.com/kopia/kopia/internal/fusemount"
)
// we're serving read-only filesystem, cache some attributes for 30 seconds.
var cacheTimeout = 30 * time.Second
func (mo *Options) toFuseMountOptions() *gofusefs.Options {
o := &gofusefs.Options{
MountOptions: fuse.MountOptions{
AllowOther: mo.FuseAllowOther,
Name: "kopia",
FsName: "kopia",
Debug: os.Getenv("KOPIA_DEBUG_FUSE") != "",
},
EntryTimeout: &cacheTimeout,
AttrTimeout: &cacheTimeout,
NegativeTimeout: &cacheTimeout,
}
o.Options = append(o.Options, "noatime")
if mo.FuseAllowNonEmptyMount {
o.Options = append(o.Options, "nonempty")
}
return o
}
// Directory mounts the given directory using FUSE.
func Directory(ctx context.Context, entry fs.Directory, mountPoint string, mountOptions Options) (Controller, error) {
isTempDir := false
if mountPoint == "*" {
var err error
mountPoint, err = os.MkdirTemp("", "kopia-mount")
if err != nil {
return nil, errors.Wrap(err, "error creating temp directory")
}
isTempDir = true
}
if mountOptions.PreferWebDAV {
return newPosixWedavController(ctx, entry, mountPoint, isTempDir)
}
rootNode := fusemount.NewDirectoryNode(entry)
fuseServer, err := gofusefs.Mount(mountPoint, rootNode, mountOptions.toFuseMountOptions())
if err != nil {
return nil, errors.Wrap(err, "mounting error")
}
done := make(chan struct{})
go func() {
fuseServer.Wait()
close(done)
}()
return fuseController{mountPoint, fuseServer, done, isTempDir}, nil
}
type fuseController struct {
mountPoint string
fuseConnection *fuse.Server
done chan struct{}
isTempDir bool
}
func (fc fuseController) MountPath() string {
return fc.mountPoint
}
func (fc fuseController) Unmount(ctx context.Context) error {
if err := fc.fuseConnection.Unmount(); err != nil {
return errors.Wrap(err, "unmount error")
}
if fc.isTempDir {
if err := os.Remove(fc.mountPoint); err != nil {
return errors.Wrap(err, "unable to remove temporary mount point")
}
}
return nil
}
func (fc fuseController) Done() <-chan struct{} {
return fc.done
}