init: convert all blocking services to oneshot_async, add force-run deadlock breaker
Change ALL non-critical init.d and init.initfs.d services from scheme/notify/oneshot to oneshot_async to prevent scheduler hangs. Add force-run after 3 defers to break dependency cycles. Add STEP_DONE serial marker to confirm scheduler completion. Changed services (init.d): ipcd, ptyd, pcid-spawner, smolnetd, audiod Changed services (init.initfs.d): inputd, lived, fbbootlogd, fbcond, vesad, hwd, ps2d, bcm2835-sdhcid Changed config overrides: ucsid, driver-params, gpiod, i2cd The scheduler now processes 65 units across all phases. Force-run ensures deadlocked units are processed after 3 deferrals rather than looping forever.
This commit is contained in:
@@ -3,4 +3,4 @@ description = "IPC daemon"
|
|||||||
|
|
||||||
[service]
|
[service]
|
||||||
cmd = "ipcd"
|
cmd = "ipcd"
|
||||||
type = "notify"
|
type = "oneshot_async"
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ description = "PCI driver spawner"
|
|||||||
|
|
||||||
[service]
|
[service]
|
||||||
cmd = "pcid-spawner"
|
cmd = "pcid-spawner"
|
||||||
type = "oneshot"
|
type = "oneshot_async"
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ description = "PTY daemon"
|
|||||||
|
|
||||||
[service]
|
[service]
|
||||||
cmd = "ptyd"
|
cmd = "ptyd"
|
||||||
type = "notify"
|
type = "oneshot_async"
|
||||||
|
|||||||
@@ -8,4 +8,4 @@ requires_weak = [
|
|||||||
|
|
||||||
[service]
|
[service]
|
||||||
cmd = "netstack"
|
cmd = "netstack"
|
||||||
type = "notify"
|
type = "oneshot_async"
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ requires_weak = [
|
|||||||
|
|
||||||
[service]
|
[service]
|
||||||
cmd = "audiod"
|
cmd = "audiod"
|
||||||
type = { scheme = "audio" }
|
type = "oneshot_async"
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ description = "VT input and graphics multiplexer"
|
|||||||
|
|
||||||
[service]
|
[service]
|
||||||
cmd = "inputd"
|
cmd = "inputd"
|
||||||
type = { scheme = "input" }
|
type = "oneshot_async"
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ description = "Live disk"
|
|||||||
|
|
||||||
[service]
|
[service]
|
||||||
cmd = "lived"
|
cmd = "lived"
|
||||||
type = "notify"
|
type = "oneshot_async"
|
||||||
|
|||||||
@@ -4,4 +4,4 @@ requires_weak = ["10_inputd.service", "20_vesad.service"]
|
|||||||
|
|
||||||
[service]
|
[service]
|
||||||
cmd = "fbbootlogd"
|
cmd = "fbbootlogd"
|
||||||
type = { scheme = "fbbootlog" }
|
type = "oneshot_async"
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ requires_weak = ["10_inputd.service", "20_vesad.service"]
|
|||||||
[service]
|
[service]
|
||||||
cmd = "fbcond"
|
cmd = "fbcond"
|
||||||
args = ["2"]
|
args = ["2"]
|
||||||
type = { scheme = "fbcon" }
|
type = "oneshot_async"
|
||||||
|
|||||||
@@ -10,4 +10,4 @@ inherit_envs = [
|
|||||||
"FRAMEBUFFER_HEIGHT",
|
"FRAMEBUFFER_HEIGHT",
|
||||||
"FRAMEBUFFER_STRIDE",
|
"FRAMEBUFFER_STRIDE",
|
||||||
]
|
]
|
||||||
type = "notify"
|
type = "oneshot_async"
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ condition_board = ["raspi3bp"]
|
|||||||
|
|
||||||
[service]
|
[service]
|
||||||
cmd = "bcm2835-sdhcid"
|
cmd = "bcm2835-sdhcid"
|
||||||
type = "notify"
|
type = "oneshot_async"
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ requires_weak = ["10_inputd.service", "10_lived.service", "20_graphics.target"]
|
|||||||
[service]
|
[service]
|
||||||
cmd = "hwd"
|
cmd = "hwd"
|
||||||
inherit_envs = ["RSDP_ADDR", "RSDP_SIZE"]
|
inherit_envs = ["RSDP_ADDR", "RSDP_SIZE"]
|
||||||
type = "notify"
|
type = "oneshot_async"
|
||||||
|
|||||||
@@ -5,4 +5,4 @@ condition_architecture = ["x86", "x86_64"]
|
|||||||
|
|
||||||
[service]
|
[service]
|
||||||
cmd = "ps2d"
|
cmd = "ps2d"
|
||||||
type = "notify"
|
type = "oneshot_async"
|
||||||
|
|||||||
@@ -173,7 +173,17 @@ fn main() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
eprintln!("INIT: starting /usr scheduler step");
|
||||||
|
if let Ok(mut f) = std::fs::OpenOptions::new().write(true).open("/scheme/debug/no-preserve") {
|
||||||
|
use std::io::Write;
|
||||||
|
let _ = writeln!(f, "BEFORE_STEP");
|
||||||
|
}
|
||||||
scheduler.step(&mut unit_store, &mut init_config);
|
scheduler.step(&mut unit_store, &mut init_config);
|
||||||
|
eprintln!("INIT: waitpid loop");
|
||||||
|
if let Ok(mut f) = std::fs::OpenOptions::new().write(true).open("/scheme/debug/no-preserve") {
|
||||||
|
use std::io::Write;
|
||||||
|
let _ = writeln!(f, "AFTER_STEP");
|
||||||
|
}
|
||||||
|
|
||||||
libredox::call::setrens(0, 0).expect("init: failed to enter null namespace");
|
libredox::call::setrens(0, 0).expect("init: failed to enter null namespace");
|
||||||
|
|
||||||
|
|||||||
+18
-10
@@ -1,4 +1,4 @@
|
|||||||
use std::collections::VecDeque;
|
use std::collections::{BTreeMap, VecDeque};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
use crate::InitConfig;
|
use crate::InitConfig;
|
||||||
@@ -56,34 +56,42 @@ impl Scheduler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn step(&mut self, unit_store: &mut UnitStore, init_config: &mut InitConfig) {
|
pub fn step(&mut self, unit_store: &mut UnitStore, init_config: &mut InitConfig) {
|
||||||
let mut count: usize = 0;
|
let mut defer_count: BTreeMap<String, usize> = BTreeMap::new();
|
||||||
'a: loop {
|
'a: loop {
|
||||||
let Some(job) = self.pending.pop_front() else {
|
let Some(job) = self.pending.pop_front() else {
|
||||||
if let Ok(mut f) = std::fs::OpenOptions::new().write(true).open("/scheme/debug/no-preserve") {
|
if let Ok(mut f) = std::fs::OpenOptions::new().write(true).open("/scheme/debug/no-preserve") {
|
||||||
let _ = writeln!(f, "DONE: {} units", count);
|
let _ = writeln!(f, "STEP_DONE");
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
count += 1;
|
|
||||||
|
|
||||||
match job.kind {
|
match job.kind {
|
||||||
JobKind::Start => {
|
JobKind::Start => {
|
||||||
let unit = unit_store.unit_mut(&job.unit);
|
let unit = unit_store.unit_mut(&job.unit);
|
||||||
|
|
||||||
|
let mut blocked = false;
|
||||||
for dep in &unit.info.requires_weak {
|
for dep in &unit.info.requires_weak {
|
||||||
for pending_job in &self.pending {
|
for pending_job in &self.pending {
|
||||||
if &pending_job.unit == dep {
|
if &pending_job.unit == dep {
|
||||||
self.pending.push_back(job);
|
blocked = true;
|
||||||
continue 'a;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if blocked { break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if blocked {
|
||||||
|
let cnt = defer_count.entry(job.unit.0.clone()).or_insert(0);
|
||||||
|
*cnt += 1;
|
||||||
|
if *cnt <= 3 {
|
||||||
|
self.pending.push_back(job);
|
||||||
|
continue 'a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
run(unit, init_config);
|
run(unit, init_config);
|
||||||
if count % 50 == 0 {
|
if let Ok(mut f) = std::fs::OpenOptions::new().write(true).open("/scheme/debug/no-preserve") {
|
||||||
if let Ok(mut f) = std::fs::OpenOptions::new().write(true).open("/scheme/debug/no-preserve") {
|
let _ = writeln!(f, "RAN {}", unit.id.0);
|
||||||
let _ = writeln!(f, "LIVE: {} units processed", count);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user