Added FUSE support #55

Merged
Elara6331 merged 65 commits from yannickulrich/itd:fuse into master 2023-03-25 22:23:52 +00:00
Showing only changes of commit 08c8d7e8de - Show all commits

29
fuse.go
View File

@ -14,35 +14,6 @@ import (
"bytes" "bytes"
yannickulrich marked this conversation as resolved Outdated

Use os.MkdirAll here instead so that it creates parent directories, and handle the error (just return it).

Use `os.MkdirAll` here instead so that it creates parent directories, and handle the error (just return it).

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. How would you suggest going about doing this?

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?

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 fusefs package, add a file called unmount.go with the following contents:

unmount.go
package fusefs

import (
    _ "unsafe"

    "github.com/hanwen/go-fuse/v2/fuse"
)

func Unmount(mountPoint string) error {
    return unmount(mountPoint, &fuse.MountOptions{DirectMount: false})
}

// Unfortunately, the FUSE library does not export its unmount function,
// so this is required until that changes
//go:linkname unmount github.com/hanwen/go-fuse/v2/fuse.unmount
func unmount(mountPoint string, opts *fuse.MountOptions) error

Then, you can simply call that function at the top of startFUSE like so:

// Ignore the error because nothing might be mounted on the mountpoint
_ = fusefs.Unmount(k.String("fuse.mountpoint"))

I'll file an issue with the fuse library to export that function once this is merged.

The best way to solve this should be calling the unmount function.

I agree that this should be done. However, this doesn't solve the problem completely because if ITD panics for whatever reason, it won't get run and then the user will get a confusing message. Let me see what the best way would be to call this function on shutdown.

Yeah, this one is going to be a bit more complicated. The FUSE library does have [a different unmount function](https://github.com/hanwen/go-fuse/blob/0f728ba15b38579efefc3dc47821882ca18ffea7/fuse/mount_linux.go#L133) 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 `fusefs` package, add a file called `unmount.go` with the following contents: <details> <summary><code>unmount.go</code></summary> ```go package fusefs import ( _ "unsafe" "github.com/hanwen/go-fuse/v2/fuse" ) func Unmount(mountPoint string) error { return unmount(mountPoint, &fuse.MountOptions{DirectMount: false}) } // Unfortunately, the FUSE library does not export its unmount function, // so this is required until that changes //go:linkname unmount github.com/hanwen/go-fuse/v2/fuse.unmount func unmount(mountPoint string, opts *fuse.MountOptions) error ``` </details> Then, you can simply call that function at the top of `startFUSE` like so: ```go // Ignore the error because nothing might be mounted on the mountpoint _ = fusefs.Unmount(k.String("fuse.mountpoint")) ``` I'll file an issue with the fuse library to export that function once this is merged. > The best way to solve this should be calling the unmount function. I agree that this should be done. However, this doesn't solve the problem completely because if ITD panics for whatever reason, it won't get run and then the user will get a confusing message. Let me see what the best way would be to call this function on shutdown.

Cool, thank you! I have implemented this 🙂

Cool, thank you! I have implemented this 🙂
) )
type Device struct {
dev *infinitime.Device
}
func (i Device) HeartRateBytes() ([]byte, error) {
v, err := i.dev.HeartRate()
return []byte(strconv.Itoa(int(v)) + "\n"), err
}
func (i Device) BatteryLevelBytes() ([]byte, error) {
v, err := i.dev.BatteryLevel()
return []byte(strconv.Itoa(int(v)) + "\n"), err
}
func (i Device) StepCountBytes() ([]byte, error) {
v, err := i.dev.StepCount()
return []byte(strconv.Itoa(int(v)) + "\n"), err
}
func (i Device) MotionBytes() ([]byte, error) {
v, err := i.dev.Motion()
return []byte(strconv.Itoa(int(v.X)) + " " + strconv.Itoa(int(v.Y)) + " " + strconv.Itoa(int(v.Z)) + "\n"), err
}
func (i Device) AddressBytes() ([]byte, error) {
v := i.dev.Address()
return []byte(v + "\n"), nil
}
func (i Device) VersionBytes() ([]byte, error) {
v, err := i.dev.Version()
return []byte(v + "\n"), err
}
func converterU8(ctx context.Context, in <-chan uint8) <-chan []byte { func converterU8(ctx context.Context, in <-chan uint8) <-chan []byte {
out := make(chan []byte, 2) out := make(chan []byte, 2)
go func() { go func() {