Skip to content

Commit 6996713

Browse files
wan9chicodex
andcommitted
docs(fspy): tighten Linux backend decision record
Co-authored-by: GPT-5 Codex <codex@openai.com>
1 parent ae90c87 commit 6996713

1 file changed

Lines changed: 19 additions & 42 deletions

File tree

Lines changed: 19 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,32 @@
11
# Linux backend
22

3-
The Linux backend stores data in an anonymous `memfd` and uses a Linux
4-
abstract Unix-domain socket as a descriptor broker. The broker is a control
5-
plane used only when opening a view. Once mapped, all frame reads and writes
6-
access memory directly.
3+
The Linux backend stores data in a sealed `memfd`. An abstract Unix-domain
4+
socket broker distributes the descriptor when a process opens the mapping;
5+
the data path remains memory-mapped.
76

8-
## Requirements
9-
10-
The fspy channel reserves a large logical region so intercepted processes can
11-
append without coordinating a resize. The Linux backend must:
12-
13-
- avoid the container's `/dev/shm` mount limit,
14-
- avoid allocating the mapping's full logical size up front,
15-
- let another process open the mapping from a serialized identifier,
16-
- support clients that run in preload code before `main`,
17-
- keep data writes free of per-record syscalls, and
18-
- preserve already-open views when the owner stops accepting new views.
19-
20-
The
21-
[`constrained_dev_shm`](../../../vite_task_bin/tests/e2e_snapshots/fixtures/constrained_dev_shm/)
22-
fixture captures the key constraint. It mounts a one-page `/dev/shm` and
23-
forces file-access tracking to write beyond that mount's capacity.
7+
The design must avoid `/dev/shm` quotas, allocate a large logical mapping on
8+
demand, support synchronous opens from preload code, and stop new opens when
9+
the owner is dropped without invalidating existing views.
2410

2511
## Options considered
2612

27-
| Option | Decision |
28-
| --- | --- |
29-
| POSIX `shm_open` | Rejected. Linux normally places the object on `/dev/shm`, so container tmpfs limits can fault mapped writes even when the host has enough memory. |
30-
| Memory-map a temporary file | Rejected. It introduces path discovery, cleanup, and possible disk writeback without providing a better identifier. |
31-
| Inherit a `memfd` | Rejected. Every process would need to propagate the descriptor to later children and across `exec`, increasing descriptor-leak risk. |
32-
| Send every record through a socket or pipe | Rejected. Every file-access record would require a syscall under concurrent writes. |
33-
| `memfd` with descriptor broker | Selected. It avoids `/dev/shm`, preserves string-based discovery, and pays socket overhead only when a process opens a view. |
13+
| Option | Decision |
14+
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
15+
| POSIX shared memory | Rejected because Linux backs it with `/dev/shm`. |
16+
| System V shared memory | Rejected because IPC namespace quotas affect availability and segment lifetime is not tied to descriptor ownership. |
17+
| Sparse temporary file | Rejected because dirty pages may reach disk and the file needs a separate lifetime protocol. |
18+
| `memfd` with descriptor broker | Selected. It avoids mount and IPC quotas while retaining descriptor-based lifetime. |
3419

35-
The broker is asynchronous so one descriptor transfer cannot stop it from
36-
accepting another client. Opening remains synchronous because preload code may
37-
run before an application provides an async runtime. Creating the owner
38-
requires an ambient Tokio runtime to host the broker.
20+
The broker accepts and serves clients asynchronously. The client is
21+
synchronous because it can run before `main`; creating an owner therefore
22+
requires an ambient Tokio runtime only on the broker side.
3923

4024
## Why not `shared_memory`
4125

42-
The `shared_memory` Unix backend creates mappings with POSIX `shm_open`. Its
43-
API cannot accept an existing `memfd` or distribute that descriptor, so
44-
wrapping it would retain the `/dev/shm` dependency.
45-
46-
Extending or forking the general-purpose crate would add more surface than
47-
fspy needs. The local backend only implements the descriptor, mapping, broker,
48-
and lifetime behavior required by the channel contract.
26+
`shared_memory` uses POSIX `shm_open` on Linux and cannot construct a mapping
27+
from a `memfd`, so it retains the `/dev/shm` dependency.
4928

5029
## Lifetime semantics
5130

52-
Dropping the owner stops the broker, so later opens fail. Descriptors already
53-
delivered to other processes remain valid, and their mapped views stay usable
54-
independently of the owner. Neither the `memfd` nor the abstract socket needs a
55-
filesystem pathname or cleanup file.
31+
Dropping the owner stops the broker. Existing views remain valid; later opens
32+
fail.

0 commit comments

Comments
 (0)