mirror of
https://github.com/rclone/rclone.git
synced 2024-12-22 19:43:45 +08:00
70 lines
1.9 KiB
Go
70 lines
1.9 KiB
Go
|
//go:build darwin && !cmount
|
||
|
// +build darwin,!cmount
|
||
|
|
||
|
// Package nfsmount implements mounting functionality using serve nfs command
|
||
|
//
|
||
|
// NFS mount is only needed for macOS since it has no
|
||
|
// support for FUSE-based file systems
|
||
|
package nfsmount
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"net"
|
||
|
"os/exec"
|
||
|
"runtime"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/rclone/rclone/cmd/mountlib"
|
||
|
"github.com/rclone/rclone/cmd/serve/nfs"
|
||
|
"github.com/rclone/rclone/vfs"
|
||
|
)
|
||
|
|
||
|
func init() {
|
||
|
cmd := mountlib.NewMountCommand("mount", false, mount)
|
||
|
cmd.Aliases = append(cmd.Aliases, "nfsmount")
|
||
|
mountlib.AddRc("nfsmount", mount)
|
||
|
}
|
||
|
|
||
|
func mount(VFS *vfs.VFS, mountpoint string, opt *mountlib.Options) (asyncerrors <-chan error, unmount func() error, err error) {
|
||
|
s, err := nfs.NewServer(context.Background(), VFS, &nfs.Options{})
|
||
|
if err != nil {
|
||
|
return
|
||
|
}
|
||
|
errChan := make(chan error, 1)
|
||
|
go func() {
|
||
|
errChan <- s.Serve()
|
||
|
}()
|
||
|
// The port is always picked at random after the NFS server has started
|
||
|
// we need to query the server for the port number so we can mount it
|
||
|
_, port, err := net.SplitHostPort(s.Addr().String())
|
||
|
if err != nil {
|
||
|
err = fmt.Errorf("cannot find port number in %s", s.Addr().String())
|
||
|
return
|
||
|
}
|
||
|
optionsString := strings.Join(opt.ExtraOptions, ",")
|
||
|
err = exec.Command("mount", fmt.Sprintf("-oport=%s,mountport=%s,%s", port, port, optionsString), "localhost:", mountpoint).Run()
|
||
|
if err != nil {
|
||
|
err = fmt.Errorf("failed to mount NFS volume %e", err)
|
||
|
return
|
||
|
}
|
||
|
asyncerrors = errChan
|
||
|
unmount = func() error {
|
||
|
var umountErr error
|
||
|
if runtime.GOOS == "darwin" {
|
||
|
umountErr = exec.Command("diskutil", "umount", "force", mountpoint).Run()
|
||
|
} else {
|
||
|
umountErr = exec.Command("umount", "-f", mountpoint).Run()
|
||
|
}
|
||
|
shutdownErr := s.Shutdown()
|
||
|
VFS.Shutdown()
|
||
|
if umountErr != nil {
|
||
|
return fmt.Errorf("failed to umount the NFS volume %e", umountErr)
|
||
|
} else if shutdownErr != nil {
|
||
|
return fmt.Errorf("failed to shutdown NFS server: %e", shutdownErr)
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
return
|
||
|
}
|