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:
@@ -78,9 +78,9 @@ fn purge(fs: &mut Storage, folder: UserFolder) -> Result<(), &'static str> {
|
||||
|
||||
/// Runs the gatekeeper until someone is in and starts their session.
|
||||
pub(crate) fn sign_in(l: &mut Launcher) -> Result<(), &'static str> {
|
||||
libkos::print!("init: loading gatekeeper... ");
|
||||
crate::out!("init: loading gatekeeper... ");
|
||||
let gatekeeper = l.launch(&GATEKEEPER)?;
|
||||
libkos::println!("ok{}", gatekeeper.note);
|
||||
crate::outln!("ok{}", gatekeeper.note);
|
||||
let handover = gatekeeper.ep.ok_or("the gatekeeper serves nothing").and_then(ask);
|
||||
// It exits on its own once it has handed over.
|
||||
syscall::drop_cap(gatekeeper.process);
|
||||
@@ -91,11 +91,11 @@ pub(crate) fn sign_in(l: &mut Launcher) -> Result<(), &'static str> {
|
||||
// While storage is locked: it removes trees only then.
|
||||
if h.flags & unlocked::FRESH != 0 {
|
||||
fs.purge(b"users").map_err(|_| "cannot clear the users of an old keystore")?;
|
||||
libkos::println!("init: a new keystore, every earlier user's files removed");
|
||||
crate::outln!("init: a new keystore, every earlier user's files removed");
|
||||
}
|
||||
for id in h.removed.iter().flatten() {
|
||||
purge(fs, UserFolder::of(*id))?;
|
||||
libkos::println!("init: a removed user's files removed");
|
||||
crate::outln!("init: a removed user's files removed");
|
||||
}
|
||||
if guest {
|
||||
purge(fs, UserFolder::GUEST)?;
|
||||
@@ -107,31 +107,20 @@ pub(crate) fn sign_in(l: &mut Launcher) -> Result<(), &'static str> {
|
||||
}
|
||||
crate::factory::prepare(fs, folder, scratch)?;
|
||||
let name = core::str::from_utf8(&h.name[..h.name_len]).unwrap_or("someone");
|
||||
libkos::println!("init: {} is in", name);
|
||||
crate::outln!("init: {} is in", name);
|
||||
l.user = Some(User { folder, guest });
|
||||
start_session(l);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Starts what runs for a signed-in user, keeping each process to stop
|
||||
/// at sign-out.
|
||||
/// Starts what runs for a signed-in user; it is stopped at sign-out.
|
||||
fn start_session(l: &mut Launcher) {
|
||||
let desktop = l.desktop;
|
||||
for p in SESSION.iter().chain(desktop) {
|
||||
libkos::print!("init: loading {}... ", p.name);
|
||||
match l.launch(p) {
|
||||
Ok(started) => {
|
||||
libkos::println!("ok{}", started.note);
|
||||
match l.running.iter_mut().find(|r| r.is_none()) {
|
||||
Some(free) => *free = Some(started.process),
|
||||
None => {
|
||||
// Untracked, it could not be stopped at sign-out.
|
||||
let _ = syscall::kill(started.process);
|
||||
syscall::drop_cap(started.process);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(why) => libkos::println!("SKIP ({})", why),
|
||||
crate::out!("init: loading {}... ", p.name);
|
||||
match l.run(p, true) {
|
||||
Ok(note) => crate::outln!("ok{}", note),
|
||||
Err(why) => crate::outln!("SKIP ({})", why),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,25 +128,19 @@ fn start_session(l: &mut Launcher) {
|
||||
/// Stops the session, locks storage, and lets the next one in.
|
||||
pub(crate) fn sign_out(l: &mut Launcher) {
|
||||
l.spawner.clear();
|
||||
for process in l.running.iter_mut().filter_map(Option::take) {
|
||||
let _ = syscall::kill(process);
|
||||
syscall::drop_cap(process);
|
||||
}
|
||||
if let Some(terminal) = l.served("terminal") {
|
||||
let _ = syscall::request(terminal, [types::terminal::SIGNED_OUT, 0, 0, 0]);
|
||||
}
|
||||
l.stop_session();
|
||||
let user = l.user.take();
|
||||
let (fs, _) = l.storage();
|
||||
let locked = fs.lock().is_ok();
|
||||
// A guest leaves nothing behind.
|
||||
let cleared = !user.is_some_and(|u| u.guest) || purge(fs, UserFolder::GUEST).is_ok();
|
||||
libkos::println!("init: signed out");
|
||||
crate::outln!("init: signed out");
|
||||
let next = match locked && cleared {
|
||||
true => sign_in(l),
|
||||
false => Err("storage would not lock"),
|
||||
};
|
||||
if let Err(why) = next {
|
||||
libkos::println!("init: STOP ({})", why);
|
||||
crate::outln!("init: STOP ({})", why);
|
||||
crate::idle();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user