update docs

This commit is contained in:
2026-09-22 13:23:34 +08:00
parent 99bc3d15c5
commit 8a4788fca8
126 changed files with 7198 additions and 2425 deletions
+141
View File
@@ -0,0 +1,141 @@
# Writable DATA and managed programs
Development reference and historical context. For current operating instructions, use the [user manual](../README.md). Acceptance applies only to the source and artifacts identified in each record.
[Documentation index](README.md) · [Cartridges](cartridges.md) · [Services](services.md)
M7 implements writable DATA. Its sustained-write, safe-eject and surrounding
image regression checks [passed in the ARM VM](m7-validation.md). A DATA
cartridge uses a GPT partition named `FDS_DATA`, ext4, and a validated
`/FDS/CARTRIDGE.TOML` declaring class `data` and `writable = true`.
Use the [M9 media tools](media-tools.md) to create new DATA media. The virtual
tests construct disposable image files and never format a workstation disk.
## Where your files live
`/home/fds` remains a temporary home, whether DATA is present or absent. Its
contents disappear at power-off. Persistent user files belong under `/data`.
Separating these paths lets you eject DATA without hiding the active shell's
home directory or substituting another cartridge underneath it.
After inserting a DATA cartridge into a configured bay:
```sh
fds bays
fds cartridge 2
ls /data
```
If exactly one valid DATA candidate is available and none is active, the daemon
activates it at `/data`. The filesystem must grant UID/GID 1000 the intended
write permissions; insertion does not recursively change ownership of user files.
M9's DATA formatter supplies that ownership for fresh media.
An active DATA session stays attached to its current cartridge when another is
inserted. If a discovery snapshot contains multiple candidates with none active,
they remain read-only until you select one:
```sh
fds data use 4
```
Eject the existing active DATA before selecting a replacement. The daemon never
changes `/data` underneath an active session. EMPTY, ERROR and SAFE states retain
the meanings in the [cartridge guide](cartridges.md); MOUNTED READ WRITE means
that the displayed DATA filesystem is available for user writes.
## Run a program that participates in eject
Ordinary console commands work as usual. They are not automatically killed when
you request eject: an open file or working directory may make eject fail as busy.
For a background task that should stop when its DATA is ejected, use:
```sh
fds run 2 -- /usr/bin/bash -c 'date > /data/managed-example.txt'
```
This starts a **background** managed program and prints its process ID. It has no
interactive input. Output goes to the bounded, volatile cartridge service log:
```sh
tail /run/log/cartridged/current
fds cartridge 2
```
The executable path must be absolute. The child starts with `/data` as its working
directory, the ordinary FDS UID/GID, no supplementary groups, no effective
capabilities, a small explicit environment, and `no_new_privs`. Programs cannot
gain privileges through setuid executables. The limit is 256 managed processes
per bay. This interface accepts healthy writable DATA; the [desktop guide](desktop.md)
also explains M8's explicit PROGRAM-media launch interface.
A root-owned Linux cgroup tracks the program and its descendants, including
children that outlive their parent. Cgroups are kernel process tracking, not a
new init system or runtime package. The configured kernel already includes the
required cgroup v2 and process-limit support. The daemon sets up its hierarchy
independently of the console. See the [kernel cgroup interface](https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v2.html).
## Eject and remove DATA
```sh
cd "$HOME"
fds eject 2
```
Eject checks for additional mounts, stops managed consumers, flushes the DATA
filesystem with `syncfs`, and performs a normal unmount. Only successful completion
produces SAFE. A retained filesystem descriptor observes writeback errors during
the session. M10 additionally makes the filesystem read-only and checks writeback
again before closing that descriptor for unmount, preventing an error-reporting
gap when a busy mount needs a later retry.
Linux's [syncfs interface](https://man7.org/linux/man-pages/man2/syncfs.2.html)
reports filesystem errors that must not be ignored.
Managed programs receive TERM first. The daemon waits on actual cgroup exit
notifications; programs that have not exited after a one-second deadline are
killed as a group, including newly forked descendants. A further bounded exit
check must succeed. These are failure deadlines, not delays imposed on a program
that has already stopped. Requesting eject therefore ends those background jobs;
it does not promise that unfinished application work is completed.
An unmanaged busy shell/file, extra mount, failed flush or failed unmount prevents
SAFE. Close the reported use and retry. A recorded DATA writeback fault requires
investigation or recovery; a later successful call is not used to erase it and
pretend the failed write succeeded. The daemon never uses lazy/forced unmount to
claim successful eject. A successfully ejected insertion remains unmounted across
a daemon restart until removal/reinsertion.
M10 records writable sessions and faults outside the daemon process. If it crashes
before verified unmount, the same insertion stays quarantined and read-only on
restart. A later flush cannot reconstruct the lost error history. See
[Shutdown and recovery records](power.md#data-recovery-records) for the current
implementation and its acceptance status.
Pulling DATA during writes is an error. The daemon stops its managed consumers,
cleans up the vanished mount and logs that writes may have been lost. This path
never produces SAFE and makes no filesystem-cleanliness promise. Use recovery
inspection/repair before trusting media that was removed during I/O.
## Build and verify on the workstation
After changing DATA code or image configuration, build fresh inputs in order:
```sh
make rootfs PROFILE=cli
make initramfs
make system-card
make data-test
```
The test boots disposable virtual media, writes continuously, verifies ordinary
user privileges and descendant shutdown, checks busy and additional mounts,
reopens persisted data, tests multiple candidates and simulates surprise removal.
After safe eject it extracts the ext4 partition into an ordinary file, runs
read-only `e2fsck -fn`, and compares the sustained-write payload byte-for-byte.
No host mount or physical USB device is used.
Run `make cartridge-test`, `make init-test`, `make boot-test` and
`make console-test` for the surrounding regressions. Test logs and VM evidence
are written under `out/`. Real flash-controller caches, battery loss, USB power
and physical Pi eject/shutdown latency remain hardware acceptance work.