Added FUSE support #55
76
fuse.go
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package main
|
||||||
|
import (
|
||||||
|
"go.arsenm.dev/itd/internal/fusefs"
|
||||||
|
"os"
|
||||||
|
"github.com/hanwen/go-fuse/v2/fs"
|
||||||
|
"github.com/hanwen/go-fuse/v2/fuse"
|
||||||
|
"go.arsenm.dev/logger/log"
|
||||||
|
"context"
|
||||||
|
"go.arsenm.dev/infinitime"
|
||||||
|
)
|
||||||
|
|
||||||
|
func startFuse(ctx context.Context, dev *infinitime.Device) error {
|
||||||
yannickulrich marked this conversation as resolved
Outdated
|
|||||||
|
// This is where we'll mount the FS
|
||||||
|
os.Mkdir(k.String("fuse.mountpoint"), 0755)
|
||||||
yannickulrich marked this conversation as resolved
Outdated
Elara6331
commented
Use Use `os.MkdirAll` here instead so that it creates parent directories, and handle the error (just return it).
yannickulrich
commented
This is actually a bit more complicated than that. If the mountpoint already exists, fuse will crash. We also can't delete the mountpoint beforehand ( This is actually a bit more complicated than that. If the mountpoint already exists, fuse will crash. We also can't delete the mountpoint beforehand (`rm: cannot remove '/tmp/itd/mnt': Transport endpoint is not connected`). The best way to solve this should be calling the [unmount function](https://pkg.go.dev/github.com/hanwen/go-fuse/v2@v2.2.0/fuse#Server.Unmount). How would you suggest going about doing this?
Elara6331
commented
Yeah, this one is going to be a bit more complicated. The FUSE library does have a different unmount function that you could call before trying to mount the fs, but it's not exported, so we'll need to do a small hack to get access to it anyway. In the
|
|||||||
|
root := &ITNode{kind: 0}
|
||||||
|
server, err := fs.Mount(k.String("fuse.mountpoint"), root, &fs.Options{
|
||||||
|
MountOptions: fuse.MountOptions{
|
||||||
|
// Set to true to see how the file system works.
|
||||||
|
Debug: false,
|
||||||
|
SingleThreaded: true,
|
||||||
|
},
|
||||||
yannickulrich marked this conversation as resolved
Outdated
Elara6331
commented
`err` is returned twice here
yannickulrich
commented
Oh, sorry, fixed now Oh, sorry, fixed now
|
|||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Mounting failed").
|
||||||
|
Str("target", k.String("fuse.mountpoint")).
|
||||||
|
Err(err).
|
||||||
|
Send()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Info("Mounted on target").
|
||||||
|
Str("target", k.String("fuse.mountpoint")).
|
||||||
|
Send()
|
||||||
|
|
||||||
|
properties[0] = ITProperty{"heartrate", 2,
|
||||||
|
func(ctx context.Context) (<-chan []byte, error) {
|
||||||
|
ans, err := dev.WatchHeartRate(ctx)
|
||||||
|
return converterU8(ctx, ans), err
|
||||||
|
}}
|
||||||
|
properties[1] = ITProperty{"battery", 3,
|
||||||
|
func(ctx context.Context) (<-chan []byte, error) {
|
||||||
|
ans, err := dev.WatchBatteryLevel(ctx)
|
||||||
|
return converterU8(ctx, ans), err
|
||||||
|
}}
|
||||||
|
properties[2] = ITProperty{"motion", 4,
|
||||||
|
func(ctx context.Context) (<-chan []byte, error) {
|
||||||
|
ans, err := dev.WatchMotion(ctx)
|
||||||
|
return converterMotionValues(ctx, ans), err
|
||||||
|
}}
|
||||||
|
properties[3] = ITProperty{"stepcount", 5,
|
||||||
|
func(ctx context.Context) (<-chan []byte, error) {
|
||||||
|
ans, err := dev.WatchStepCount(ctx)
|
||||||
|
return converterU32(ctx, ans), err
|
||||||
|
}}
|
||||||
|
properties[4] = ITProperty{"version", 6,
|
||||||
|
func(ctx context.Context) (<-chan []byte, error) {
|
||||||
|
ans, err := dev.Version()
|
||||||
|
return converter1String(ctx, ans), err
|
||||||
|
}}
|
||||||
|
properties[5] = ITProperty{"address", 7,
|
||||||
|
func(ctx context.Context) (<-chan []byte, error) {
|
||||||
|
ans := dev.Address()
|
||||||
|
return converter1String(ctx, ans), nil
|
||||||
|
}}
|
||||||
|
|
||||||
|
myfs, err = dev.FS()
|
||||||
|
if err != nil {
|
||||||
|
log.Warn("Error getting BLE filesystem").Err(err).Send()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
inodemap = make(map[string]uint64)
|
||||||
|
|
||||||
|
// Wait until unmount before exiting
|
||||||
|
go server.Serve()
|
||||||
|
return nil
|
||||||
|
}
|
@ -1,10 +1,9 @@
|
|||||||
package main
|
package fusefs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.arsenm.dev/infinitime"
|
"go.arsenm.dev/infinitime"
|
||||||
"go.arsenm.dev/infinitime/blefs"
|
"go.arsenm.dev/infinitime/blefs"
|
||||||
"go.arsenm.dev/logger/log"
|
"go.arsenm.dev/logger/log"
|
||||||
"os"
|
|
||||||
"context"
|
"context"
|
||||||
"syscall"
|
"syscall"
|
||||||
"github.com/hanwen/go-fuse/v2/fs"
|
"github.com/hanwen/go-fuse/v2/fs"
|
||||||
@ -550,69 +549,3 @@ var _ = (fs.NodeRmdirer)((*ITNode)(nil))
|
|||||||
func (f *ITNode) Rmdir(ctx context.Context, name string) syscall.Errno {
|
func (f *ITNode) Rmdir(ctx context.Context, name string) syscall.Errno {
|
||||||
return f.Unlink(ctx, name)
|
return f.Unlink(ctx, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func startFuse(ctx context.Context, dev *infinitime.Device) error {
|
|
||||||
// This is where we'll mount the FS
|
|
||||||
os.Mkdir(k.String("fuse.mountpoint"), 0755)
|
|
||||||
root := &ITNode{kind: 0}
|
|
||||||
server, err := fs.Mount(k.String("fuse.mountpoint"), root, &fs.Options{
|
|
||||||
MountOptions: fuse.MountOptions{
|
|
||||||
// Set to true to see how the file system works.
|
|
||||||
Debug: false,
|
|
||||||
SingleThreaded: true,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Error("Mounting failed").
|
|
||||||
Str("target", k.String("fuse.mountpoint")).
|
|
||||||
Err(err).
|
|
||||||
Send()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("Mounted on target").
|
|
||||||
Str("target", k.String("fuse.mountpoint")).
|
|
||||||
Send()
|
|
||||||
|
|
||||||
properties[0] = ITProperty{"heartrate", 2,
|
|
||||||
func(ctx context.Context) (<-chan []byte, error) {
|
|
||||||
ans, err := dev.WatchHeartRate(ctx)
|
|
||||||
return converterU8(ctx, ans), err
|
|
||||||
}}
|
|
||||||
properties[1] = ITProperty{"battery", 3,
|
|
||||||
func(ctx context.Context) (<-chan []byte, error) {
|
|
||||||
ans, err := dev.WatchBatteryLevel(ctx)
|
|
||||||
return converterU8(ctx, ans), err
|
|
||||||
}}
|
|
||||||
properties[2] = ITProperty{"motion", 4,
|
|
||||||
func(ctx context.Context) (<-chan []byte, error) {
|
|
||||||
ans, err := dev.WatchMotion(ctx)
|
|
||||||
return converterMotionValues(ctx, ans), err
|
|
||||||
}}
|
|
||||||
properties[3] = ITProperty{"stepcount", 5,
|
|
||||||
func(ctx context.Context) (<-chan []byte, error) {
|
|
||||||
ans, err := dev.WatchStepCount(ctx)
|
|
||||||
return converterU32(ctx, ans), err
|
|
||||||
}}
|
|
||||||
properties[4] = ITProperty{"version", 6,
|
|
||||||
func(ctx context.Context) (<-chan []byte, error) {
|
|
||||||
ans, err := dev.Version()
|
|
||||||
return converter1String(ctx, ans), err
|
|
||||||
}}
|
|
||||||
properties[5] = ITProperty{"address", 7,
|
|
||||||
func(ctx context.Context) (<-chan []byte, error) {
|
|
||||||
ans := dev.Address()
|
|
||||||
return converter1String(ctx, ans), nil
|
|
||||||
}}
|
|
||||||
|
|
||||||
myfs, err = dev.FS()
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("Error getting BLE filesystem").Err(err).Send()
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
inodemap = make(map[string]uint64)
|
|
||||||
|
|
||||||
// Wait until unmount before exiting
|
|
||||||
go server.Serve()
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
This function should be called
startFUSE
instead to adhere to Go naming conventionsThanks, I'm relatively new to Go, sorry for these issues
Done in
673383f