From 02f7da4b0c113709cca8a4531c74aa1232a8cd20 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Thu, 21 Apr 2022 20:28:09 +0100 Subject: [PATCH] mount: fix --devname and fusermount: unknown option 'fsname' when mounting via rc In this commit f4c40bf79ddfd17c mount: add --devname to set the device name sent to FUSE for mount display The --devname parameter was added. However it was soon noticed that attempting to mount via the rc gave this error: mount helper error: fusermount: unknown option 'fsname' mount FAILED: fusermount: exit status 1 This was because the DeviceName (and VolumeName) parameter was never being initialised when the mount was called via the rc. The fix for this was to refactor the rc interface so it called the same Mount method as the command line mount which initialised the DeviceName and VolumeName parameters properly. This also fixes the cmd/mount tests which were breaking in the same way but since they aren't normally run on the CI we didn't notice. Fixes #6044 --- cmd/mountlib/mount.go | 21 +++++++++++++-------- cmd/mountlib/rc.go | 15 +++------------ cmd/serve/docker/volume.go | 1 - vfs/vfstest/fs.go | 34 +++++++++++++++++----------------- 4 files changed, 33 insertions(+), 38 deletions(-) diff --git a/cmd/mountlib/mount.go b/cmd/mountlib/mount.go index 5a9b762a1..b0119dc12 100644 --- a/cmd/mountlib/mount.go +++ b/cmd/mountlib/mount.go @@ -78,6 +78,17 @@ type MountPoint struct { ErrChan <-chan error } +// NewMountPoint makes a new mounting structure +func NewMountPoint(mount MountFn, mountPoint string, f fs.Fs, mountOpt *Options, vfsOpt *vfscommon.Options) *MountPoint { + return &MountPoint{ + MountFn: mount, + MountPoint: mountPoint, + Fs: f, + MountOpt: *mountOpt, + VFSOpt: *vfsOpt, + } +} + // Global constants const ( MaxLeafSize = 1024 // don't pass file names longer than this @@ -167,14 +178,7 @@ func NewMountCommand(commandName string, hidden bool, mount MountFn) *cobra.Comm defer cmd.StartStats()() } - mnt := &MountPoint{ - MountFn: mount, - MountPoint: args[1], - Fs: cmd.NewFsDir(args), - MountOpt: Opt, - VFSOpt: vfsflags.Opt, - } - + mnt := NewMountPoint(mount, args[1], cmd.NewFsDir(args), &Opt, &vfsflags.Opt) daemon, err := mnt.Mount() // Wait for foreground mount, if any... @@ -253,6 +257,7 @@ func (m *MountPoint) Mount() (daemon *os.Process, err error) { if err != nil { return nil, fmt.Errorf("failed to mount FUSE fs: %w", err) } + m.MountedOn = time.Now() return nil, nil } diff --git a/cmd/mountlib/rc.go b/cmd/mountlib/rc.go index 2262ecfa8..7a89787fe 100644 --- a/cmd/mountlib/rc.go +++ b/cmd/mountlib/rc.go @@ -10,7 +10,6 @@ import ( "github.com/rclone/rclone/fs" "github.com/rclone/rclone/fs/rc" - "github.com/rclone/rclone/vfs" "github.com/rclone/rclone/vfs/vfsflags" ) @@ -117,23 +116,15 @@ func mountRc(ctx context.Context, in rc.Params) (out rc.Params, err error) { return nil, err } - VFS := vfs.New(fdst, &vfsOpt) - _, unmountFn, err := mountFn(VFS, mountPoint, &mountOpt) + mnt := NewMountPoint(mountFn, mountPoint, fdst, &mountOpt, &vfsOpt) + _, err = mnt.Mount() if err != nil { log.Printf("mount FAILED: %v", err) return nil, err } // Add mount to list if mount point was successfully created - liveMounts[mountPoint] = &MountPoint{ - MountPoint: mountPoint, - MountedOn: time.Now(), - MountFn: mountFn, - UnmountFn: unmountFn, - MountOpt: mountOpt, - VFSOpt: vfsOpt, - Fs: fdst, - } + liveMounts[mountPoint] = mnt fs.Debugf(nil, "Mount for %s created at %s using %s", fdst.String(), mountPoint, mountType) return nil, nil diff --git a/cmd/serve/docker/volume.go b/cmd/serve/docker/volume.go index 076736684..f774eef8d 100644 --- a/cmd/serve/docker/volume.go +++ b/cmd/serve/docker/volume.go @@ -274,7 +274,6 @@ func (vol *Volume) mount(id string) error { if _, err := vol.mnt.Mount(); err != nil { return err } - vol.mnt.MountedOn = time.Now() vol.mountReqs[id] = nil vol.drv.monChan <- false // ask monitor to refresh channels return nil diff --git a/vfs/vfstest/fs.go b/vfs/vfstest/fs.go index 3e7b47a0e..bb9a61fc5 100644 --- a/vfs/vfstest/fs.go +++ b/vfs/vfstest/fs.go @@ -102,16 +102,15 @@ func RunTests(t *testing.T, useVFS bool, fn mountlib.MountFn) { // Run holds the remotes for a test run type Run struct { - os Oser - vfs *vfs.VFS - useVFS bool // set if we are testing a VFS not a mount - mountPath string - fremote fs.Fs - fremoteName string - cleanRemote func() - umountResult <-chan error - umountFn mountlib.UnmountFn - skip bool + os Oser + vfs *vfs.VFS + useVFS bool // set if we are testing a VFS not a mount + mnt *mountlib.MountPoint + mountPath string + fremote fs.Fs + fremoteName string + cleanRemote func() + skip bool } // run holds the master Run data @@ -125,8 +124,7 @@ var run *Run // Finalise() will tidy them away when done. func newRun(useVFS bool) *Run { r := &Run{ - useVFS: useVFS, - umountResult: make(chan error, 1), + useVFS: useVFS, } fstest.Initialise() @@ -173,14 +171,16 @@ func findMountPath() string { func (r *Run) mount() { log.Printf("mount %q %q", r.fremote, r.mountPath) var err error - r.vfs = vfs.New(r.fremote, &vfsflags.Opt) - r.umountResult, r.umountFn, err = mountFn(r.vfs, r.mountPath, &mountlib.Opt) + r.mnt = mountlib.NewMountPoint(mountFn, r.mountPath, r.fremote, &mountlib.Opt, &vfsflags.Opt) + + _, err = r.mnt.Mount() if err != nil { log.Printf("mount FAILED: %v", err) r.skip = true } else { log.Printf("mount OK") } + r.vfs = r.mnt.VFS if r.useVFS { r.os = vfsOs{r.vfs} } else { @@ -202,17 +202,17 @@ func (r *Run) umount() { } */ log.Printf("Unmounting %q", r.mountPath) - err := r.umountFn() + err := r.mnt.Unmount() if err != nil { log.Printf("signal to umount failed - retrying: %v", err) time.Sleep(3 * time.Second) - err = r.umountFn() + err = r.mnt.Unmount() } if err != nil { log.Fatalf("signal to umount failed: %v", err) } log.Printf("Waiting for umount") - err = <-r.umountResult + err = <-r.mnt.ErrChan if err != nil { log.Fatalf("umount failed: %v", err) }