Skip to content
This repository has been archived by the owner on Dec 13, 2021. It is now read-only.

improve-hookfs #12

Merged
merged 2 commits into from
Apr 23, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
improve-hookfs
  • Loading branch information
qiffang committed Apr 23, 2019
commit 4b014a7a7a506cdfe2ce43ae1573733247efbc79
File renamed without changes.
10 changes: 4 additions & 6 deletions example/ex01/main.go → cmd/ex01/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,20 @@ package main
import (
"flag"
"fmt"
"github.com/qiffang/hookfs/pkg/example"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

osrg/hooks ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

"github.com/qiffang/hookfs/pkg/hookfs"
"math/rand"
"os"
"time"

hookfs "github.com/osrg/hookfs/hookfs"
//hookfs "github.com/osrg/hookfs/hookfs"
log "github.com/sirupsen/logrus"
)

func init() {
rand.Seed(time.Now().UnixNano())
}

func probab(percentage int) bool {
return rand.Intn(99) < percentage
}

func main() {
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "Usage of %s:\n", os.Args[0])
Expand All @@ -43,7 +41,7 @@ func main() {
}

func serve(original string, mountpoint string) {
fs, err := hookfs.NewHookFs(original, mountpoint, &MyHook{})
fs, err := hookfs.NewHookFs(original, mountpoint, &example.MyHook{})
if err != nil {
log.Fatal(err)
}
Expand Down
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/qiffang/hookfs

go 1.12

require (
github.com/hanwen/go-fuse v1.0.0
github.com/sirupsen/logrus v1.4.1
)
17 changes: 17 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/hanwen/go-fuse v1.0.0 h1:GxS9Zrn6c35/BnfiVsZVWmsG803xwE7eVRDvcf/BEVc=
github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/qiffang/hookfs v0.0.0-20180612002201-9afd0d5baf9f h1:b9X36mKCEznoe9t16NhQv3Y8Man/2t0dExJfl7nx8eE=
github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
9 changes: 7 additions & 2 deletions example/ex01/myhook.go → pkg/example/myhook.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package main
package example

import (
"math/rand"
"syscall"
"time"

hookfs "github.com/osrg/hookfs/hookfs"
hookfs "github.com/qiffang/hookfs/pkg/hookfs"
log "github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -206,3 +207,7 @@ func (h *MyHook) PostFsync(realRetCode int32, ctx hookfs.HookContext) (bool, err
}
return false, nil
}

func probab(percentage int) bool {
return rand.Intn(99) < percentage
}
16 changes: 13 additions & 3 deletions hookfs/file.go → pkg/hookfs/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,17 @@ func (h *hookFile) Allocate(off uint64, size uint64, mode uint32) fuse.Status {
return h.file.Allocate(off, size, mode)
}

