remove dead mount/ package and olliesrv mount subcommand

The FUSE-based 9P mount (mount/) was unused — all actual mounting
uses 9pfuse via ollie-remount. Remove the package, the olliesrv mount
subcommand, and the go-fuse dependency.
This commit is contained in:
Ollie Agent 2026-07-30 21:18:52 +02:00
parent 96dc6e442b
commit bcfdda26b4
5 changed files with 1 additions and 382 deletions

View File

@ -21,7 +21,6 @@ import (
"ollie/env"
"ollie/fs/session"
olog "ollie/log"
"ollie/mount"
"ollie/paths"
"ollie/skills"
"ollie/toolsrv"
@ -90,11 +89,6 @@ func (c *ModelCache) Invalidate() {
func main() {
flag.CommandLine.Parse(os.Args[1:]) //nolint:errcheck
// Handle mount subcommand (kept as a convenience)
if flag.NArg() > 0 && flag.Arg(0) == "mount" {
cmdMount()
return
}
ns := client.Namespace()
if ns == "" {
@ -106,35 +100,7 @@ func main() {
runServer(sockPath)
}
func cmdMount() {
if flag.NArg() < 1 {
fmt.Fprintln(os.Stderr, "usage: olliesrv mount <address> [mountpoint]")
os.Exit(1)
}
addr := flag.Arg(0)
mnt := flag.Arg(1)
if mnt == "" {
home, _ := os.UserHomeDir()
mnt = filepath.Join(home, "mnt", addr)
}
if err := os.MkdirAll(mnt, fs.PermMkdir); err != nil {
fmt.Fprintf(os.Stderr, "cannot create mount dir: %v\n", err)
os.Exit(1)
}
network := "unix"
if strings.Contains(addr, ":") {
network = "tcp"
}
fmt.Printf("mounting %s at %s\n", addr, mnt)
if err := mount.Run(mount.Config{
Network: network,
Address: addr,
Mountpoint: mnt,
}); err != nil {
fmt.Fprintf(os.Stderr, "mount: %v\n", err)
os.Exit(1)
}
}
func runServer(sockPath string) {
env.EnsureDefaults()

3
go.mod
View File

@ -5,10 +5,7 @@ go 1.25.6
require (
9fans.net/go v0.0.7
github.com/godbus/dbus/v5 v5.1.0
github.com/hanwen/go-fuse/v2 v2.10.1
github.com/simonfxr/pubsub v0.0.5
golang.org/x/time v0.15.0
gopkg.in/yaml.v3 v3.0.1
)
require golang.org/x/sys v0.47.0 // indirect

8
go.sum
View File

@ -7,12 +7,6 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/hanwen/go-fuse/v2 v2.10.1 h1:QAqZuc9+aBtTou+OPruU/hkYQYCkgPtQd2QaepHkTTs=
github.com/hanwen/go-fuse/v2 v2.10.1/go.mod h1:aU7NkGYZUmuJrZapoI3mEcNve7PZTySUOLBuch/vR6U=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg=
github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/simonfxr/pubsub v0.0.5 h1:DJfvFoglqGvwJriIOC5NI5um34n2YX8KAU5+7jv768w=
@ -42,8 +36,6 @@ golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210415045647-66c3f260301c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=

View File

@ -1,65 +0,0 @@
// 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
}

View File

@ -1,271 +0,0 @@
package mount
import (
"context"
"os/user"
"strconv"
"sync"
"syscall"
"9fans.net/go/plan9"
"9fans.net/go/plan9/client"
"github.com/hanwen/go-fuse/v2/fs"
"github.com/hanwen/go-fuse/v2/fuse"
)
// p9Dir is a FUSE directory node backed by a 9P path.
type p9Dir struct {
fs.Inode
fsys *client.Fsys
path string // 9P path (empty string = root)
}
// p9File is a FUSE file node backed by a 9P path.
type p9File struct {
fs.Inode
fsys *client.Fsys
path string
mu sync.Mutex
}
var _ = (fs.NodeGetattrer)((*p9Dir)(nil))
var _ = (fs.NodeReaddirer)((*p9Dir)(nil))
var _ = (fs.NodeLookuper)((*p9Dir)(nil))
var _ = (fs.NodeCreater)((*p9Dir)(nil))
var _ = (fs.NodeUnlinker)((*p9Dir)(nil))
var _ = (fs.NodeMkdirer)((*p9Dir)(nil))
var _ = (fs.NodeRmdirer)((*p9Dir)(nil))
var _ = (fs.NodeRenamer)((*p9Dir)(nil))
var _ = (fs.NodeGetattrer)((*p9File)(nil))
var _ = (fs.NodeOpener)((*p9File)(nil))
var _ = (fs.NodeReader)((*p9File)(nil))
var _ = (fs.NodeWriter)((*p9File)(nil))
var _ = (fs.NodeSetattrer)((*p9File)(nil))
func p9path(base, name string) string {
if base == "" {
return name
}
return base + "/" + name
}
// --- p9Dir ---
func (d *p9Dir) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.AttrOut) syscall.Errno {
path := d.path
if path == "" {
path = "/"
}
dir, err := d.fsys.Stat(path)
if err != nil {
return syscall.ENOENT
}
out.Mode = uint32(dir.Mode)&0777 | syscall.S_IFDIR
out.Uid = lookupUid(dir.Uid)
out.Gid = lookupGid(dir.Gid)
return 0
}
func (d *p9Dir) Readdir(ctx context.Context) (fs.DirStream, syscall.Errno) {
path := d.path
if path == "" {
path = "/"
}
fid, err := d.fsys.Open(path, plan9.OREAD)
if err != nil {
return nil, syscall.EIO
}
defer fid.Close()
dirs, err := fid.Dirreadall()
if err != nil {
return nil, syscall.EIO
}
entries := make([]fuse.DirEntry, len(dirs))
for i, dir := range dirs {
m := uint32(dir.Mode) & 0777
if dir.Mode&plan9.DMDIR != 0 {
m |= syscall.S_IFDIR
}
entries[i] = fuse.DirEntry{Name: dir.Name, Mode: m}
}
return fs.NewListDirStream(entries), 0
}
func (d *p9Dir) Lookup(ctx context.Context, name string, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) {
child := p9path(d.path, name)
dir, err := d.fsys.Stat(child)
if err != nil {
return nil, syscall.ENOENT
}
out.Uid = lookupUid(dir.Uid)
out.Gid = lookupGid(dir.Gid)
if dir.Mode&plan9.DMDIR != 0 {
out.Mode = uint32(dir.Mode)&0777 | syscall.S_IFDIR
node := &p9Dir{fsys: d.fsys, path: child}
return d.NewInode(ctx, node, fs.StableAttr{Mode: syscall.S_IFDIR}), 0
}
out.Mode = uint32(dir.Mode) & 0777
out.Size = dir.Length
node := &p9File{fsys: d.fsys, path: child}
return d.NewInode(ctx, node, fs.StableAttr{}), 0
}
func (d *p9Dir) Create(ctx context.Context, name string, flags uint32, mode uint32, out *fuse.EntryOut) (*fs.Inode, fs.FileHandle, uint32, syscall.Errno) {
child := p9path(d.path, name)
fid, err := d.fsys.Create(child, plan9.OWRITE, plan9.Perm(mode&0777))
if err != nil {
return nil, nil, 0, syscall.EIO
}
fid.Close()
out.Mode = mode & 0777
node := &p9File{fsys: d.fsys, path: child}
inode := d.NewInode(ctx, node, fs.StableAttr{})
return inode, nil, fuse.FOPEN_DIRECT_IO, 0
}
func (d *p9Dir) Unlink(ctx context.Context, name string) syscall.Errno {
child := p9path(d.path, name)
if err := d.fsys.Remove(child); err != nil {
return syscall.EIO
}
return 0
}
func (d *p9Dir) Mkdir(ctx context.Context, name string, mode uint32, out *fuse.EntryOut) (*fs.Inode, syscall.Errno) {
child := p9path(d.path, name)
fid, err := d.fsys.Create(child, plan9.OREAD, plan9.DMDIR|plan9.Perm(mode&0777))
if err != nil {
return nil, syscall.EIO
}
fid.Close()
out.Mode = mode&0777 | syscall.S_IFDIR
node := &p9Dir{fsys: d.fsys, path: child}
return d.NewInode(ctx, node, fs.StableAttr{Mode: syscall.S_IFDIR}), 0
}
func (d *p9Dir) Rmdir(ctx context.Context, name string) syscall.Errno {
child := p9path(d.path, name)
if err := d.fsys.Remove(child); err != nil {
return syscall.EIO
}
return 0
}
func (d *p9Dir) Rename(ctx context.Context, name string, newParent fs.InodeEmbedder, newName string, flags uint32) syscall.Errno {
child := p9path(d.path, name)
var dir plan9.Dir
dir.Null()
dir.Name = newName
if err := d.fsys.Wstat(child, &dir); err != nil {
return syscall.EIO
}
return 0
}
// --- p9File ---
func (f *p9File) Getattr(ctx context.Context, fh fs.FileHandle, out *fuse.AttrOut) syscall.Errno {
dir, err := f.fsys.Stat(f.path)
if err != nil {
return syscall.ENOENT
}
out.Mode = uint32(dir.Mode) & 0777
out.Size = dir.Length
out.Uid = lookupUid(dir.Uid)
out.Gid = lookupGid(dir.Gid)
return 0
}
func (f *p9File) Setattr(ctx context.Context, fh fs.FileHandle, in *fuse.SetAttrIn, out *fuse.AttrOut) syscall.Errno {
// Accept truncate silently — 9P files are append/overwrite on write.
dir, err := f.fsys.Stat(f.path)
if err != nil {
return syscall.ENOENT
}
out.Mode = uint32(dir.Mode) & 0777
return 0
}
func (f *p9File) Open(ctx context.Context, flags uint32) (fs.FileHandle, uint32, syscall.Errno) {
return nil, fuse.FOPEN_DIRECT_IO, 0
}
func (f *p9File) Read(ctx context.Context, fh fs.FileHandle, dest []byte, off int64) (fuse.ReadResult, syscall.Errno) {
f.mu.Lock()
defer f.mu.Unlock()
fid, err := f.fsys.Open(f.path, plan9.OREAD)
if err != nil {
return nil, syscall.EIO
}
defer fid.Close()
if off > 0 {
buf := make([]byte, min(off, 8192))
remaining := off
for remaining > 0 {
n := int64(len(buf))
if n > remaining {
n = remaining
}
nr, err := fid.Read(buf[:n])
if err != nil || nr == 0 {
break
}
remaining -= int64(nr)
}
}
n, err := fid.Read(dest)
if n == 0 {
return fuse.ReadResultData(nil), 0
}
return fuse.ReadResultData(dest[:n]), 0
}
func (f *p9File) Write(ctx context.Context, fh fs.FileHandle, data []byte, off int64) (uint32, syscall.Errno) {
f.mu.Lock()
defer f.mu.Unlock()
fid, err := f.fsys.Open(f.path, plan9.OWRITE)
if err != nil {
return 0, syscall.EACCES
}
n, err := fid.Write(data)
if err != nil {
fid.Close()
return 0, syscall.EIO
}
if err := fid.Close(); err != nil {
return 0, syscall.EACCES
}
return uint32(n), 0
}
func min(a, b int64) int64 {
if a < b {
return a
}
return b
}
func lookupUid(name string) uint32 {
if id, err := strconv.ParseUint(name, 10, 32); err == nil {
return uint32(id)
}
if u, err := user.Lookup(name); err == nil {
if id, err := strconv.ParseUint(u.Uid, 10, 32); err == nil {
return uint32(id)
}
}
return 0
}
func lookupGid(name string) uint32 {
if id, err := strconv.ParseUint(name, 10, 32); err == nil {
return uint32(id)
}
if g, err := user.LookupGroup(name); err == nil {
if id, err := strconv.ParseUint(g.Gid, 10, 32); err == nil {
return uint32(id)
}
}
return 0
}