From aff348065b5d34791bf64cf25d2bcbbcf27f69e3 Mon Sep 17 00:00:00 2001 From: Aaron Bieber Date: Sat, 27 May 2017 16:12:10 -0600 Subject: [PATCH] update for pr #104 - go test runs and successfuly mounts a dir, but, doing an ls in said dir will result in 'device not configured'. - more info here: https://github.com/bazil/fuse/pull/104 --- error_freebsd.go | 2 + error_openbsd.go | 17 +++++ fs/fstestutil/mountinfo_openbsd.go | 7 ++ fs/serve_openbsd_test.go | 30 +++++++++ fuse.go | 2 +- fuse_kernel_freebsd.go | 2 + fuse_kernel_openbsd.go | 64 +++++++++++++++++++ fuse_openbsd.go | 6 ++ mount_openbsd.go | 32 ++++++++++ options_freebsd.go | 2 + options_openbsd.go | 30 +++++++++ options_test.go | 17 ++--- syscallx/asm.s | 8 +++ syscallx/fstestutil/mountinfo_openbsd.go | 7 ++ syscallx/fstestutil/mountinfo_openbsd.go.orig | 0 syscallx/generate | 13 +++- syscallx/mount_openbsd.go | 16 +++++ syscallx/mount_openbsd_386.go | 30 +++++++++ syscallx/mount_openbsd_amd64.go | 30 +++++++++ syscallx/syscall.go | 8 +++ syscallx/syscallx_openbsd.go | 19 ++++++ syscallx/syscallx_std.go | 2 +- syscallx/xattr_darwin_386.go | 7 ++ syscallx/xattr_darwin_amd64.go | 7 ++ syscallx/ztypes_openbsd.go | 7 ++ 25 files changed, 353 insertions(+), 12 deletions(-) create mode 100644 error_openbsd.go create mode 100644 fs/fstestutil/mountinfo_openbsd.go create mode 100644 fs/serve_openbsd_test.go create mode 100644 fuse_kernel_openbsd.go create mode 100644 fuse_openbsd.go create mode 100644 mount_openbsd.go create mode 100644 options_openbsd.go create mode 100644 syscallx/asm.s create mode 100644 syscallx/fstestutil/mountinfo_openbsd.go create mode 100644 syscallx/fstestutil/mountinfo_openbsd.go.orig create mode 100644 syscallx/mount_openbsd.go create mode 100644 syscallx/mount_openbsd_386.go create mode 100644 syscallx/mount_openbsd_amd64.go create mode 100644 syscallx/syscall.go create mode 100644 syscallx/syscallx_openbsd.go create mode 100644 syscallx/ztypes_openbsd.go diff --git a/error_freebsd.go b/error_freebsd.go index c6ea6d6e..98fb2148 100644 --- a/error_freebsd.go +++ b/error_freebsd.go @@ -1,3 +1,5 @@ +// +build freebsd + package fuse import "syscall" diff --git a/error_openbsd.go b/error_openbsd.go new file mode 100644 index 00000000..077bc421 --- /dev/null +++ b/error_openbsd.go @@ -0,0 +1,17 @@ +// +build openbsd + +package fuse + +import "syscall" + +const ( + ENOATTR = Errno(syscall.ENOATTR) +) + +const ( + errNoXattr = ENOATTR +) + +func init() { + errnoNames[errNoXattr] = "ENOATTR" +} diff --git a/fs/fstestutil/mountinfo_openbsd.go b/fs/fstestutil/mountinfo_openbsd.go new file mode 100644 index 00000000..ff498c04 --- /dev/null +++ b/fs/fstestutil/mountinfo_openbsd.go @@ -0,0 +1,7 @@ +package fstestutil + +import "errors" + +func getMountInfo(mnt string) (*MountInfo, error) { + return nil, errors.New("OpenBSD has no useful mount information") +} diff --git a/fs/serve_openbsd_test.go b/fs/serve_openbsd_test.go new file mode 100644 index 00000000..f716dc66 --- /dev/null +++ b/fs/serve_openbsd_test.go @@ -0,0 +1,30 @@ +package fs_test + +import ( + "testing" + + "bazil.org/fuse/fs/fstestutil" + "golang.org/x/sys/unix" +) + +type exchangeData struct { + fstestutil.File + // this struct cannot be zero size or multiple instances may look identical + _ int +} + +func TestExchangeDataNotSupported(t *testing.T) { + t.Parallel() + mnt, err := fstestutil.MountedT(t, fstestutil.SimpleFS{&fstestutil.ChildMap{ + "one": &exchangeData{}, + "two": &exchangeData{}, + }}, nil) + if err != nil { + t.Fatal(err) + } + defer mnt.Close() + + if err := unix.Exchangedata(mnt.Dir+"/one", mnt.Dir+"/two", 0); err != unix.ENOTSUP { + t.Fatalf("expected ENOTSUP from exchangedata: %v", err) + } +} diff --git a/fuse.go b/fuse.go index 6db0ef29..ecdd79fc 100644 --- a/fuse.go +++ b/fuse.go @@ -217,7 +217,7 @@ func initMount(c *Conn, conf *mountConfig) error { min := Protocol{protoVersionMinMajor, protoVersionMinMinor} if r.Kernel.LT(min) { - req.RespondError(Errno(syscall.EPROTO)) + req.RespondError(Errno(syscall.EIO)) c.Close() return &OldVersionError{ Kernel: r.Kernel, diff --git a/fuse_kernel_freebsd.go b/fuse_kernel_freebsd.go index b1141e41..3f3b917c 100644 --- a/fuse_kernel_freebsd.go +++ b/fuse_kernel_freebsd.go @@ -1,3 +1,5 @@ +// +build freebsd + package fuse import "time" diff --git a/fuse_kernel_openbsd.go b/fuse_kernel_openbsd.go new file mode 100644 index 00000000..5f057850 --- /dev/null +++ b/fuse_kernel_openbsd.go @@ -0,0 +1,64 @@ +// +build openbsd + +package fuse + +import "time" + +type attr struct { + Ino uint64 + Size uint64 + Blocks uint64 + Atime uint64 + Mtime uint64 + Ctime uint64 + AtimeNsec uint32 + MtimeNsec uint32 + CtimeNsec uint32 + Mode uint32 + Nlink uint32 + UID uint32 + Gid uint32 + Rdev uint32 + Blksize uint32 + padding uint32 +} + +func (a *attr) Crtime() time.Time { + return time.Time{} +} + +func (a *attr) SetCrtime(s uint64, ns uint32) { + // ignored on openbsd +} + +func (a *attr) SetFlags(f uint32) { + // ignored on openbsd +} + +type setattrIn struct { + setattrInCommon +} + +func (in *setattrIn) BkupTime() time.Time { + return time.Time{} +} + +func (in *setattrIn) Chgtime() time.Time { + return time.Time{} +} + +func (in *setattrIn) Flags() uint32 { + return 0 +} + +func openFlags(flags uint32) OpenFlags { + return OpenFlags(flags) +} + +type getxattrIn struct { + getxattrInCommon +} + +type setxattrIn struct { + setxattrInCommon +} diff --git a/fuse_openbsd.go b/fuse_openbsd.go new file mode 100644 index 00000000..4aa83a0d --- /dev/null +++ b/fuse_openbsd.go @@ -0,0 +1,6 @@ +package fuse + +// Maximum file write size we are prepared to receive from the kernel. +// +// This number is just a guess. +const maxWrite = 128 * 1024 diff --git a/mount_openbsd.go b/mount_openbsd.go new file mode 100644 index 00000000..6965a060 --- /dev/null +++ b/mount_openbsd.go @@ -0,0 +1,32 @@ +package fuse + +import ( + "fmt" + "os" + "unsafe" + + "bazil.org/fuse/syscallx" +) + +const fuseBufMaxSize = (1024 * 4096) + +func mount(dir string, conf *mountConfig, ready chan<- struct{}, errp *error) (*os.File, error) { + defer close(ready) + + fmt.Printf("mount(%v, %v)\n", dir, conf) + f, err := os.OpenFile("/dev/fuse0", os.O_RDWR, 0000) + if err != nil { + *errp = err + return nil, err + } + + fuse_args := syscallx.Fusefs_args{ + FD: int(f.Fd()), + MaxRead: fuseBufMaxSize, + } + + fmt.Printf("fusefs_args: %#v\n", fuse_args) + + err = syscallx.Mount("fuse", dir, 0, uintptr(unsafe.Pointer(&fuse_args))) + return f, err +} diff --git a/options_freebsd.go b/options_freebsd.go index 7c164b13..1aeb3d1a 100644 --- a/options_freebsd.go +++ b/options_freebsd.go @@ -1,3 +1,5 @@ +// +build freebsd + package fuse func localVolume(conf *mountConfig) error { diff --git a/options_openbsd.go b/options_openbsd.go new file mode 100644 index 00000000..2cd02f25 --- /dev/null +++ b/options_openbsd.go @@ -0,0 +1,30 @@ +// +build openbsd + +package fuse + +func localVolume(conf *mountConfig) error { + return nil +} + +func volumeName(name string) MountOption { + return dummyOption +} + +func daemonTimeout(name string) MountOption { + return func(conf *mountConfig) error { + conf.options["timeout"] = name + return nil + } +} + +func noAppleXattr(conf *mountConfig) error { + return nil +} + +func noAppleDouble(conf *mountConfig) error { + return nil +} + +func exclCreate(conf *mountConfig) error { + return nil +} diff --git a/options_test.go b/options_test.go index 965c00c9..7b978fbc 100644 --- a/options_test.go +++ b/options_test.go @@ -4,6 +4,7 @@ import ( "os" "runtime" "syscall" + "strings" "testing" "bazil.org/fuse" @@ -17,8 +18,8 @@ func init() { } func TestMountOptionFSName(t *testing.T) { - if runtime.GOOS == "freebsd" { - t.Skip("FreeBSD does not support FSName") + if strings.Contains(runtime.GOOS, "bsd") { + t.Skip("BSD does not support FSName") } t.Parallel() const name = "FuseTestMarker" @@ -40,8 +41,8 @@ func TestMountOptionFSName(t *testing.T) { } func testMountOptionFSNameEvil(t *testing.T, evil string) { - if runtime.GOOS == "freebsd" { - t.Skip("FreeBSD does not support FSName") + if strings.Contains(runtime.GOOS, "bsd") { + t.Skip("BSD does not support FSName") } t.Parallel() var name = "FuseTest" + evil + "Marker" @@ -97,8 +98,8 @@ func TestMountOptionSubtype(t *testing.T) { if runtime.GOOS == "darwin" { t.Skip("OS X does not support Subtype") } - if runtime.GOOS == "freebsd" { - t.Skip("FreeBSD does not support Subtype") + if strings.Contains(runtime.GOOS, "bsd") { + t.Skip("BSD does not support Subtype") } t.Parallel() const name = "FuseTestMarker" @@ -161,8 +162,8 @@ func (f unwritableFile) Attr(ctx context.Context, a *fuse.Attr) error { } func TestMountOptionDefaultPermissions(t *testing.T) { - if runtime.GOOS == "freebsd" { - t.Skip("FreeBSD does not support DefaultPermissions") + if strings.Contains(runtime.GOOS, "bsd") { + t.Skip("BSD do not support DefaultPermissions") } t.Parallel() diff --git a/syscallx/asm.s b/syscallx/asm.s new file mode 100644 index 00000000..d4ca868f --- /dev/null +++ b/syscallx/asm.s @@ -0,0 +1,8 @@ +// Copyright 2014 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "textflag.h" + +TEXT ·use(SB),NOSPLIT,$0 + RET diff --git a/syscallx/fstestutil/mountinfo_openbsd.go b/syscallx/fstestutil/mountinfo_openbsd.go new file mode 100644 index 00000000..ff498c04 --- /dev/null +++ b/syscallx/fstestutil/mountinfo_openbsd.go @@ -0,0 +1,7 @@ +package fstestutil + +import "errors" + +func getMountInfo(mnt string) (*MountInfo, error) { + return nil, errors.New("OpenBSD has no useful mount information") +} diff --git a/syscallx/fstestutil/mountinfo_openbsd.go.orig b/syscallx/fstestutil/mountinfo_openbsd.go.orig new file mode 100644 index 00000000..e69de29b diff --git a/syscallx/generate b/syscallx/generate index 476a282b..9fd19976 100755 --- a/syscallx/generate +++ b/syscallx/generate @@ -1,7 +1,7 @@ #!/bin/sh set -e -mksys="$(go env GOROOT)/src/pkg/syscall/mksyscall.pl" +mksys="$(go env GOROOT)/src/syscall/mksyscall.pl" fix() { sed 's,^package syscall$,&x\nimport "syscall",' \ @@ -12,7 +12,8 @@ fix() { | gofmt -r='SYS_LISTXATTR -> syscall.SYS_LISTXATTR' \ | gofmt -r='SYS_SETXATTR -> syscall.SYS_SETXATTR' \ | gofmt -r='SYS_REMOVEXATTR -> syscall.SYS_REMOVEXATTR' \ - | gofmt -r='SYS_MSYNC -> syscall.SYS_MSYNC' + | gofmt -r='SYS_MSYNC -> syscall.SYS_MSYNC' \ + | gofmt -r='SYS_MOUNT -> syscall.SYS_MOUNT' } cd "$(dirname "$0")" @@ -32,3 +33,11 @@ $mksys msync.go \ $mksys -l32 msync.go \ | fix \ >msync_386.go + +$mksys mount_openbsd.go \ + | fix \ + > mount_openbsd_amd64.go + +$mksys -l32 mount_openbsd.go \ + | fix \ + > mount_openbsd_386.go diff --git a/syscallx/mount_openbsd.go b/syscallx/mount_openbsd.go new file mode 100644 index 00000000..ff375c64 --- /dev/null +++ b/syscallx/mount_openbsd.go @@ -0,0 +1,16 @@ +package syscallx + +import "fmt" + +/* This is the source file for syscallx_darwin_*.go, to regenerate run + + ./generate + +*/ + +//sys mount(tpe string, dir string, flags int, data uintptr) (err error) + +func Mount(tpe string, dir string, flags int, data uintptr) (err error) { + fmt.Printf("mount(%v, %v, %v, %v)\n", tpe, dir, flags, data) + return mount(tpe, dir, flags, data) +} diff --git a/syscallx/mount_openbsd_386.go b/syscallx/mount_openbsd_386.go new file mode 100644 index 00000000..cc5af7e8 --- /dev/null +++ b/syscallx/mount_openbsd_386.go @@ -0,0 +1,30 @@ +// mksyscall.pl -l32 mount_openbsd.go +// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT + +package syscallx + +import "syscall" + +import "unsafe" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mount(tpe string, dir string, flags int, data uintptr) (err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(tpe) + if err != nil { + return + } + var _p1 *byte + _p1, err = syscall.BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall.Syscall6(syscall.SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + use(unsafe.Pointer(_p0)) + use(unsafe.Pointer(_p1)) + if e1 != 0 { + err = e1 + } + return +} diff --git a/syscallx/mount_openbsd_amd64.go b/syscallx/mount_openbsd_amd64.go new file mode 100644 index 00000000..4a558b24 --- /dev/null +++ b/syscallx/mount_openbsd_amd64.go @@ -0,0 +1,30 @@ +// mksyscall.pl mount_openbsd.go +// MACHINE GENERATED BY THE COMMAND ABOVE; DO NOT EDIT + +package syscallx + +import "syscall" + +import "unsafe" + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func mount(tpe string, dir string, flags int, data uintptr) (err error) { + var _p0 *byte + _p0, err = syscall.BytePtrFromString(tpe) + if err != nil { + return + } + var _p1 *byte + _p1, err = syscall.BytePtrFromString(dir) + if err != nil { + return + } + _, _, e1 := syscall.Syscall6(syscall.SYS_MOUNT, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(flags), uintptr(data), 0, 0) + use(unsafe.Pointer(_p0)) + use(unsafe.Pointer(_p1)) + if e1 != 0 { + err = e1 + } + return +} diff --git a/syscallx/syscall.go b/syscallx/syscall.go new file mode 100644 index 00000000..40ca4ef4 --- /dev/null +++ b/syscallx/syscall.go @@ -0,0 +1,8 @@ +package syscallx + +import "unsafe" + +// use is a no-op, but the compiler cannot see that it is. +// Calling use(p) ensures that p is kept live until that point. +//go:noescape +func use(p unsafe.Pointer) diff --git a/syscallx/syscallx_openbsd.go b/syscallx/syscallx_openbsd.go new file mode 100644 index 00000000..8595e3a6 --- /dev/null +++ b/syscallx/syscallx_openbsd.go @@ -0,0 +1,19 @@ +package syscallx + +import "errors" + +func Getxattr(path string, attr string, dest []byte) (sz int, err error) { + return 0, errors.New("not implemented") +} + +func Listxattr(path string, dest []byte) (sz int, err error) { + return 0, errors.New("not implemented") +} + +func Setxattr(path string, attr string, data []byte, flags int) (err error) { + return errors.New("not implemented") +} + +func Removexattr(path string, attr string) (err error) { + return errors.New("not implemented") +} diff --git a/syscallx/syscallx_std.go b/syscallx/syscallx_std.go index c0187a6b..8e18d1a5 100644 --- a/syscallx/syscallx_std.go +++ b/syscallx/syscallx_std.go @@ -1,4 +1,4 @@ -// +build !darwin +// +build !darwin,!openbsd package syscallx diff --git a/syscallx/xattr_darwin_386.go b/syscallx/xattr_darwin_386.go index ffc357ae..1da7fcfd 100644 --- a/syscallx/xattr_darwin_386.go +++ b/syscallx/xattr_darwin_386.go @@ -21,6 +21,8 @@ func getxattr(path string, attr string, dest *byte, size int, position uint32, o return } r0, _, e1 := syscall.Syscall6(syscall.SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) + use(unsafe.Pointer(_p0)) + use(unsafe.Pointer(_p1)) sz = int(r0) if e1 != 0 { err = e1 @@ -43,6 +45,7 @@ func listxattr(path string, dest []byte, options int) (sz int, err error) { _p1 = unsafe.Pointer(&_zero) } r0, _, e1 := syscall.Syscall6(syscall.SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(options), 0, 0) + use(unsafe.Pointer(_p0)) sz = int(r0) if e1 != 0 { err = e1 @@ -70,6 +73,8 @@ func setxattr(path string, attr string, data []byte, position uint32, flags int) _p2 = unsafe.Pointer(&_zero) } _, _, e1 := syscall.Syscall6(syscall.SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(position), uintptr(flags)) + use(unsafe.Pointer(_p0)) + use(unsafe.Pointer(_p1)) if e1 != 0 { err = e1 } @@ -90,6 +95,8 @@ func removexattr(path string, attr string, options int) (err error) { return } _, _, e1 := syscall.Syscall(syscall.SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) + use(unsafe.Pointer(_p0)) + use(unsafe.Pointer(_p1)) if e1 != 0 { err = e1 } diff --git a/syscallx/xattr_darwin_amd64.go b/syscallx/xattr_darwin_amd64.go index 864c4c1d..6d9c33fa 100644 --- a/syscallx/xattr_darwin_amd64.go +++ b/syscallx/xattr_darwin_amd64.go @@ -21,6 +21,8 @@ func getxattr(path string, attr string, dest *byte, size int, position uint32, o return } r0, _, e1 := syscall.Syscall6(syscall.SYS_GETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(unsafe.Pointer(dest)), uintptr(size), uintptr(position), uintptr(options)) + use(unsafe.Pointer(_p0)) + use(unsafe.Pointer(_p1)) sz = int(r0) if e1 != 0 { err = e1 @@ -43,6 +45,7 @@ func listxattr(path string, dest []byte, options int) (sz int, err error) { _p1 = unsafe.Pointer(&_zero) } r0, _, e1 := syscall.Syscall6(syscall.SYS_LISTXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(_p1), uintptr(len(dest)), uintptr(options), 0, 0) + use(unsafe.Pointer(_p0)) sz = int(r0) if e1 != 0 { err = e1 @@ -70,6 +73,8 @@ func setxattr(path string, attr string, data []byte, position uint32, flags int) _p2 = unsafe.Pointer(&_zero) } _, _, e1 := syscall.Syscall6(syscall.SYS_SETXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(_p2), uintptr(len(data)), uintptr(position), uintptr(flags)) + use(unsafe.Pointer(_p0)) + use(unsafe.Pointer(_p1)) if e1 != 0 { err = e1 } @@ -90,6 +95,8 @@ func removexattr(path string, attr string, options int) (err error) { return } _, _, e1 := syscall.Syscall(syscall.SYS_REMOVEXATTR, uintptr(unsafe.Pointer(_p0)), uintptr(unsafe.Pointer(_p1)), uintptr(options)) + use(unsafe.Pointer(_p0)) + use(unsafe.Pointer(_p1)) if e1 != 0 { err = e1 } diff --git a/syscallx/ztypes_openbsd.go b/syscallx/ztypes_openbsd.go new file mode 100644 index 00000000..07b4ec99 --- /dev/null +++ b/syscallx/ztypes_openbsd.go @@ -0,0 +1,7 @@ +package syscallx + +type Fusefs_args struct { + Name string + FD int + MaxRead int +}