Skip to content

Commit 17bf8f7

Browse files
committed
fs-gen: proot is working!
This creates a mounted loopback ps, and then executes a binary there with proot. We have a custom open function that prints the path and next we would want to cache that somehow. Signed-off-by: vsoch <[email protected]>
1 parent 87f8651 commit 17bf8f7

File tree

6 files changed

+54
-42
lines changed

6 files changed

+54
-42
lines changed

README.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,19 @@ This was the experiment to generate something akin to spindle. I think it still
3838
2. Generate a fuse overlay where everything will be found in one spot (no searching needed)
3939
3. Then execute the binary.
4040

41-
We would want to see that the exercise of not needing to do the search speeds up that loading time. If it does, it would make sense to pre-package this metadata with the binary for some registry to use.
42-
This isn't currently working because I can't execute the binary in the proot, so that's the unsolved problem. Here is to test running with a binary.
41+
We would want to see that the exercise of not needing to do the search speeds up that loading time. If it does, it would make sense to pre-package this metadata with the binary for some registry to use. Here is how to run it with a binary:
4342

4443
```bash
4544
./bin/fs-gen /home/vanessa/Desktop/Code/spack/opt/spack/linux-ubuntu24.04-zen4/gcc-13.2.0/xz-5.4.6-klise22d77jjaoejkucrczlkvnm6f4au/bin/xz --help
4645
```
4746

48-
I tried removing read only (ro) and then it freezes, so that's probably not it.
47+
This one has a few more paths:
48+
49+
```bash
50+
./bin/fs-gen /home/vanessa/Desktop/Code/spack/opt/spack/linux-ubuntu24.04-zen4/gcc-13.2.0/hwloc-2.11.1-zuv2etx7sgd5yn6khpblfw6qjh54lpsp/bin/hwloc-ls
51+
```
52+
53+
Next we would want to add some kind of cache to store file descriptors (or paths) and return something else.
4954

5055
### 2. Compatibility Wrapper
5156

cmd/fs/fs.go

+11-14
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ import (
77
"os"
88
"os/signal"
99
"path/filepath"
10+
"strings"
1011
"syscall"
1112

1213
"github.com/compspec/compat-lib/pkg/fs"
1314
"github.com/compspec/compat-lib/pkg/generate"
1415
)
1516