// implements nodefs.Flock
func (h *hookFile) Flock(flags int) fuse.Status {
return h.file.Flock(flags)
//implements nodefs,GetLk
func (h *hookFile) GetLk(owner uint64, lk *fuse.FileLock, flags uint32, out *fuse.FileLock) (code fuse.Status) {
return h.file.GetLk(owner, lk, flags, out)
}

//implements nodefs.SetLk
func (h *hookFile) SetLk(owner uint64, lk *fuse.FileLock, flags uint32) (code fuse.Status) {
return h.file.SetLk(owner, lk, flags)
}

//implements nodefs,SetLkw
func (h *hookFile) SetLkw(owner uint64, lk *fuse.FileLock, flags uint32) (code fuse.Status) {
return h.file.SetLkw(owner, lk, flags)
}
50 changes: 49 additions & 1 deletion hookfs/fs.go → pkg/hookfs/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,40 @@ func (h *HookFs) Mknod(name string, mode uint32, dev uint32, context *fuse.Conte

// Rename implements hanwen/go-fuse/fuse/pathfs.FileSystem. You are not expected to call h manually.
func (h *HookFs) Rename(oldName string, newName string, context *fuse.Context) fuse.Status {
return h.fs.Rename(oldName, newName, context)
hook, hookEnabled := h.hook.(HookOnRename)
if hookEnabled {
preHooked, prehookCtx, prehookErr := hook.PreRename(oldName, newName)
if preHooked {
log.WithFields(log.Fields{
"h": h,
"prehookErr": prehookErr,
"prehookCtx": prehookCtx,
}).Debug("Rename: Prehooked")

if prehookErr != nil {
return fuse.ToStatus(prehookErr)
}
}
}

status := h.fs.Rename(oldName, newName, context)

if hookEnabled {
postHooked, posthookCtx, posthookErr := hook.PostRename(oldName, newName)
if postHooked {
log.WithFields(log.Fields{
"h": h,
"posthookErr": postHooked,
"posthookCtx": posthookCtx,
}).Debug("Rename: Posthooked")

if posthookErr != nil {
return fuse.ToStatus(posthookErr)
}
}
}

return status
}

// Rmdir implements hanwen/go-fuse/fuse/pathfs.FileSystem. You are not expected to call h manually.
Expand Down Expand Up @@ -340,3 +373,18 @@ func (h *HookFs) Serve() error {
server.Serve()
return nil
}

// Serve initiates the FUSE loop. Normally, callers should run Serve()
// and wait for it to exit, but tests will want to run this in a
// goroutine.
func (h *HookFs) ServeAsync() (*fuse.Server, error) {
server, err := newHookServer(h)
if err != nil {
return nil, err
}
go func() {
server.Serve()
}()

return server, nil
}
6 changes: 6 additions & 0 deletions hookfs/hook.go → pkg/hookfs/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,9 @@ type HookOnFsync interface {
PreFsync(path string, flags uint32) (hooked bool, ctx HookContext, err error)
PostFsync(realRetCode int32, prehookCtx HookContext) (hooked bool, err error)
}

// HookOnRename is called on rename
type HookOnRename interface {
PreRename(oldPatgh string, newPath string) (hooked bool, ctx HookContext, err error)
PostRename(oldPatgh string, newPath string) (hooked bool, ctx HookContext, err error)
}
76 changes: 76 additions & 0 deletions pkg/hookfs/hook_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package hookfs

import (
"fmt"
"github.com/hanwen/go-fuse/fuse"
"github.com/qiffang/hookfs/pkg/utils"
"log"
"os"
"path/filepath"
"syscall"
"testing"
"time"
)

func TestRenameHook_RenameHookRenameTest(t *testing.T) {
//init action
original := filepath.Join(string(filepath.Separator), "tmp", fmt.Sprintf("dev-%d", time.Now().Unix()))
mountpoint := filepath.Join(string(filepath.Separator), "tmp", fmt.Sprintf("mountpoint-%d", time.Now().Unix()))
newFuseServer(t, original, mountpoint)
//remember to call unmount after you do not use it
defer cleanUp(mountpoint, original)

//normal logic
log.Print(filepath.Join(mountpoint, "tsdb.txt"))
_, err := os.Create(filepath.Join(mountpoint, "tsdb.txt"))

if err != nil {
log.Printf("%v",err)
}

//rename should be failed
err = os.Rename(filepath.Join(mountpoint, "tsdb.txt"), filepath.Join(mountpoint, "tsdbNew.txt"))
utils.NotOk(t, err)
fmt.Println(err)
}

func newFuseServer(t *testing.T, original,mountpoint string)(*fuse.Server){
createDirIfAbsent(original)
createDirIfAbsent(mountpoint)
fs, err := NewHookFs(original, mountpoint, &TestRenameHook{})
utils.Ok(t, err)
server, err := fs.ServeAsync()
if err != nil {
log.Fatalf("start server failed, %v", err)
}
utils.Ok(t, err)

return server
}

func cleanUp(mountpoint string, original string) {
syscall.Unmount(mountpoint, -1)

os.RemoveAll(mountpoint)
os.RemoveAll(original)
fmt.Println("Done")
}

func createDirIfAbsent(name string) {
_, err := os.Stat(name)
if err != nil {
os.Mkdir(name, os.ModePerm)
}
}

type TestRenameHook struct{}

func (h *TestRenameHook) PreRename(oldPatgh string, newPath string) (hooked bool, ctx HookContext, err error) {
fmt.Printf("Pre renamed file from %s to %s \n", oldPatgh, newPath)
return true, nil, syscall.EIO
}

func (h *TestRenameHook) PostRename(oldPatgh string, newPath string) (hooked bool, ctx HookContext, err error) {
fmt.Printf("Post renamed file from %s to %s \n", oldPatgh, newPath)
return false, nil, nil
}
File renamed without changes.
File renamed without changes.
26 changes: 26 additions & 0 deletions pkg/utils/testutils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package utils

import (
"fmt"
"path/filepath"
"runtime"
"testing"
)

// Ok fails the test if an err is not nil.
func Ok(tb testing.TB, err error) {
if err != nil {
_, file, line, _ := runtime.Caller(1)
fmt.Printf("\033[31m%s:%d: unexpected error: %s\033[39m\n\n", filepath.Base(file), line, err.Error())
tb.FailNow()
}
}

// NotOk fails the test if an err is nil.
func NotOk(tb testing.TB, err error) {
if err == nil {
_, file, line, _ := runtime.Caller(1)
fmt.Printf("\033[31m%s:%d: expected error, got nothing \033[39m\n\n", filepath.Base(file), line)
tb.FailNow()
}
}