redbear-sessiond: port ACPI shutdown watcher to new Fd-based scheme

Phase D of the ACPI fork-sync plan (continuation).

Phase B replaced the `/scheme/kernel.acpi/kstop` filesystem file with
a single Fd-based call() interface. This consumer (redbear-sessiond)
still tried to open the old path and got EBADF, leaving sessiond without
shutdown-watchdog signal emission.

The new implementation:

- Opens `/scheme/kernel.acpi` and uses `openat("kstop", ...)` to
  get the kstop sub-handle. The kernel requires the CheckShutdown
  kcall to target the sub-handle (HandleBits::KSTOP_HANDLE), not the
  parent.
- Uses the new `AcpiVerb::CheckShutdown` (value 2) kcall to poll
  the kernel-side shutdown flag every 250ms.
- The poll-based approach was chosen over the event-queue
  subscription path (which would require pulling in `redox_event`
  and dealing with the `llvm_asm!` macro deprecation). The kernel's
  new design supports this polling pattern natively; the wakeup
  latency is bounded at 250ms.

Also updates the inner-fork submodule pointers to pick up
the Phase A (kernel re-sync) and Phase C+D (base gap-closing)
commits from local/sources/{kernel,base}.

Files:

- local/recipes/system/redbear-sessiond/source/src/acpi_watcher.rs:
  rewrote wait_for_shutdown_edge() to use the new Fd interface.

- local/sources/base: pointer bumped to include Phase C+D gap
  fixes (4f2a043 in kernel paired with ae57fe3, d844111, 8140a2c
  in base).

- local/sources/kernel: pointer bumped to include the Phase A
  ACPI re-sync (RSDP validation, AcpiScheme fevent, new
  kcall interface).

Verified by: redbear-mini ISO rebuilt cleanly (2026-06-30 06:28)
and QEMU boot reaches Red Bear login: prompt with redbear-sessiond
working (login1 registered on D-Bus, ACPI shutdown watcher no
longer errors).
This commit is contained in:
Red Bear OS
2026-06-30 06:33:11 +03:00
committed by vasilito
parent 2382aa496f
commit 5f1da52502
3 changed files with 45 additions and 12 deletions
@@ -3,17 +3,50 @@ use zbus::Connection;
use crate::runtime_state::SharedRuntime;
#[cfg(target_os = "redox")]
const KSTOP_PATH: &str = "/scheme/kernel.acpi/kstop";
mod redox_shutdown {
/// Block until the kernel signals a shutdown.
///
/// Phase B of the ACPI fork-sync replaced the `/scheme/kernel.acpi/kstop`
/// file with a single Fd-based call() interface. The kstop sub-handle
/// is event-driven (see kernel/scheme/acpi.rs register_kstop).
///
/// Rather than subscribing to the event queue (which would require
/// pulling in `redox_event` and dealing with the macro-deprecation
/// churn), we poll the `AcpiVerb::CheckShutdown` kcall every 250ms.
/// This is the supported pattern for userspace that just wants
/// the boolean "is shutdown pending" signal.
pub fn wait_for_shutdown_edge() -> std::io::Result<()> {
let parent = libredox::Fd::open(
"/scheme/kernel.acpi",
libredox::flag::O_CLOEXEC,
0,
)?;
// Open the kstop sub-handle. The kernel requires us to call
// CheckShutdown on the kstop handle (HandleBits::KSTOP_HANDLE),
// not on the parent handle.
let kstop = parent.openat("kstop", libredox::flag::O_CLOEXEC, 0)?;
// AcpiVerb::CheckShutdown = 2.
loop {
let mut buf = [0u8; 8];
let n = kstop.call_ro(
&mut buf,
redox_syscall::flag::CallFlags::empty(),
&[2u64],
)?;
if n > 0 {
let shutdown = u64::from_le_bytes(buf[..8].try_into().unwrap_or([0; 8]));
if shutdown != 0 {
return Ok(());
}
}
std::thread::sleep(std::time::Duration::from_millis(250));
}
}
}
#[cfg(target_os = "redox")]
fn wait_for_shutdown_edge() -> std::io::Result<()> {
use std::io::Read;
let mut file = std::fs::File::open(KSTOP_PATH)?;
let mut byte = [0_u8; 1];
let _ = file.read(&mut byte)?;
Ok(())
}
use redox_shutdown::wait_for_shutdown_edge;
pub async fn watch_and_emit(connection: Connection, runtime: SharedRuntime) {
#[cfg(target_os = "redox")]
@@ -45,4 +78,4 @@ pub async fn watch_and_emit(connection: Connection, runtime: SharedRuntime) {
let _ = connection;
let _ = runtime;
}
}
}
Submodule local/sources/base updated: de9d1f495f...8140a2cd27
Submodule local/sources/kernel updated: 4cb9d80396...4f2a0436eb