feat(init): supervise servers+session progs: restart on death, same endpoint, backoff 0/1/5/30s then give up, restarts_clients cascade; release grants/spawn at stop (stale-slot safe); storage death fatal; init output via printer thread (never blocks on log); terminal Ctrl+C via CONTROL-badged copy, latest wins; flaky test server + spawntest restart/backoff check

This commit is contained in:
2026-10-28 01:44:24 +01:00
parent c4871320a0
commit 28f1ace00a
23 changed files with 736 additions and 144 deletions

View File

@@ -49,8 +49,15 @@ pub struct Program {
pub spawns: Option<Limits>,
/// May halt the machine.
pub system_control: bool,
/// May sign the user out (`types::spawn::SIGN_OUT`), in the last slot.
/// May sign the user out (`types::spawn::SIGN_OUT`), in the next slot.
pub signs_out: bool,
/// Takes Ctrl+C: a terminal copy with `types::terminal::CONTROL`, last.
pub takes_ctrl_c: bool,
/// Started again if it dies (see init's supervise.rs).
pub restart: bool,
/// Its clients keep state in it (a subscription, focus, a handle), so
/// they are restarted after it is.
pub restarts_clients: bool,
}
/// Enough for a small program: its image, stack and a little heap.
@@ -75,22 +82,29 @@ const fn server(name: &'static str, file: &'static [u8], limits: Limits) -> Prog
spawns: None,
system_control: false,
signs_out: false,
takes_ctrl_c: false,
restart: true,
restarts_clients: false,
}
}
/// Started on every boot. The log server comes first so the rest can print.
pub const SERVERS: &[Program] = &[
Program { console: true, ..server("log", b"bin/log", SMALL) },
Program { devices: &[Device::Input], ..server("input", b"bin/input", Limits { regions: 4, ..SMALL }) },
// The display subscribes to it.
Program { devices: &[Device::Input], restarts_clients: true, ..server("input", b"bin/input", Limits { regions: 4, ..SMALL }) },
// The input server's only client: it passes input on to the app in focus.
Program {
devices: &[Device::Gpu],
uses: &["input"],
// Its clients subscribe and take focus.
restarts_clients: true,
// The framebuffer alone is ~1000 pages at 1280x800.
..server("display", b"bin/display", Limits { pages: 1280, regions: 4, ..SMALL })
},
// Text on the display, lines from the keyboard (it takes input focus).
Program { uses: &["display"], ..server("terminal", b"bin/terminal", SMALL) },
// Its clients wait on lines and Ctrl+C.
Program { uses: &["display"], restarts_clients: true, ..server("terminal", b"bin/terminal", SMALL) },
server("session", b"bin/session", SMALL),
];
@@ -102,6 +116,8 @@ pub const GATEKEEPER: Program = Program {
devices: &[Device::Keystore, Device::Random],
// A user's record is KiBs, and it handles a few at once.
stack_pages: 12,
// It exits once it has handed over; a new one runs at each sign-in.
restart: false,
// argon2's 16 MiB, its image and a little more.
..server("gatekeeper", b"bin/gatekeeper", Limits { pages: 4096 + 160, regions: 6, ..SMALL })
};
@@ -115,18 +131,22 @@ pub const SESSION: &[Program] = &[Program {
storage: &[users(b"", true), disk(b"apps", false)],
// Room for a few apps at a time.
spawns: Some(Limits { pages: 512, endpoints: 8, notifications: 8, regions: 8 }),
// The shell holds handles to the apps it ran, which die with it.
restarts_clients: true,
..server("permission", b"bin/permission", Limits { pages: 96, ..SMALL })
}];
/// Run on the test image after the SMP self-test, instead of the desktop:
/// spawns through init, then reports and halts.
pub const TESTS: &[Program] = &[Program {
/// spawns through init, then reports and halts. `flaky` dies when asked,
/// for spawntest to see it restarted.
pub const TESTS: &[Program] = &[server("flaky", b"bin/flaky", SMALL), Program {
serves: false,
// The permission manager, to run an app the way the shell does.
uses: &["permission"],
uses: &["permission", "flaky"],
storage: &[disk(b"", true), users(b"home", true)],
spawns: Some(Limits { pages: 128, endpoints: 2, notifications: 2, regions: 2 }),
system_control: true,
restart: false,
..server("spawntest", b"bin/spawntest", SMALL)
}];
@@ -138,5 +158,6 @@ pub const DESKTOP: &[Program] = &[Program {
uses: &["terminal", "permission"],
storage: &[users(b"home", true)],
signs_out: true,
takes_ctrl_c: true,
..server("shell", b"bin/shell", SMALL)
}];