// Package mount provides FUSE-based 9P mount functionality. // Used by `olliesrv mount` for network-transparent access to remote servers. package mount import ( "fmt" "os" "os/signal" "syscall" "9fans.net/go/plan9/client" "github.com/hanwen/go-fuse/v2/fs" "github.com/hanwen/go-fuse/v2/fuse" ) // Config configures a FUSE mount. type Config struct { Network string // "unix" or "tcp" Address string // server address Mountpoint string // local mountpoint Uname string // uname for Tattach (default: $USER) } // Run mounts the remote 9P server and blocks until unmounted or signaled. func Run(cfg Config) error { if cfg.Uname == "" { cfg.Uname = os.Getenv("USER") } if cfg.Uname == "" { cfg.Uname = "none" } conn, err := client.Dial(cfg.Network, cfg.Address) if err != nil { return fmt.Errorf("dial %s!%s: %w", cfg.Network, cfg.Address, err) } fsys, err := conn.Attach(nil, cfg.Uname, "") if err != nil { conn.Close() return fmt.Errorf("attach: %w", err) } root := &p9Dir{fsys: fsys, path: "/"} server, err := fs.Mount(cfg.Mountpoint, root, &fs.Options{ MountOptions: fuse.MountOptions{ FsName: "ollie", Name: "ollie9p", DisableXAttrs: true, MaxBackground: 32, }, }) if err != nil { return fmt.Errorf("mount %s: %w", cfg.Mountpoint, err) } sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) go func() { <-sigCh server.Unmount() }() server.Wait() return nil }