Conversation
|
We need to have a thorough discussion on how tee-ing is supposed to work both architecturally and in code. I am going to explain the issues seen in the current approach, and also an alternate approach I tried. The structure of this grate is messy which makes it hard to describe these issues with a 100% clarity so follow up questions for clarity are appreciated. The current approach If we want to tee, we invoke:
The issue with this is that the tee-grate is now interposing on
Possible Fix As a fix for this, I envisioned something like:
Here, I had to add support for both "%{" (shift + set interposing = true) and "%}" (shift + set interposing = false). When the grates in this path don't themselves invoke
The handler constructed for this is convoluted beyond any meaning. Walking through what happens:
The issue here is that we expect these unrelated grates to act as a parent and child to other grates that have nothing to do with each other. While intercepting on register_handler helps ensure that these parent/child pairing don't mean anything to a certain extent, it's still hard to avoid issues like this. For instance, when We need to come up with a better way to implement this state tracking and avoid random grate chains being parents to other random grate chains. One initial thought I had was: tee-grate calls three parallel processes and its direct child, in this example Once everything is done and |
|
CC: @rennergade @Yaxuan-w |
This is fine / what I envisioned would happen. I think the fact you seem to have open-simple-grate able to interpose on open-alt-grate is a problem here. What should happen is that open-simple-grate should see "%} test" as its command line. Once it execs "%}" with "test" as an argument, the tee-grate then goes to fork / exec "open-alt-grate" with "%} test" as arguments and the tee grate's handles as this process's handlers. (You could conceivably fork both processes at once to make it easier to manage the handler tables.) Once the open-alt-grate forks and execs "%}" with an argument "test", you're ready to have the tee-grate go to the next step. Now the tee-grate has two children, which will have registered handlers for at least fork, if not more. You need to have tracked those in your handler table. You exec "test" with a handler table that points to your own implementation of any call that either stack has interposed on. You call those handlers, allowing the call stacks for most to 'go through' except things that are destructive and non-idempotent (fork, exec, exit, etc.). I may be misunderstanding some complexities here if this doesn't seem it will work. Happy to discuss in person or on slack. |
|
I think this approach makes sense, and falls into a similar space where I thought it'd go which is to do some I'll try to implement this and share more on the feasibility. |
How it works
Interposition: The tee grate registers handlers for register_handler (1001), exec (59), fork (57), and exit (60) on every managed cage. When a grate in either the primary or secondary stack calls register_handler, the tee intercepts it, allocates an alt syscall number, and installs its own dispatch handler on the target cage.
Dispatch: When the app makes a syscall, the tee handler fires. It calls the primary handler first (via its alt syscall number), then calls the secondary handler best-effort. The primary's return value is always what gets returned to the caller.
Primary/secondary assignment: Auto-detected by order — the first grate_id seen in a register_handler call becomes primary, the second becomes secondary.
Primary-only syscalls: fork, clone, exec, exit are never duplicated — they have process-level side effects that would break if executed twice.
fdtables integration: open records new fds, close removes them, dup/dup2/dup3 copies entries, fork clones the fd table, exec closes cloexec fds, exit removes the cage's fd table.
CLI
tee-grate --primary imfs-grate --secondary archive-grate -- python build_app.py
Or inline:
tee-grate %{ archive-grate %} python
Files
examples/tee-grate/
Cargo.toml - git deps for grate-rs, fdtables, libc
src/
main.rs - CLI parsing, lifecycle handlers, dispatch handlers, fork/exec/wait
tee.rs - TeeState, route table, tee_dispatch(), do_syscall(), unit tests