macos-fuse-t / fuse-t

Other
889 stars 6 forks source link

Unclosed file descriptors on demonization #30

Closed xaizek closed 1 year ago

xaizek commented 1 year ago

I think that this issue with using fuse-zip built against fuse-t is caused by fuse-t not closing stderr (and maybe other descriptors) during demonization. Vifm efectively waits for data on stderr from a zombie, so the likely explanation is that zombie's child keeps the descriptor open. So please verify how you demonize and fix it if my guess is right.

alexfs commented 1 year ago

Do you have instructions how to build vifm with fuse-t and provide configuration instructions so I can test ?

xaizek commented 1 year ago

Vifm doesn't link against fuse-t. It just invokes fuse-zip and waits for it to finish by reading its error stream. The issue manifests with v0.13, earlier versions just appended somethinig like 2>/tmp/fuse.err to FUSE mount command.

Vifm's configuration file is either ~/.config/vifm/vifmrc if ~/.config exists (assuming $XDG_DATA_HOME isn't set) or in ~/.vifm/vifmrc. You only need one line (put it at the top):

filetype *.zip FUSE_MOUNT|fuse-zip %SOURCE_FILE %DESTINATION_DIR

Then run vifm --select path/to/some.zip and press Enter, this should invoke fuse-zip to mount the file and enter mount point on success or hang until you kill fuse-zip. Quit Vifm with :q<Enter>.

slonopotamus commented 1 year ago

Doesn't macFUSE behave the same way?

xaizek commented 1 year ago

Doesn't macFUSE behave the same way?

Just built the same fuse-zip (dropping the top commit) against macFUSE and it works well, while fuse-t version hangs.

slonopotamus commented 1 year ago

@alexfs This hanging can be reproduced in a simpler way. Just try to run any FUSE mount with Golang exec.Command using CombinedOutput(). You'll observe that it hangs waiting on unclosed I/O streams. If you need, I can provide a complete repro code. And the issue is not specific to fuse-zip, I'm observing the same behaviour with bindfs.

slonopotamus commented 1 year ago

BTW, I confirm that this issue does NOT happen with macFUSE.

macos-fuse-t commented 1 year ago

If you have a sample code that would be great

slonopotamus commented 1 year ago

Assumes that you have bindfs in PATH. Build instructions: https://github.com/mpartel/bindfs/issues/100#issuecomment-1627767719

But as I said, any other FUSE fs should also reproduce the issue.

Run as root (sudo is ok):

package main

import (
    "fmt"
    "os"
    "os/exec"
)

func main() {
    _ = os.Mkdir("a", 755)
    _ = os.Mkdir("b", 755)

    cmd := exec.Command("bindfs", "a", "b")
    out, err := cmd.CombinedOutput() // hangs with fuse-t reading from stdout/stderr, but exits normally with macFUSE
    if err != nil {
        fmt.Printf("%s: %v", string(out), err)
        panic(err)
    }
    println("done")
}
slonopotamus commented 1 year ago

Confirming this is fixed in 1.0.24.

xaizek commented 1 year ago

Didn't notice there was a release. It is indeed fixed. Thanks.