diff --git a/fuse/ipns/mount_unix.go b/fuse/ipns/mount_unix.go index e12330e20..731693c5f 100644 --- a/fuse/ipns/mount_unix.go +++ b/fuse/ipns/mount_unix.go @@ -19,34 +19,12 @@ func Mount(ipfs *core.IpfsNode, fpath string, ipfspath string) (mount.Mount, err log.Infof("Mounting ipns at %s...", fpath) // setup the Mount abstraction. - m := mount.New(ipfs.Context(), fpath, unmount) + m := mount.New(ipfs.Context(), fpath) // go serve the mount - mount.ServeMount(m, func(m mount.Mount) error { - - c, err := fuse.Mount(fpath) - if err != nil { - return err - } - defer c.Close() - - fsys, err := NewIpns(ipfs, ipfspath) - if err != nil { - return err - } - - log.Infof("Mounted ipns at %s.", fpath) - if err := fs.Serve(c, fsys); err != nil { - return err - } - - // check if the mount process has an error to report - <-c.Ready - if err := c.MountError; err != nil { - return err - } - return nil - }) + m.Mount(func(m mount.Mount) error { + return internalMount(ipfs, fpath, ipfspath) + }, internalUnmount) select { case <-m.Closed(): @@ -61,9 +39,37 @@ func Mount(ipfs *core.IpfsNode, fpath string, ipfspath string) (mount.Mount, err return m, nil } +// mount attempts to mount at the provided FUSE mount point +func internalMount(ipfs *core.IpfsNode, fpath string, ipfspath string) error { + + c, err := fuse.Mount(fpath) + if err != nil { + return err + } + defer c.Close() + + fsys, err := NewIpns(ipfs, ipfspath) + if err != nil { + return err + } + + log.Infof("Mounted ipns at %s.", fpath) + if err := fs.Serve(c, fsys); err != nil { + return err + } + + // check if the mount process has an error to report + <-c.Ready + if err := c.MountError; err != nil { + return err + } + return nil +} + // unmount attempts to unmount the provided FUSE mount point, forcibly // if necessary. -func unmount(point string) error { +func internalUnmount(m mount.Mount) error { + point := m.MountPoint() log.Infof("Unmounting ipns at %s...", point) var cmd *exec.Cmd diff --git a/fuse/mount/mount.go b/fuse/mount/mount.go index 35c41174d..484907dd4 100644 --- a/fuse/mount/mount.go +++ b/fuse/mount/mount.go @@ -19,23 +19,26 @@ type Mount interface { // MountPoint is the path at which this mount is mounted MountPoint() string + // Mount function sets up a mount + registers the unmount func + Mount(mount MountFunc, unmount UnmountFunc) + // Unmount calls Close. Unmount() error ctxc.ContextCloser } -// UnmountFunc is a function used to unmount a mount -type UnmountFunc func(mountpoint string) error +// UnmountFunc is a function used to Unmount a mount +type UnmountFunc func(Mount) error + +// MountFunc is a function used to Mount a mount +type MountFunc func(Mount) error // New constructs a new Mount instance. ctx is a context to wait upon, // the mountpoint is the directory that the mount was mounted at, and unmount // in an UnmountFunc to perform the unmounting logic. -func New(ctx context.Context, mountpoint string, unmount UnmountFunc) Mount { - m := &mount{ - mpoint: mountpoint, - unmount: unmount, - } +func New(ctx context.Context, mountpoint string) Mount { + m := &mount{mpoint: mountpoint} m.ContextCloser = ctxc.NewContextCloser(ctx, m.persistentUnmount) return m } @@ -50,10 +53,14 @@ type mount struct { // umount is called after the mount is closed. // TODO this is hacky, make it better. func (m *mount) persistentUnmount() error { + // no unmount func. + if m.unmount == nil { + return nil + } // ok try to unmount a whole bunch of times... for i := 0; i < 34; i++ { - err := m.unmount(m.mpoint) + err := m.unmount(m) if err == nil { return nil } @@ -72,8 +79,9 @@ func (m *mount) Unmount() error { return m.Close() } -func ServeMount(m Mount, mount func(Mount) error) { +func (m *mount) Mount(mount MountFunc, unmount UnmountFunc) { m.Children().Add(1) + m.unmount = unmount // go serve the mount go func() { diff --git a/fuse/readonly/readonly_unix.go b/fuse/readonly/readonly_unix.go index 6583aab79..0fb7a6129 100644 --- a/fuse/readonly/readonly_unix.go +++ b/fuse/readonly/readonly_unix.go @@ -165,32 +165,12 @@ func Mount(ipfs *core.IpfsNode, fpath string) (mount.Mount, error) { log.Infof("Mounting ipfs at %s...", fpath) // setup the Mount abstraction. - m := mount.New(ipfs.Context(), fpath, unmount) + m := mount.New(ipfs.Context(), fpath) // go serve the mount - mount.ServeMount(m, func(m mount.Mount) error { - - c, err := fuse.Mount(m.MountPoint()) - if err != nil { - return err - } - defer c.Close() - - fsys := FileSystem{Ipfs: ipfs} - - log.Infof("Mounted ipfs at %s.", fpath) - if err := fs.Serve(c, fsys); err != nil { - return err - } - - // check if the mount process has an error to report - <-c.Ready - if err := c.MountError; err != nil { - m.Unmount() - return err - } - return nil - }) + m.Mount(func(m mount.Mount) error { + return internalMount(ipfs, m) + }, internalUnmount) select { case <-m.Closed(): @@ -205,9 +185,34 @@ func Mount(ipfs *core.IpfsNode, fpath string) (mount.Mount, error) { return m, nil } -// Unmount attempts to unmount the provided FUSE mount point, forcibly +// mount attempts to mount the provided FUSE mount point +func internalMount(ipfs *core.IpfsNode, m mount.Mount) error { + c, err := fuse.Mount(m.MountPoint()) + if err != nil { + return err + } + defer c.Close() + + fsys := FileSystem{Ipfs: ipfs} + + log.Infof("Mounted ipfs at %s.", m.MountPoint()) + if err := fs.Serve(c, fsys); err != nil { + return err + } + + // check if the mount process has an error to report + <-c.Ready + if err := c.MountError; err != nil { + m.Unmount() + return err + } + return nil +} + +// unmount attempts to unmount the provided FUSE mount point, forcibly // if necessary. -func unmount(point string) error { +func internalUnmount(m mount.Mount) error { + point := m.MountPoint() log.Infof("Unmounting ipfs at %s...", point) var cmd *exec.Cmd