diff options
| -rw-r--r-- | frontend/fe_file.go | 2 | ||||
| -rw-r--r-- | frontend/fe_fs.go | 10 | ||||
| -rw-r--r-- | main.go | 41 | ||||
| -rwxr-xr-x | main_benchmark.bash | 6 | ||||
| -rw-r--r-- | main_test.go | 149 | 
5 files changed, 190 insertions, 18 deletions
diff --git a/frontend/fe_file.go b/frontend/fe_file.go index b417227..4679589 100644 --- a/frontend/fe_file.go +++ b/frontend/fe_file.go @@ -68,7 +68,7 @@ func (f *File) Open(ctx context.Context, req *fuse.OpenRequest, resp *fuse.OpenR  func (f *File) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error { -	fmt.Printf("Read: o=%d l=%d\n", req.Offset, req.Size) +	cryptfs.Debug.Printf("Read: o=%d l=%d\n", req.Offset, req.Size)  	// Read the backing ciphertext in one go  	iblocks := f.crfs.SplitRange(uint64(req.Offset), uint64(req.Size)) diff --git a/frontend/fe_fs.go b/frontend/fe_fs.go index 4d49194..d1fa5b1 100644 --- a/frontend/fe_fs.go +++ b/frontend/fe_fs.go @@ -27,17 +27,17 @@ type nullTracer struct {}  func (nullTracer) Trace(op cluefs.FsOperTracer) {} -func NewFS(key [16]byte, backing string, useOpenssl bool) *FS { -	var nt nullTracer -	clfs, err := cluefs.NewClueFS(backing, nt) +func NewFS(key [16]byte, backing string, useOpenssl bool) (*FS, error) { +	var tracer nullTracer +	clfs, err := cluefs.NewClueFS(backing, tracer)  	if err != nil { -		panic(err) +		return nil, err  	}  	return &FS {  		CryptFS: cryptfs.NewCryptFS(key, useOpenssl),  		ClueFS: clfs,  		backing: backing, -	} +	}, nil  }  func (fs *FS) Root() (fusefs.Node, error) { @@ -1,29 +1,46 @@  package main  import ( -	"bazil.org/fuse" -	fusefs "bazil.org/fuse/fs" +	"path/filepath" +	"flag" +	"os"  	"fmt" -	"github.com/rfjakob/cluefs/lib/cluefs"  	"github.com/rfjakob/gocryptfs/frontend" -	"os" +	"bazil.org/fuse" +	fusefs "bazil.org/fuse/fs" +  )  const (  	PROGRAM_NAME = "gocryptfs"  	USE_OPENSSL = true + +	ERREXIT_USAGE = 1 +	ERREXIT_NEWFS = 2 +	ERREXIT_MOUNT = 3 +	ERREXIT_SERVE = 4 +	ERREXIT_MOUNT2 = 5  )  func main() {  	// Parse command line arguments -	conf, err := cluefs.ParseArguments() -	if err != nil { -		os.Exit(1) +	flag.Parse() +	if flag.NArg() < 2 { +		fmt.Printf("NArg=%d\n", flag.NArg()) +		fmt.Printf("usage: %s CIPHERDIR MOUNTPOINT\n", PROGRAM_NAME) +		os.Exit(ERREXIT_USAGE)  	} +	cipherdir, _ := filepath.Abs(flag.Arg(0)) +	mountpoint, err := filepath.Abs(flag.Arg(1)) +  	// Create the file system object  	var key [16]byte -	cfs := frontend.NewFS(key, conf.GetShadowDir(), USE_OPENSSL) +	cfs, err := frontend.NewFS(key, cipherdir, USE_OPENSSL) +	if err != nil { +		fmt.Println(err) +		os.Exit(ERREXIT_NEWFS) +	}  	// Mount the file system  	mountOpts := []fuse.MountOption{ @@ -33,24 +50,24 @@ func main() {  		fuse.LocalVolume(),  		fuse.MaxReadahead(1024*1024),  	} -	conn, err := fuse.Mount(conf.GetMountPoint(), mountOpts...) +	conn, err := fuse.Mount(mountpoint, mountOpts...)  	if err != nil {  		fmt.Println(err) -		os.Exit(1) +		os.Exit(ERREXIT_MOUNT)  	}  	defer conn.Close()  	// Start serving requests  	if err = fusefs.Serve(conn, cfs); err != nil {  		fmt.Println(err) -		os.Exit(1) +		os.Exit(ERREXIT_SERVE)  	}  	// Check for errors when mounting the file system  	<-conn.Ready  	if err = conn.MountError; err != nil {  		fmt.Println(err) -		os.Exit(1) +		os.Exit(ERREXIT_MOUNT2)  	}  	// We are done diff --git a/main_benchmark.bash b/main_benchmark.bash new file mode 100755 index 0000000..447581a --- /dev/null +++ b/main_benchmark.bash @@ -0,0 +1,6 @@ +#!/bin/bash + +set -eux + +go build +go test -bench=. diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000..f17b5f5 --- /dev/null +++ b/main_test.go @@ -0,0 +1,149 @@ +package main + +import ( +	"io" +	"fmt" +	"time" +	"testing" +	"os" +	"os/exec" +	"io/ioutil" +	"crypto/md5" +	"encoding/hex" +) + +const tmpDir = "test_tmp_dir/" +const plainDir = tmpDir + "plain/" +const cipherDir = tmpDir + "cipher/" + +func TestMain(m *testing.M) { + +	fu := exec.Command("fusermount", "-u", plainDir) +	fu.Stdout = os.Stdout +	fu.Stderr = os.Stderr +	fu.Run() +	os.RemoveAll(tmpDir) + +	err := os.MkdirAll(plainDir, 0777) +	if err != nil { +		panic("Could not create plainDir") +	} + +	err = os.MkdirAll(cipherDir, 0777) +	if err != nil { +		panic("Could not create cipherDir") +	} + +	c := exec.Command("./gocryptfs", cipherDir, plainDir) +	c.Stdout = os.Stdout +	c.Stderr = os.Stderr +	go c.Run() + +	time.Sleep(3 * time.Second) + +	r := m.Run() + + +	fu.Run() +	os.Exit(r) +} + +func testWriteN(t *testing.T, fn string, n int, hashWant string) { +	file, err := os.Create(plainDir + fn) +	if err != nil { +		t.FailNow() +	} + +	d := make([]byte, n) +	written, err := file.Write(d) +	if err != nil || written != len(d) { +		fmt.Printf("err=\"%s\", written=%d\n", err, written) +		t.Fail() +	} +	file.Close() + +	buf, err := ioutil.ReadFile(plainDir + fn) +	if err != nil { +		t.Fail() +	} + +	rawHash := md5.Sum(buf) +	hashActual := hex.EncodeToString(rawHash[:]) +	if hashActual != hashWant { +		fmt.Printf("hashWant=%s hashActual=%s\n", hashWant, hashActual) +		t.Fail() +	} +} + +func TestWrite10(t *testing.T) { +	testWriteN(t, "10", 10, "a63c90cc3684ad8b0a2176a6a8fe9005") +} + +func TestWrite100(t *testing.T) { +	testWriteN(t, "100", 100, "6d0bb00954ceb7fbee436bb55a8397a9") +} + +func TestWrite1M(t *testing.T) { +	testWriteN(t, "1M", 1024*1024, "b6d81b360a5672d80c27430f39153e2c") +} + +func TestWrite1Mx100(t *testing.T) { +	testWriteN(t, "1Mx100", 1024*1024, "b6d81b360a5672d80c27430f39153e2c") +	// Read and check 100 times to catch race conditions +	var i int +	for i = 0; i < 100; i++ { +		buf, err := ioutil.ReadFile(plainDir + "1M") +		if err != nil { +			t.Fail() +		} +		rawHash := md5.Sum(buf) +		hashActual := hex.EncodeToString(rawHash[:]) +		if hashActual != "b6d81b360a5672d80c27430f39153e2c" { +			fmt.Printf("Read corruption in loop # %d\n", i) +			t.FailNow() +		} else { +			//fmt.Print(".") +		} +	} +} + +func BenchmarkStreamWrite(t *testing.B) { +	buf := make([]byte, 1024*1024) +	t.SetBytes(int64(len(buf))) + +	file, err := os.Create(plainDir + "BenchmarkWrite") +	if err != nil { +		t.FailNow() +	} + +	t.ResetTimer() +	var i int +	for i = 0; i < t.N; i++ { +		written, err := file.Write(buf) +		if err != nil { +			fmt.Printf("err=\"%s\", written=%d\n", err.Error(), written) +			t.FailNow() +		} +	} +} + +func BenchmarkStreamRead(t *testing.B) { +	buf := make([]byte, 1024*1024) +	t.SetBytes(int64(len(buf))) +	file, err := os.Open(plainDir + "BenchmarkWrite") +	if err != nil { +		t.FailNow() +	} +	t.ResetTimer() +	var i int +	for i = 0; i < t.N; i++ { +		_, err := file.Read(buf) +		if err == io.EOF { +			fmt.Printf("Test file too small\n") +			t.SkipNow() +		} else if err != nil { +			fmt.Println(err) +			t.FailNow() +		} +	} +}  | 
