Extend Red Bear runtime tooling

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-04-15 12:57:45 +01:00
parent e2c7b0ebf5
commit d9faecc4ba
8 changed files with 465 additions and 0 deletions
@@ -11,6 +11,35 @@ path = "src/bin/lspci.rs"
name = "lsusb"
path = "src/bin/lsusb.rs"
[[bin]]
name = "redbear-evtest"
path = "src/bin/evtest-rbos.rs"
[[bin]]
name = "redbear-input-inject"
path = "src/bin/input-inject-rbos.rs"
[[bin]]
name = "redbear-phase3-input-check"
path = "src/bin/redbear-phase3-input-check.rs"
[[bin]]
name = "redbear-phase4-wayland-check"
path = "src/bin/redbear-phase4-wayland-check.rs"
[[bin]]
name = "redbear-phase5-network-check"
path = "src/bin/redbear-phase5-network-check.rs"
[[bin]]
name = "redbear-phase6-kde-check"
path = "src/bin/redbear-phase6-kde-check.rs"
[[bin]]
name = "redbear-phase-iommu-check"
path = "src/bin/redbear-phase-iommu-check.rs"
[dependencies]
serde = { version = "1", features = ["derive"] }
serde_json = "1"
orbclient = "0.3"
@@ -0,0 +1,79 @@
use std::fs::File;
use std::io::Read;
use std::process;
use std::time::{Duration, Instant};
use redbear_hwutils::parse_args;
const PROGRAM: &str = "redbear-evtest";
const USAGE: &str = "Usage: redbear-evtest\n\nRead the first keyboard event from the udev-backed evdev consumer path and print it.";
const EVENT_SIZE: usize = 24;
const EV_KEY: u16 = 0x01;
#[derive(Clone, Copy, Debug)]
struct InputEvent {
event_type: u16,
code: u16,
value: i32,
}
impl InputEvent {
fn from_bytes(bytes: &[u8]) -> Result<Self, String> {
if bytes.len() != EVENT_SIZE {
return Err(format!("expected {EVENT_SIZE} bytes, got {}", bytes.len()));
}
Ok(Self {
event_type: u16::from_le_bytes([bytes[16], bytes[17]]),
code: u16::from_le_bytes([bytes[18], bytes[19]]),
value: i32::from_le_bytes([bytes[20], bytes[21], bytes[22], bytes[23]]),
})
}
}
fn run() -> Result<(), String> {
parse_args(PROGRAM, USAGE, std::env::args()).map_err(|err| {
if err.is_empty() {
process::exit(0);
}
err
})?;
let candidate_paths = ["/scheme/udev/dev/input/event0", "/scheme/evdev/event0"];
let mut last_error = String::new();
for event_path in candidate_paths {
let mut file = match File::open(event_path) {
Ok(file) => file,
Err(err) => {
last_error = format!("failed to open {event_path}: {err}");
continue;
}
};
let deadline = Instant::now() + Duration::from_secs(10);
let mut raw = [0_u8; EVENT_SIZE];
while Instant::now() < deadline {
file.read_exact(&mut raw)
.map_err(|err| format!("failed to read evdev event from {event_path}: {err}"))?;
let event = InputEvent::from_bytes(&raw)?;
if event.event_type == EV_KEY {
println!("SOURCE={event_path}");
println!("EV_KEY code={} value={}", event.code, event.value);
return Ok(());
}
}
last_error = format!("timed out waiting for a key event on {event_path}");
}
Err(last_error)
}
fn main() {
if let Err(err) = run() {
eprintln!("{PROGRAM}: {err}");
process::exit(1);
}
}
@@ -0,0 +1,106 @@
use std::fs::{File, OpenOptions};
use std::io::{Read, Write};
use std::process;
use std::time::{Duration, Instant};
use orbclient::{KeyEvent, K_A};
use redbear_hwutils::parse_args;
const PROGRAM: &str = "redbear-input-inject";
const USAGE: &str =
"Usage: redbear-input-inject\n\nInject a synthetic 'A' key press/release through /scheme/input/producer and verify the first evdev consumer event.";
const EVENT_SIZE: usize = 24;
const EV_KEY: u16 = 0x01;
#[derive(Clone, Copy, Debug)]
struct InputEvent {
event_type: u16,
code: u16,
value: i32,
}
impl InputEvent {
fn from_bytes(bytes: &[u8]) -> Result<Self, String> {
if bytes.len() != EVENT_SIZE {
return Err(format!("expected {EVENT_SIZE} bytes, got {}", bytes.len()));
}
Ok(Self {
event_type: u16::from_le_bytes([bytes[16], bytes[17]]),
code: u16::from_le_bytes([bytes[18], bytes[19]]),
value: i32::from_le_bytes([bytes[20], bytes[21], bytes[22], bytes[23]]),
})
}
}
fn open_consumer() -> Result<(File, &'static str), String> {
for path in ["/scheme/udev/dev/input/event0", "/scheme/evdev/event0"] {
if let Ok(file) = File::open(path) {
return Ok((file, path));
}
}
Err("failed to open an evdev consumer path".to_string())
}
fn run() -> Result<(), String> {
parse_args(PROGRAM, USAGE, std::env::args()).map_err(|err| {
if err.is_empty() {
process::exit(0);
}
err
})?;
let (mut consumer, consumer_path) = open_consumer()?;
let mut producer = OpenOptions::new()
.write(true)
.open("/scheme/input/producer")
.map_err(|err| format!("failed to open /scheme/input/producer: {err}"))?;
producer
.write_all(
&KeyEvent {
character: 'a',
scancode: K_A,
pressed: true,
}
.to_event(),
)
.map_err(|err| format!("failed to inject key press: {err}"))?;
producer
.write_all(
&KeyEvent {
character: 'a',
scancode: K_A,
pressed: false,
}
.to_event(),
)
.map_err(|err| format!("failed to inject key release: {err}"))?;
let deadline = Instant::now() + Duration::from_secs(5);
let mut raw = [0_u8; EVENT_SIZE];
while Instant::now() < deadline {
consumer
.read_exact(&mut raw)
.map_err(|err| format!("failed to read evdev event from {consumer_path}: {err}"))?;
let event = InputEvent::from_bytes(&raw)?;
if event.event_type == EV_KEY {
println!("Injected synthetic key event: A");
println!("SOURCE={consumer_path}");
println!("EV_KEY code={} value={}", event.code, event.value);
return Ok(());
}
}
Err(format!(
"timed out waiting for an evdev consumer event on {consumer_path}"
))
}
fn main() {
if let Err(err) = run() {
eprintln!("{PROGRAM}: {err}");
process::exit(1);
}
}
@@ -0,0 +1,67 @@
use std::path::Path;
use std::process::{self, Command};
use redbear_hwutils::parse_args;
const PROGRAM: &str = "redbear-phase-iommu-check";
const USAGE: &str = "Usage: redbear-phase-iommu-check\n\nShow the installed IOMMU validation surface inside the guest.";
fn require_path(path: &str) -> Result<(), String> {
if Path::new(path).exists() {
println!("{path}");
Ok(())
} else {
Err(format!("missing {path}"))
}
}
fn run() -> Result<(), String> {
parse_args(PROGRAM, USAGE, std::env::args()).map_err(|err| {
if err.is_empty() {
process::exit(0);
}
err
})?;
println!("=== Red Bear OS IOMMU Runtime Check ===");
require_path("/usr/bin/iommu")?;
let output = Command::new("/usr/bin/iommu")
.env("IOMMU_LOG", "info")
.arg("--self-test-init")
.output()
.map_err(|err| format!("failed to run /usr/bin/iommu --self-test-init: {err}"))?;
let stdout = String::from_utf8_lossy(&output.stdout);
let stderr = String::from_utf8_lossy(&output.stderr);
print!("{}", stdout);
print!("{}", stderr);
if !output.status.success() {
return Err(format!(
"iommu self-test exited with status {:?}",
output.status.code()
));
}
if !stdout.contains("units_detected=") {
return Err("iommu self-test did not report detected unit count".to_string());
}
if !stdout.contains("units_initialized_now=") {
return Err("iommu self-test did not report initialized unit count".to_string());
}
if !stdout.contains("units_initialized_after=") {
return Err("iommu self-test did not report initialized-after count".to_string());
}
if !stdout.contains("events_drained=") {
return Err("iommu self-test did not report drained events".to_string());
}
Ok(())
}
fn main() {
if let Err(err) = run() {
eprintln!("{PROGRAM}: {err}");
process::exit(1);
}
}
@@ -0,0 +1,38 @@
use std::process::{self, Command};
use redbear_hwutils::parse_args;
const PROGRAM: &str = "redbear-phase3-input-check";
const USAGE: &str =
"Usage: redbear-phase3-input-check\n\nRun the Phase 3 input-path check inside the guest.";
fn run_cmd(name: &str) -> Result<(), String> {
let status = Command::new(name)
.status()
.map_err(|err| format!("failed to run {name}: {err}"))?;
if status.success() {
Ok(())
} else {
Err(format!("{name} exited with status {status}"))
}
}
fn run() -> Result<(), String> {
parse_args(PROGRAM, USAGE, std::env::args()).map_err(|err| {
if err.is_empty() {
process::exit(0);
}
err
})?;
run_cmd("redbear-input-inject")?;
run_cmd("redbear-evtest")?;
Ok(())
}
fn main() {
if let Err(err) = run() {
eprintln!("{PROGRAM}: {err}");
process::exit(1);
}
}
@@ -0,0 +1,47 @@
use std::path::Path;
use std::process::{self, Command};
use redbear_hwutils::parse_args;
const PROGRAM: &str = "redbear-phase4-wayland-check";
const USAGE: &str = "Usage: redbear-phase4-wayland-check\n\nShow the installed Phase 4 Wayland launch surface inside the guest.";
fn require_path(path: &str) -> Result<(), String> {
if Path::new(path).exists() {
println!("{path}");
Ok(())
} else {
Err(format!("missing {path}"))
}
}
fn run() -> Result<(), String> {
parse_args(PROGRAM, USAGE, std::env::args()).map_err(|err| {
if err.is_empty() {
process::exit(0);
}
err
})?;
println!("=== Red Bear OS Phase 4 Wayland Runtime Check ===");
require_path("/usr/bin/orbital-wayland")?;
require_path("/usr/bin/wayland-session")?;
require_path("/usr/bin/smallvil")?;
let status = Command::new("redbear-info")
.arg("--json")
.status()
.map_err(|err| format!("failed to run redbear-info --json: {err}"))?;
if status.success() {
Ok(())
} else {
Err(format!("redbear-info exited with status {status}"))
}
}
fn main() {
if let Err(err) = run() {
eprintln!("{PROGRAM}: {err}");
process::exit(1);
}
}
@@ -0,0 +1,51 @@
use std::path::Path;
use std::process::{self, Command};
use redbear_hwutils::parse_args;
const PROGRAM: &str = "redbear-phase5-network-check";
const USAGE: &str = "Usage: redbear-phase5-network-check\n\nShow the installed Phase 5 networking/session plumbing surface inside the guest.";
fn require_path(path: &str) -> Result<(), String> {
if Path::new(path).exists() {
println!("{path}");
Ok(())
} else {
Err(format!("missing {path}"))
}
}
fn run() -> Result<(), String> {
parse_args(PROGRAM, USAGE, std::env::args()).map_err(|err| {
if err.is_empty() {
process::exit(0);
}
err
})?;
println!("=== Red Bear OS Phase 5 Networking Check ===");
require_path("/usr/bin/dbus-daemon")?;
let info_status = Command::new("redbear-info")
.arg("--json")
.status()
.map_err(|err| format!("failed to run redbear-info --json: {err}"))?;
if !info_status.success() {
return Err(format!("redbear-info exited with status {info_status}"));
}
let _ = Command::new("netctl").arg("status").status();
if Path::new("/run/dbus/system_bus_socket").exists() {
println!("DBUS_SYSTEM_BUS=present");
} else {
println!("DBUS_SYSTEM_BUS=missing");
}
Ok(())
}
fn main() {
if let Err(err) = run() {
eprintln!("{PROGRAM}: {err}");
process::exit(1);
}
}
@@ -0,0 +1,48 @@
use std::path::Path;
use std::process::{self, Command};
use redbear_hwutils::parse_args;
const PROGRAM: &str = "redbear-phase6-kde-check";
const USAGE: &str = "Usage: redbear-phase6-kde-check\n\nShow the installed Phase 6 KDE session surface inside the guest.";
fn require_path(path: &str) -> Result<(), String> {
if Path::new(path).exists() {
println!("{path}");
Ok(())
} else {
Err(format!("missing {path}"))
}
}
fn run() -> Result<(), String> {
parse_args(PROGRAM, USAGE, std::env::args()).map_err(|err| {
if err.is_empty() {
process::exit(0);
}
err
})?;
println!("=== Red Bear OS Phase 6 KDE Runtime Check ===");
require_path("/usr/bin/orbital-kde")?;
require_path("/usr/bin/kwin_wayland")?;
require_path("/usr/bin/dbus-daemon")?;
require_path("/usr/bin/seatd")?;
let status = Command::new("redbear-info")
.arg("--json")
.status()
.map_err(|err| format!("failed to run redbear-info --json: {err}"))?;
if status.success() {
Ok(())
} else {
Err(format!("redbear-info exited with status {status}"))
}
}
fn main() {
if let Err(err) = run() {
eprintln!("{PROGRAM}: {err}");
process::exit(1);
}
}