diff --git a/example/autounionfs/main.go b/example/autounionfs/main.go index f70b9c950c0dea536f69d474d461973e712f9f1d..ce7da41938ba14e1c581ae2448127c4d15e1f89e 100644 --- a/example/autounionfs/main.go +++ b/example/autounionfs/main.go @@ -28,7 +28,7 @@ func main() { } options := unionfs.AutoUnionFsOptions{ UnionFsOptions: ufsOptions, - MountOptions: fuse.MountOptions{ + FileSystemOptions: fuse.FileSystemOptions{ EntryTimeout: 1.0, AttrTimeout: 1.0, NegativeTimeout: 1.0, diff --git a/example/loopback/loopback.go b/example/loopback/loopback.go index 6eccd010dd23643d2da6907c12a4a6e81eafaa61..4f51b53a7e2d40b17d0f5d99efe3b3a9f1a1d01d 100644 --- a/example/loopback/loopback.go +++ b/example/loopback/loopback.go @@ -39,7 +39,7 @@ func main() { finalFs = timing } - opts := &fuse.MountOptions{ + opts := &fuse.FileSystemOptions{ // These options are to be compatible with libfuse defaults, // making benchmarking easier. NegativeTimeout: 1.0, @@ -71,7 +71,7 @@ func main() { mountPoint := flag.Arg(0) fmt.Println("Mounting") - err := state.Mount(mountPoint) + err := state.Mount(mountPoint, nil) if err != nil { fmt.Printf("Mount fail: %v\n", err) os.Exit(1) diff --git a/fuse/api.go b/fuse/api.go index bc97071b17e64db562f9463e5e52d0554fbdf93f..d13807e2d6992360b20ebb0582f3262c99b8f23a 100644 --- a/fuse/api.go +++ b/fuse/api.go @@ -86,12 +86,16 @@ type File interface { // MountOptions contains time out options for a FileSystem. The // default copied from libfuse and set in NewMountOptions() is // (1s,1s,0s). -type MountOptions struct { +type FileSystemOptions struct { EntryTimeout float64 AttrTimeout float64 NegativeTimeout float64 } +type MountOptions struct { + AllowOther bool +} + // DefaultFileSystem implements a FileSystem that returns ENOSYS for every operation. type DefaultFileSystem struct{} diff --git a/fuse/fuse.go b/fuse/fuse.go index c28e85077d36dceb43d56a99a8bc6ced163b3743..d47183f44c2f60d13e7fac4aae9c0b1b4986b102 100644 --- a/fuse/fuse.go +++ b/fuse/fuse.go @@ -4,11 +4,11 @@ import ( "fmt" ) -func MountFileSystem(mountpoint string, fs FileSystem, opts *MountOptions) (*MountState, *FileSystemConnector, os.Error) { +func MountFileSystem(mountpoint string, fs FileSystem, opts *FileSystemOptions) (*MountState, *FileSystemConnector, os.Error) { conn := NewFileSystemConnector(fs, opts) mountState := NewMountState(conn) fmt.Printf("Go-FUSE Version %v.\nMounting...\n", Version()) - err := mountState.Mount(mountpoint) + err := mountState.Mount(mountpoint, nil) if err != nil { return nil, nil, err } diff --git a/fuse/loopback_test.go b/fuse/loopback_test.go index 4a84c2c571a6edea5378dffa11b4ac26e4a3b7d5..c602d7f8884e0595bdf023fabda52f40f33449b2 100644 --- a/fuse/loopback_test.go +++ b/fuse/loopback_test.go @@ -68,7 +68,7 @@ func (me *testCase) Setup(t *testing.T) { me.connector.Debug = true me.state = NewMountState(rfs) - me.state.Mount(me.mountPoint) + me.state.Mount(me.mountPoint, nil) //me.state.Debug = false me.state.Debug = true diff --git a/fuse/mount.go b/fuse/mount.go index 138d0a35e86083da74211bd79d14f353e85968af..ca6af7dcfa3feda9ab72757faa201a7c2382fb05 100644 --- a/fuse/mount.go +++ b/fuse/mount.go @@ -33,7 +33,7 @@ func Socketpair(network string) (l, r *os.File, err os.Error) { // Create a FUSE FS on the specified mount point. The returned // mount point is always absolute. -func mount(mountPoint string) (f *os.File, finalMountPoint string, err os.Error) { +func mount(mountPoint string, options string) (f *os.File, finalMountPoint string, err os.Error) { local, remote, err := Socketpair("unixgram") if err != nil { return @@ -50,8 +50,15 @@ func mount(mountPoint string) (f *os.File, finalMountPoint string, err os.Error) } mountPoint = filepath.Clean(filepath.Join(cwd, mountPoint)) } + + cmd := []string{"/bin/fusermount", mountPoint} + if options != "" { + cmd = append(cmd, "-o") + cmd = append(cmd, options) + } + proc, err := os.StartProcess("/bin/fusermount", - []string{"/bin/fusermount", mountPoint}, + cmd, &os.ProcAttr{ Env: []string{"_FUSE_COMMFD=3"}, Files: []*os.File{os.Stdin, os.Stdout, os.Stderr, remote}}) diff --git a/fuse/mountstate.go b/fuse/mountstate.go index df5a4d45e69e59a756e8e8d50ead0e5be7a75361..34f587267bb4fca16cfab068a580893bc7ce0e5c 100644 --- a/fuse/mountstate.go +++ b/fuse/mountstate.go @@ -45,8 +45,14 @@ func (me *MountState) MountPoint() string { } // Mount filesystem on mountPoint. -func (me *MountState) Mount(mountPoint string) os.Error { - file, mp, err := mount(mountPoint) +func (me *MountState) Mount(mountPoint string, opts *MountOptions) os.Error { + + optStr := "" + if opts != nil && opts.AllowOther { + optStr = "allow_other" + } + + file, mp, err := mount(mountPoint, optStr) if err != nil { return err } diff --git a/fuse/pathdebug_test.go b/fuse/pathdebug_test.go index 1e74ded5ae6314ae0a06addda8df81192a8fde69..04c250e11b6ccac7326fef98bd89c9072297b370 100644 --- a/fuse/pathdebug_test.go +++ b/fuse/pathdebug_test.go @@ -17,7 +17,7 @@ func TestPathDebug(t *testing.T) { defer os.RemoveAll(mountPoint) state := NewMountState(connector) - state.Mount(mountPoint) + state.Mount(mountPoint, nil) state.Debug = true defer state.Unmount() diff --git a/fuse/pathfilesystem.go b/fuse/pathfilesystem.go index 7892be33779f6c3e152dd9e81ce56c25dd9ee759..a6b9c1358c7be8d988ad5c43cc0a072fd2a19798 100644 --- a/fuse/pathfilesystem.go +++ b/fuse/pathfilesystem.go @@ -46,7 +46,7 @@ type mountData struct { // consider if we can measure significant contention for // multi-mount filesystems. - options *MountOptions + options *FileSystemOptions } func newMount(fs FileSystem) *mountData { @@ -165,8 +165,8 @@ func (me *inode) setParent(newParent *inode) { } } -func NewMountOptions() *MountOptions { - return &MountOptions{ +func NewFileSystemOptions() *FileSystemOptions { + return &FileSystemOptions{ NegativeTimeout: 0.0, AttrTimeout: 1.0, EntryTimeout: 1.0, @@ -422,7 +422,7 @@ func EmptyFileSystemConnector() (out *FileSystemConnector) { return out } -func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *MountOptions) Status { +func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *FileSystemOptions) Status { var node *inode if mountPoint != "/" { @@ -465,7 +465,7 @@ func (me *FileSystemConnector) Mount(mountPoint string, fs FileSystem, opts *Mou node.mount = newMount(fs) if opts == nil { - opts = NewMountOptions() + opts = NewFileSystemOptions() } node.mount.options = opts return OK diff --git a/fuse/pathops.go b/fuse/pathops.go index ab23d060a6673c462c087ad0f34acb94a25a00b6..cb870ff811f771baf76b7fa744205df85d09e81c 100644 --- a/fuse/pathops.go +++ b/fuse/pathops.go @@ -12,7 +12,7 @@ import ( var _ = fmt.Println -func NewFileSystemConnector(fs FileSystem, opts *MountOptions) (out *FileSystemConnector) { +func NewFileSystemConnector(fs FileSystem, opts *FileSystemOptions) (out *FileSystemConnector) { out = EmptyFileSystemConnector() if code := out.Mount("/", fs, opts); code != OK { panic("root mount failed.") diff --git a/unionfs/autounion.go b/unionfs/autounion.go index c06ba84afe5a71513fee722344322a14bcf3d82c..3f4d3b5637d2fada4d49ebecda569803a608509e 100644 --- a/unionfs/autounion.go +++ b/unionfs/autounion.go @@ -32,7 +32,7 @@ type AutoUnionFs struct { type AutoUnionFsOptions struct { UnionFsOptions - fuse.MountOptions + fuse.FileSystemOptions // If set, run updateKnownFses() after mounting. UpdateOnMount bool @@ -134,7 +134,7 @@ func (me *AutoUnionFs) addFs(name string, roots []string) (code fuse.Status) { } gofs, code := me.createFs(name, roots) if gofs != nil { - me.connector.Mount("/"+name, gofs, &me.options.MountOptions) + me.connector.Mount("/"+name, gofs, &me.options.FileSystemOptions) } return code } diff --git a/unionfs/autounion_test.go b/unionfs/autounion_test.go index 3a1c452b22ac838dd5f13d1dd3fcaec7596026e9..1ab7a7f30a29ae39db8bb7b69168f6bcb585f95d 100644 --- a/unionfs/autounion_test.go +++ b/unionfs/autounion_test.go @@ -17,7 +17,7 @@ const entryTtl = 0.1 var testAOpts = AutoUnionFsOptions{ UnionFsOptions: testOpts, - MountOptions: fuse.MountOptions{ + FileSystemOptions: fuse.FileSystemOptions{ EntryTimeout: entryTtl, AttrTimeout: entryTtl, NegativeTimeout: 0, @@ -44,7 +44,7 @@ func setup(t *testing.T) (workdir string, cleanup func()) { WriteFile(wd+"/ro/file2", "file2") fs := NewAutoUnionFs(wd+"/store", testAOpts) - state, _, err := fuse.MountFileSystem(wd + "/mount", fs, &testAOpts.MountOptions) + state, _, err := fuse.MountFileSystem(wd + "/mount", fs, &testAOpts.FileSystemOptions) CheckSuccess(err) state.Debug = true go state.Loop(false) diff --git a/unionfs/unionfs_test.go b/unionfs/unionfs_test.go index 2f68c460ae192f9ac774ec0421ec53bc22c1432c..bb289efcd577271cf3867f71e57608211b28c45c 100644 --- a/unionfs/unionfs_test.go +++ b/unionfs/unionfs_test.go @@ -42,7 +42,7 @@ func setupUfs(t *testing.T) (workdir string, cleanup func()) { fses = append(fses, fuse.NewLoopbackFileSystem(wd+"/ro")) ufs := NewUnionFs("testFs", fses, testOpts) - opts := &fuse.MountOptions{ + opts := &fuse.FileSystemOptions{ EntryTimeout: entryTtl, AttrTimeout: entryTtl, NegativeTimeout: entryTtl,