Skip to main content

strat9_kernel/shell/commands/sys/
shutdown.rs

1use super::*;
2
3/// Graceful shutdown: stop strates in reverse order, then power off.
4///
5/// QEMU/KVM ACPI shutdown uses I/O port 0x604 (Bochs/QEMU) or 0xB004 (older).
6pub fn cmd_shutdown(_args: &[String]) -> Result<(), ShellError> {
7    shell_println!("[shutdown] Stopping silos...");
8
9    let mut silos = crate::silo::list_silos_snapshot();
10    silos.sort_by(|a, b| b.id.cmp(&a.id));
11
12    for s in &silos {
13        shell_println!("  stopping silo {} ({})", s.id, s.name);
14        let _ = crate::silo::kernel_suspend_silo(&alloc::format!("{}", s.id));
15    }
16
17    shell_println!("[shutdown] Killing remaining tasks...");
18    let current_tid = crate::process::current_task_clone().map(|t| t.id);
19    if let Some(tasks) = crate::process::get_all_tasks() {
20        for t in tasks.iter().rev() {
21            let tid = t.id;
22            if tid.as_u64() <= 1 || current_tid == Some(tid) {
23                continue;
24            }
25            crate::process::kill_task(tid);
26        }
27    }
28
29    for _ in 0..500 {
30        crate::process::yield_task();
31    }
32
33    shell_println!("[shutdown] Power off...");
34    unsafe {
35        crate::arch::x86_64::cli();
36        // QEMU/Bochs ACPI shutdown
37        crate::arch::x86_64::io::outw(0x604, 0x2000);
38        // Fallback: older QEMU
39        crate::arch::x86_64::io::outw(0xB004, 0x2000);
40        loop {
41            crate::arch::x86_64::hlt();
42        }
43    }
44}