Skip to content

Commit

Permalink
Merge pull request #853 from jbenet/noFuse
Browse files Browse the repository at this point in the history
simple nofuse build tag
  • Loading branch information
jbenet committed Mar 5, 2015
2 parents 2d16d25 + 40e0a5a commit 4b7493e
Show file tree
Hide file tree
Showing 14 changed files with 204 additions and 145 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ install:
build:
cd cmd/ipfs && go build -i

nofuse:
cd cmd/ipfs && go install -tags nofuse

##############################################################
# tests targets

Expand Down
28 changes: 28 additions & 0 deletions core/commands/mount_nofuse.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// +build (linux darwin freebsd) and nofuse

package commands

import (
"errors"

cmds "github.com/jbenet/go-ipfs/commands"
"github.com/jbenet/go-ipfs/core"
)

var MountCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Mounts IPFS to the filesystem (disabled)",
ShortDescription: `
This version of ipfs is compiled without fuse support, which is required
for mounting. If you'd like to be able to mount, please use a version of
ipfs compiled with fuse.
For the latest instructions, please check the project's repository:
http://github.com/jbenet/go-ipfs
`,
},
}

func Mount(node *core.IpfsNode, fsdir, nsdir string) error {
return errors.New("not compiled in")
}
2 changes: 1 addition & 1 deletion core/commands/mount_unix.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// +build linux darwin freebsd
// +build (linux darwin freebsd) and !nofuse

package commands

Expand Down
37 changes: 37 additions & 0 deletions fuse/ipns/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ipns

import (
"github.com/jbenet/go-ipfs/core"
mdag "github.com/jbenet/go-ipfs/merkledag"
nsys "github.com/jbenet/go-ipfs/namesys"
ci "github.com/jbenet/go-ipfs/p2p/crypto"
ft "github.com/jbenet/go-ipfs/unixfs"
)

// InitializeKeyspace sets the ipns record for the given key to
// point to an empty directory.
func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error {
emptyDir := &mdag.Node{Data: ft.FolderPBData()}
nodek, err := n.DAG.Add(emptyDir)
if err != nil {
return err
}

err = n.Pinning.Pin(emptyDir, false)
if err != nil {
return err
}

err = n.Pinning.Flush()
if err != nil {
return err
}

pub := nsys.NewRoutingPublisher(n.Routing)
err = pub.Publish(n.Context(), key, nodek)
if err != nil {
return err
}

return nil
}
4 changes: 3 additions & 1 deletion fuse/ipns/ipns_test.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
// +build !nofuse

package ipns

