hanwen / go-fuse

FUSE bindings for Go
Other
2.06k stars 328 forks source link

strange behaviour with pyinstaller executable #442

Closed nikolaevigor closed 1 year ago

nikolaevigor commented 2 years ago

It may be very specific use case, but I still think it's worth reporting

I am using gofuse to distribute python application, that I build with pyinstaller. My build steps:

during execution of go app, it opens itself as archive and mounts to some directory (via gofuse), then it tries to exec python executable. at this point it fails (but if I pack and execute for example ls the same way, it works just fine). strace shows that go application is waiting on some futex. but if I open and close this file, then after that it works just fine. any ideas why is this happening?

package main

import (
    "fmt"
    "os"
    "runtime"
    "os/exec"
    "math/rand"
    "time"
    "io"

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

func NewZipFileSystem(name string) (root fs.InodeEmbedder, err error) {
    root, err = zipfs.NewZipTree(name)

    if err != nil {
        return nil, err
    }

    return root, nil
}

func main() {
    root, err := NewZipFileSystem(os.Args[0])
    if err != nil {
        fmt.Fprintf(os.Stderr, "failed to create zip fs: %v\n", err)
        os.Exit(1)
    }

    fmt.Printf("created zip fs at: %s\n", os.Args[0])

    mount_point := "mnt"
    fmt.Printf("mount point: %s\n", mount_point)

    err = os.Mkdir(mount_point, 0750)
    if err != nil && !os.IsExist(err) {
        fmt.Print("failed to create tmp mnt dir and it does not exist\n")
        os.Exit(1)
    }

    fmt.Printf("created mount point: %s\n", mount_point)

    server, err := fs.Mount(mount_point, root, &fs.Options{})
    if err != nil {
        fmt.Printf("mount fail: %v\n", err)
        os.Exit(1)
    }

    pythonapp := fmt.Sprintf("%s/pythonapp", mount_point)

    in, _ := os.Open(pyinstaller) // without this part it hangs after cmd.Run()
    in.Close()

    cmd := exec.Command(pythonapp)

    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr
    cmd.Stdin = os.Stdin

    cmd.Run()
    server.Wait()
}
hanwen commented 1 year ago

no idea. i suggest mounting the FS with Debug switched on. Maybe it gives some clues about where it is hanging.