1617
func main() {
17-
fmt.Println("⭐️ Compatibility Filesystem (clib-fs)")
18+
fmt.Println("⭐️ Compatibility Filesystem (fs-gen)")
1819
mountPoint := flag.String("mount-path", "", "Mount path (for control from calling process)")
1920

2021
flag.Parse()
@@ -34,13 +35,10 @@ func main() {
3435

3536
// This is where we should look them up in some cache
3637
fmt.Printf("Preparing to find shared libraries needed for %s\n", args)
37-
paths, err := generate.FindSharedLibs(path)
38+
_, err = generate.FindSharedLibs(path)
3839
if err != nil {
3940
log.Panicf("Error finding shared libraries for %s: %x", path, err)
4041
}
41-
for _, lib := range paths {
42-
fmt.Println(lib)
43-
}
4442

4543
// Generate the fusefs server
4644
compatFS, err := fs.NewCompatFS(mountPath)
@@ -60,15 +58,14 @@ func main() {
6058
}()
6159

6260
// Execute the command with proot
63-
// Disabled for now - operation not permitted. Removing ro seems to freeze
64-
// proot := []string{"proot", "-r", compatFS.MountPoint}
65-
//args = append(proot, args...)
66-
//call := strings.Join(args, " ")
67-
//fmt.Println(call)
68-
//err = compatFS.RunCommand(call)
69-
//if err != nil {
70-
// log.Panicf("Error running command: %s", err)
71-
//}
61+
proot := []string{"proot", "-S", compatFS.MountPoint, "-0"}
62+
args = append(proot, args...)
63+
call := strings.Join(args, " ")
64+
fmt.Println(call)
65+
err = compatFS.RunCommand(call)
66+
if err != nil {
67+
log.Panicf("Error running command: %s", err)
68+
}
7269
defer compatFS.Server.Unmount()
7370
compatFS.Server.Wait()
7471
}

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/compspec/compat-lib
33
go 1.22
44

55
require (
6+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
67
github.com/hanwen/go-fuse/v2 v2.6.1
78
github.com/opencontainers/image-spec v1.1.0
89
github.com/pkg/errors v0.9.1

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
22
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
33
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
4+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
5+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
46
github.com/hanwen/go-fuse/v2 v2.6.1 h1:F3RUMbAuRhVTi3fvgf8HjMPvOm9xEv5wjuy/AXJtEwI=
57
github.com/hanwen/go-fuse/v2 v2.6.1/go.mod h1:ugNaD/iv5JYyS1Rcvi57Wz7/vrLQJo10mmketmoef48=
68
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=

pkg/fs/fs.go

+10-23
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import (
44
"fmt"
55
"os"
66
"os/exec"
7-
"syscall"
87

8+
"github.com/google/shlex"
99
"github.com/hanwen/go-fuse/v2/fuse"
1010
)
1111

@@ -83,43 +83,30 @@ func NewCompatFS(mountPath string) (*CompatFS, error) {
8383
// separately.
8484
func (c *CompatFS) RunCommand(command string) error {
8585

86-
// Get current working directory to return to
87-
cwd, err := os.Getwd()
86+
// returns list of strings
87+
call, err := shlex.Split(command)
8888
if err != nil {
8989
return err
9090
}
9191

92-
// Get the file descriptor to return to later
93-
fd, err := os.Open(cwd)
92+
command, args := call[0], call[1:]
93+
94+
// Get current working directory to return to
95+
cwd, err := os.Getwd()
9496
if err != nil {
9597
return err
9698
}
97-
defer fd.Close()
9899

99100
// Setup command, using standard outputs
100-
cmd := exec.Command(command)
101+
cmd := exec.Command(command, args...)
101102
cmd.Stdin = os.Stdin
102103
cmd.Stdout = os.Stdout
103104
cmd.Stderr = os.Stderr
105+
cmd.Dir = cwd
104106

105-
// Change directory to the new "root" (mountpoint) and call chroot
106-
err = syscall.Chdir(c.MountPoint)
107-
if err != nil {
108-
return err
109-
}
110-
err = syscall.Chroot(c.MountPoint)
111-
if err != nil {
112-
return err
113-
}
114107
err = cmd.Run()
115108
if err != nil {
116109
return err
117110
}
118-
119-
// Return to previous location
120-
err = syscall.Fchdir(int(fd.Fd()))
121-
if err != nil {
122-
return err
123-
}
124-
return syscall.Chroot(".")
111+
return err
125112
}

pkg/fs/loopback.go

+22-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"log"
77
"os"
8+
"path/filepath"
89
"syscall"
910
"time"
1011

@@ -19,14 +20,33 @@ type CompatLoopbackNode struct {
1920
fs.LoopbackNode
2021
}
2122

23+
func (n *CompatLoopbackNode) path() string {
24+
path := n.Path(n.root())
25+
return filepath.Join(n.RootData.Path, path)
26+
}
27+
28+
// path returns the full path to the file in the underlying file system.
29+
func (n *CompatLoopbackNode) root() *fs.Inode {
30+
var rootNode *fs.Inode
31+
if n.RootData.RootNode != nil {
32+
rootNode = n.RootData.RootNode.EmbeddedInode()
33+
} else {
34+
rootNode = n.Root()
35+
}
36+
37+
return rootNode
38+
}
39+
2240
func (n *CompatLoopbackNode) Open(ctx context.Context, flags uint32) (fs.FileHandle, uint32, syscall.Errno) {
23-
fmt.Println("CUSTOM OPEN FOR %s with flags %s\n", ctx, flags)
41+
flags = flags &^ syscall.O_APPEND
42+
p := n.path()
43+
fmt.Printf("CUSTOM OPEN FOR %s with flags %d\n", p, flags)
2444
fh, flags, errno := n.LoopbackNode.Open(ctx, flags)
2545
return fh, flags, errno
2646
}
2747

2848
func (n *CompatLoopbackNode) Create(ctx context.Context, name string, flags uint32, mode uint32, out *fuse.EntryOut) (*fs.Inode, fs.FileHandle, uint32, syscall.Errno) {
29-
fmt.Println("CUSTOM CREATE FOR %s with flags %s\n", name, flags)
49+
fmt.Printf("CUSTOM CREATE FOR %s with flags %d\n", name, flags)
3050
inode, fh, flags, errno := n.LoopbackNode.Create(ctx, name, flags, mode, out)
3151
return inode, fh, flags, errno
3252
}

0 commit comments

Comments
 (0)