import (
"bytes"
"crypto/rand"
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
"io/ioutil"
"os"
"testing"
"time"

fstest "github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs/fstestutil"
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"

core "github.com/jbenet/go-ipfs/core"
u "github.com/jbenet/go-ipfs/util"
Expand Down
31 changes: 2 additions & 29 deletions fuse/ipns/ipns_unix.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// +build !nofuse

// package fuse/ipns implements a fuse filesystem that interfaces
// with ipns, the naming system for ipfs.
package ipns
Expand All @@ -18,7 +20,6 @@ import (
core "github.com/jbenet/go-ipfs/core"
chunk "github.com/jbenet/go-ipfs/importer/chunk"
mdag "github.com/jbenet/go-ipfs/merkledag"
nsys "github.com/jbenet/go-ipfs/namesys"
ci "github.com/jbenet/go-ipfs/p2p/crypto"
path "github.com/jbenet/go-ipfs/path"
ft "github.com/jbenet/go-ipfs/unixfs"
Expand All @@ -37,34 +38,6 @@ var (
longRepublishTimeout = time.Millisecond * 500
)

// InitializeKeyspace sets the ipns record for the given key to
// point to an empty directory.
func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error {
emptyDir := &mdag.Node{Data: ft.FolderPBData()}
nodek, err := n.DAG.Add(emptyDir)
if err != nil {
return err
}

err = n.Pinning.Pin(emptyDir, false)
if err != nil {
return err
}

err = n.Pinning.Flush()
if err != nil {
return err
}

pub := nsys.NewRoutingPublisher(n.Routing)
err = pub.Publish(n.Context(), key, nodek)
if err != nil {
return err
}

return nil
}

// FileSystem is the readwrite IPNS Fuse Filesystem.
type FileSystem struct {
Ipfs *core.IpfsNode
Expand Down
2 changes: 2 additions & 0 deletions fuse/ipns/link_unix.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// +build !nofuse

package ipns

import (
Expand Down
2 changes: 1 addition & 1 deletion fuse/ipns/mount_unix.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// +build linux darwin freebsd
// +build (linux darwin freebsd) and !nofuse

package ipns

Expand Down
2 changes: 2 additions & 0 deletions fuse/ipns/repub_unix.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// +build !nofuse

package ipns

import "time"
Expand Down
121 changes: 121 additions & 0 deletions fuse/mount/fuse.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// +build !nofuse

package mount

import (
"fmt"
"time"

"github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/bazil.org/fuse/fs"
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-ctxgroup"
)

// mount implements go-ipfs/fuse/mount
type mount struct {
mpoint string
filesys fs.FS
fuseConn *fuse.Conn
// closeErr error

cg ctxgroup.ContextGroup
}

// Mount mounts a fuse fs.FS at a given location, and returns a Mount instance.
// parent is a ContextGroup to bind the mount's ContextGroup to.
func NewMount(p ctxgroup.ContextGroup, fsys fs.FS, mountpoint string) (Mount, error) {
conn, err := fuse.Mount(mountpoint)
if err != nil {
return nil, err
}

m := &mount{
mpoint: mountpoint,
fuseConn: conn,
filesys: fsys,
cg: ctxgroup.WithParent(p), // link it to parent.
}
m.cg.SetTeardown(m.unmount)

// launch the mounting process.
if err := m.mount(); err != nil {
m.Unmount() // just in case.
return nil, err
}

return m, nil
}

func (m *mount) mount() error {
log.Infof("Mounting %s", m.MountPoint())

errs := make(chan error, 1)
go func() {
err := fs.Serve(m.fuseConn, m.filesys)
log.Debugf("Mounting %s -- fs.Serve returned (%s)", err)
errs <- err
close(errs)
}()

// wait for the mount process to be done, or timed out.
select {
case <-time.After(MountTimeout):
return fmt.Errorf("Mounting %s timed out.", m.MountPoint())
case err := <-errs:
return err
case <-m.fuseConn.Ready:
}

// check if the mount process has an error to report
if err := m.fuseConn.MountError; err != nil {
return err
}

log.Infof("Mounted %s", m.MountPoint())
return nil
}

// umount is called exactly once to unmount this service.
// note that closing the connection will not always unmount
// properly. If that happens, we bring out the big guns
// (mount.ForceUnmountManyTimes, exec unmount).
func (m *mount) unmount() error {
log.Infof("Unmounting %s", m.MountPoint())

// try unmounting with fuse lib
err := fuse.Unmount(m.MountPoint())
if err == nil {
return nil
}
log.Debug("fuse unmount err: %s", err)

// try closing the fuseConn
err = m.fuseConn.Close()
if err == nil {
return nil
}
if err != nil {
log.Debug("fuse conn error: %s", err)
}

// try mount.ForceUnmountManyTimes
if err := ForceUnmountManyTimes(m, 10); err != nil {
return err
}

log.Infof("Seemingly unmounted %s", m.MountPoint())
return nil
}

func (m *mount) CtxGroup() ctxgroup.ContextGroup {
return m.cg
}

func (m *mount) MountPoint() string {
return m.mpoint
}

func (m *mount) Unmount() error {
// call ContextCloser Close(), which calls unmount() exactly once.
return m.cg.Close()
}
Loading

0 comments on commit 4b7493e

Please sign in to comment.