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:
@@ -8,9 +8,11 @@ mod factory;
|
||||
mod launch;
|
||||
mod load;
|
||||
mod manifest;
|
||||
mod output;
|
||||
mod selftest;
|
||||
mod session;
|
||||
mod spawn;
|
||||
mod supervise;
|
||||
|
||||
use libkos::fs::Storage;
|
||||
use libkos::syscall;
|
||||
@@ -25,37 +27,44 @@ pub(crate) const STORAGE_EP: CapSlot = CapSlot::const_new(2);
|
||||
|
||||
pub fn run() -> ! {
|
||||
libkos::start::set_console(devices::console());
|
||||
libkos::println!("init: started (pid={:#x})", syscall::get_process_id().raw());
|
||||
let printer = output::start();
|
||||
crate::outln!("init: started (pid={:#x})", syscall::get_process_id().raw());
|
||||
if !printer {
|
||||
crate::outln!("init: no printer thread; output waits on the log server");
|
||||
}
|
||||
|
||||
// Storage waits for its disk before serving, so this comes first.
|
||||
let found = devices::discover();
|
||||
let disk =
|
||||
libkos::device::give_device(STORAGE_EP, found.disk).is_ok() && found.disk.mmio.is_some();
|
||||
libkos::println!(
|
||||
crate::outln!(
|
||||
"init: disk: {}",
|
||||
if disk { "handed to its driver" } else { "none" }
|
||||
);
|
||||
|
||||
let Ok(mut storage) = Storage::attach(STORAGE_EP, STORAGE_BUF_VA) else {
|
||||
libkos::println!("init: cannot reach storage, nothing to load");
|
||||
crate::outln!("init: cannot reach storage, nothing to load");
|
||||
idle();
|
||||
};
|
||||
// Storage has nothing to print with yet; init speaks for it.
|
||||
libkos::println!("init: storage: up");
|
||||
crate::outln!("init: storage: up");
|
||||
let Some(scratch) = load::scratch() else {
|
||||
libkos::println!("init: no memory to load programs into");
|
||||
crate::outln!("init: no memory to load programs into");
|
||||
idle();
|
||||
};
|
||||
|
||||
let mut launcher = match launch::Launcher::new(&mut storage, scratch, found) {
|
||||
Ok(l) => l,
|
||||
Err(why) => {
|
||||
libkos::println!("init: {}", why);
|
||||
crate::outln!("init: {}", why);
|
||||
idle();
|
||||
}
|
||||
};
|
||||
launch_all(&mut launcher, manifest::SERVERS);
|
||||
give_storage_the_log();
|
||||
if !launcher.watch_storage() {
|
||||
crate::outln!("init: cannot watch storage");
|
||||
}
|
||||
|
||||
// The test image carries the SMP self-test; it and the tests run
|
||||
// instead of the desktop, and the last one halts the machine.
|
||||
@@ -64,7 +73,7 @@ pub fn run() -> ! {
|
||||
.open(b"bin/smptest")
|
||||
.is_ok_and(|h| storage.close(h).is_ok())
|
||||
{
|
||||
libkos::println!("init: running the SMP self-test");
|
||||
crate::outln!("init: running the SMP self-test");
|
||||
selftest::run(storage, scratch);
|
||||
manifest::TESTS
|
||||
} else {
|
||||
@@ -72,22 +81,22 @@ pub fn run() -> ! {
|
||||
};
|
||||
// Nothing that touches a user's files starts before someone is in.
|
||||
if let Err(why) = session::sign_in(&mut launcher) {
|
||||
libkos::println!("init: STOP ({})", why);
|
||||
crate::outln!("init: STOP ({})", why);
|
||||
idle();
|
||||
}
|
||||
|
||||
libkos::println!("init: all loaded, serving spawns");
|
||||
crate::outln!("init: all loaded, serving spawns");
|
||||
let _ = syscall::bind_notification(launcher.deaths);
|
||||
let ep = launcher.spawn_ep;
|
||||
server_framework::serve(&mut launcher, ep)
|
||||
}
|
||||
|
||||
fn launch_all(launcher: &mut launch::Launcher, programs: &[manifest::Program]) {
|
||||
fn launch_all(launcher: &mut launch::Launcher, programs: &'static [manifest::Program]) {
|
||||
for p in programs {
|
||||
libkos::print!("init: loading {}... ", p.name);
|
||||
match launcher.launch(p) {
|
||||
Ok(started) => libkos::println!("ok{}", started.note),
|
||||
Err(why) => libkos::println!("SKIP ({})", why),
|
||||
crate::out!("init: loading {}... ", p.name);
|
||||
match launcher.run(p, false) {
|
||||
Ok(note) => crate::outln!("ok{}", note),
|
||||
Err(why) => crate::outln!("SKIP ({})", why),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user