Commit 8bfe84d5 authored by Ivan Krasin's avatar Ivan Krasin

It works: at least it starts w/o errors

parent d6600466
...@@ -6,7 +6,6 @@ import ( ...@@ -6,7 +6,6 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"fmt" "fmt"
"log"
"net" "net"
"os" "os"
"path" "path"
...@@ -18,18 +17,18 @@ const ( ...@@ -18,18 +17,18 @@ const (
bufSize = 66000 bufSize = 66000
) )
type FileSystem interface{ type FileSystem interface {
Init(in *InitIn) (out *InitOut, code Error) Init(in *InitIn) (out *InitOut, code Error)
} }
type MountPoint struct { type MountPoint struct {
mountPoint string mountPoint string
f *os.File f *os.File
fs FileSystem fs FileSystem
} }
// Mount create a fuse fs on the specified mount point. // Mount create a fuse fs on the specified mount point.
func Mount(mountPoint string, fs FileSystem) (m *MountPoint, err os.Error) { func Mount(mountPoint string, fs FileSystem) (m *MountPoint, err os.Error, errors chan os.Error) {
local, remote, err := net.Socketpair("unixgram") local, remote, err := net.Socketpair("unixgram")
if err != nil { if err != nil {
return return
...@@ -59,7 +58,8 @@ func Mount(mountPoint string, fs FileSystem) (m *MountPoint, err os.Error) { ...@@ -59,7 +58,8 @@ func Mount(mountPoint string, fs FileSystem) (m *MountPoint, err os.Error) {
return return
} }
if w.ExitStatus() != 0 { if w.ExitStatus() != 0 {
return nil, os.NewError(fmt.Sprintf("fusermount exited with code %d\n", w.ExitStatus())) err = os.NewError(fmt.Sprintf("fusermount exited with code %d\n", w.ExitStatus()))
return
} }
f, err := getFuseConn(local) f, err := getFuseConn(local)
...@@ -67,27 +67,29 @@ func Mount(mountPoint string, fs FileSystem) (m *MountPoint, err os.Error) { ...@@ -67,27 +67,29 @@ func Mount(mountPoint string, fs FileSystem) (m *MountPoint, err os.Error) {
return return
} }
m = &MountPoint{mountPoint, f, fs} m = &MountPoint{mountPoint, f, fs}
go m.loop() errors = make(chan os.Error, 100)
go m.loop(errors)
return return
} }
func (m *MountPoint) loop() { func (m *MountPoint) loop(errors chan os.Error) {
buf := make([]byte, bufSize) buf := make([]byte, bufSize)
f := m.f f := m.f
errors := make(chan os.Error, 100) defer close(errors)
toW := make(chan [][]byte, 100) toW := make(chan [][]byte, 100)
go m.errorHandler(errors) defer close(toW)
go m.writer(f, toW, errors) go m.writer(f, toW, errors)
for { for {
n, err := f.Read(buf) n, err := f.Read(buf)
if err != nil {
errors <- err
}
if err == os.EOF { if err == os.EOF {
break break
} }
if err != nil {
errors <- os.NewError(fmt.Sprintf("Failed to read from fuse conn: %v", err))
break
}
go handle(m.fs, buf[0:n], toW, errors) handle(m.fs, buf[0:n], toW, errors)
} }
} }
...@@ -105,19 +107,23 @@ func handle(fs FileSystem, in_data []byte, toW chan [][]byte, errors chan os.Err ...@@ -105,19 +107,23 @@ func handle(fs FileSystem, in_data []byte, toW chan [][]byte, errors chan os.Err
} }
var out interface{} var out interface{}
var result Error = OK var result Error = OK
fmt.Printf("Opcode: %v\n", h.Opcode)
switch h.Opcode { switch h.Opcode {
case FUSE_INIT: case FUSE_INIT:
in := new(InitIn) in := new(InitIn)
err = binary.Read(r, binary.LittleEndian, in) err = binary.Read(r, binary.LittleEndian, in)
if err != nil { if err != nil {
break break
} }
fmt.Printf("in: %v\n", in) fmt.Printf("in: %v\n", in)
var init_out *InitOut var init_out *InitOut
init_out, result = fs.Init(in) init_out, result = fs.Init(in)
if init_out != nil { if init_out != nil {
out = init_out out = init_out
} }
case FUSE_FORGET:
return
default: default:
errors <- os.NewError(fmt.Sprintf("Unsupported OpCode: %d", h.Opcode)) errors <- os.NewError(fmt.Sprintf("Unsupported OpCode: %d", h.Opcode))
result = EIO result = EIO
...@@ -130,9 +136,9 @@ func handle(fs FileSystem, in_data []byte, toW chan [][]byte, errors chan os.Err ...@@ -130,9 +136,9 @@ func handle(fs FileSystem, in_data []byte, toW chan [][]byte, errors chan os.Err
} }
b := new(bytes.Buffer) b := new(bytes.Buffer)
out_data := make([]byte, 0) out_data := make([]byte, 0)
fmt.Printf("OpCode: %v result: %v\n", h.Opcode, result)
if out != nil && result == OK { if out != nil && result == OK {
fmt.Printf("out = %v, out == nil: %v\n", out, out == nil) fmt.Printf("out = %v, out == nil: %v\n", out, out == nil)
return
err = binary.Write(b, binary.LittleEndian, out) err = binary.Write(b, binary.LittleEndian, out)
if err == nil { if err == nil {
out_data = b.Bytes() out_data = b.Bytes()
...@@ -140,6 +146,7 @@ func handle(fs FileSystem, in_data []byte, toW chan [][]byte, errors chan os.Err ...@@ -140,6 +146,7 @@ func handle(fs FileSystem, in_data []byte, toW chan [][]byte, errors chan os.Err
errors <- os.NewError(fmt.Sprintf("Can serialize out: %v", err)) errors <- os.NewError(fmt.Sprintf("Can serialize out: %v", err))
} }
} }
fmt.Printf("out_data: %v, len(out_data): %d, SizeOfOutHeader: %d\n", out_data, len(out_data), SizeOfOutHeader)
var hout OutHeader var hout OutHeader
hout.Unique = h.Unique hout.Unique = h.Unique
hout.Error = int32(result) hout.Error = int32(result)
...@@ -151,26 +158,20 @@ func handle(fs FileSystem, in_data []byte, toW chan [][]byte, errors chan os.Err ...@@ -151,26 +158,20 @@ func handle(fs FileSystem, in_data []byte, toW chan [][]byte, errors chan os.Err
return return
} }
_, _ = b.Write(out_data) _, _ = b.Write(out_data)
toW <- [][]byte { b.Bytes() } fmt.Printf("Sending to writer: %v\n", b.Bytes())
toW <- [][]byte{b.Bytes()}
} }
func (m *MountPoint) writer(f *os.File, in chan [][]byte, errors chan os.Error) { func (m *MountPoint) writer(f *os.File, in chan [][]byte, errors chan os.Error) {
// fd := f.Fd() fd := f.Fd()
for _ = range in { for packet := range in {
// _, err := Writev(fd, packet) fmt.Printf("writer, packet: %v\n", packet)
// if err != nil { _, err := Writev(fd, packet)
// errors <- err if err != nil {
// continue errors <- os.NewError(fmt.Sprintf("writer: Writev failed, err: %v", err))
// } continue
}
}
func (m *MountPoint) errorHandler(errors chan os.Error) {
for err := range errors {
log.Stderr("MountPoint.errorHandler: ", err)
if err == os.EOF {
break
} }
fmt.Printf("writer: OK\n")
} }
} }
......
...@@ -2,6 +2,7 @@ package fuse ...@@ -2,6 +2,7 @@ package fuse
import ( import (
"fmt" "fmt"
"log"
"os" "os"
"testing" "testing"
) )
...@@ -10,15 +11,15 @@ const ( ...@@ -10,15 +11,15 @@ const (
tempMountDir = "./.testMountDir" tempMountDir = "./.testMountDir"
) )
type testFuse struct {} type testFuse struct{}
func (fs *testFuse) Init(in *InitIn) (out *InitOut, code Error) { func (fs *testFuse) Init(in *InitIn) (out *InitOut, code Error) {
if (in.Major != FUSE_KERNEL_VERSION) { if in.Major != FUSE_KERNEL_VERSION {
fmt.Printf("Major versions does not match. Given %d, want %d\n", in.Major, FUSE_KERNEL_VERSION) fmt.Printf("Major versions does not match. Given %d, want %d\n", in.Major, FUSE_KERNEL_VERSION)
code = EIO code = EIO
return return
} }
if (in.Minor < FUSE_KERNEL_MINOR_VERSION) { if in.Minor < FUSE_KERNEL_MINOR_VERSION {
fmt.Printf("Minor version is less than we support. Given %d, want at least %d\n", in.Minor, FUSE_KERNEL_MINOR_VERSION) fmt.Printf("Minor version is less than we support. Given %d, want at least %d\n", in.Minor, FUSE_KERNEL_MINOR_VERSION)
code = EIO code = EIO
return return
...@@ -26,32 +27,42 @@ func (fs *testFuse) Init(in *InitIn) (out *InitOut, code Error) { ...@@ -26,32 +27,42 @@ func (fs *testFuse) Init(in *InitIn) (out *InitOut, code Error) {
out = new(InitOut) out = new(InitOut)
out.Major = FUSE_KERNEL_VERSION out.Major = FUSE_KERNEL_VERSION
out.Minor = FUSE_KERNEL_MINOR_VERSION out.Minor = FUSE_KERNEL_MINOR_VERSION
out.MaxReadahead = 65536 out.MaxReadAhead = in.MaxReadAhead
out.MaxWrite = 65536 out.MaxWrite = 65536
return return
} }
func errorHandler(errors chan os.Error) {
for err := range errors {
log.Stderr("MountPoint.errorHandler: ", err)
if err == os.EOF {
break
}
}
}
func TestMount(t *testing.T) { func TestMount(t *testing.T) {
fs := new(testFuse) fs := new(testFuse)
// toW := make(chan [][]byte, 100) // toW := make(chan [][]byte, 100)
// errors := make(chan os.Error, 100) // errors := make(chan os.Error, 100)
// in_data := []byte { 56, 0, 0, 0, 26, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 0, 0, 2, 0, 123, 0, 0, 0, }
// handle(fs, in_data, toW, errors)
// return
// in_data := []byte { 56, 0, 0, 0, 26, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 13, 0, 0, 0, 0, 0, 2, 0, 123, 0, 0, 0, }
// handle(fs, in_data, toW, errors)
// return
err := os.Mkdir(tempMountDir, 0777) err := os.Mkdir(tempMountDir, 0777)
if err != nil { if err != nil {
t.Fatalf("Can't create temp mount dir at %s, err: %v", tempMountDir, err) t.Fatalf("Can't create temp mount dir at %s, err: %v", tempMountDir, err)
} }
defer os.Remove(tempMountDir) defer os.Remove(tempMountDir)
m, err := Mount(tempMountDir, fs) m, err, errors := Mount(tempMountDir, fs)
if err != nil { if err != nil {
t.Fatalf("Can't mount a dir, err: %v", err) t.Fatalf("Can't mount a dir, err: %v", err)
} }
errorHandler(errors)
err = m.Unmount() err = m.Unmount()
if err != nil { if err != nil {
t.Fatalf("Can't unmount a dir, err: %v", err) t.Fatalf("Can't unmount a dir, err: %v", err)
} }
} }
...@@ -405,16 +405,16 @@ type AccessIn struct { ...@@ -405,16 +405,16 @@ type AccessIn struct {
} }
type InitIn struct { type InitIn struct {
Major uint32 Major uint32
Minor uint32 Minor uint32
Max_readahead uint32 MaxReadAhead uint32
Flags uint32 Flags uint32
} }
type InitOut struct { type InitOut struct {
Major uint32 Major uint32
Minor uint32 Minor uint32
MaxReadahead uint32 MaxReadAhead uint32
Flags uint32 Flags uint32
MaxBackground uint16 MaxBackground uint16
CongestionThreshold uint16 CongestionThreshold uint16
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment