Files
RedBear-OS/recipes/drivers/pcid-spawner/src/main.rs
T
vasilito b9874d0941 feat: USB storage read/write proof + full Red Bear OS tree sync
Add redbear-usb-storage-check in-guest binary that validates USB mass
storage read and write I/O: discovers /scheme/disk/ devices, writes a
test pattern to sector 2048, reads it back, verifies match, restores
original content. Updates test-usb-storage-qemu.sh with write-proof
verification step.

Includes all accumulated Red Bear OS work: kernel patches, relibc
patches, driver infrastructure, DRM/GPU, KDE recipes, firmware,
validation tooling, build system hardening, and documentation.
2026-05-03 23:03:24 +01:00

102 lines
2.9 KiB
Rust

use std::fs;
use std::process::Command;
use anyhow::{anyhow, Context, Result};
use pcid_interface::config::Config;
use pcid_interface::PciFunctionHandle;
fn main() -> Result<()> {
let mut args = pico_args::Arguments::from_env();
let initfs = args.contains("--initfs");
common::setup_logging(
"bus",
"pci",
"pci-spawner.log",
common::output_level(),
common::file_level(),
);
let mut config_data = String::new();
for path in if initfs {
config::config_for_initfs("pcid")?
} else {
config::config("pcid")?
} {
if let Ok(tmp) = fs::read_to_string(path) {
config_data.push_str(&tmp);
}
}
let config: Config = toml::from_str(&config_data)?;
for entry in fs::read_dir("/scheme/pci")? {
let entry = entry.context("failed to get entry")?;
let device_path = entry.path();
log::trace!("ENTRY: {}", device_path.to_string_lossy());
let mut handle = match PciFunctionHandle::connect_by_path(&device_path) {
Ok(handle) => handle,
Err(err) if err.raw_os_error() == Some(syscall::ENOLCK) => {
log::debug!(
"pcid-spawner: {} already in use: {err}",
device_path.display(),
);
continue;
}
Err(err) => {
log::error!(
"pcid-spawner: failed to open channel for {}: {err}",
device_path.display(),
);
continue;
}
};
let full_device_id = handle.config().func.full_device_id;
log::debug!(
"pcid-spawner enumerated: PCI {} {}",
handle.config().func.addr,
full_device_id.display()
);
let Some(driver) = config
.drivers
.iter()
.find(|driver| driver.match_function(&full_device_id))
else {
log::debug!("no driver for {}, continuing", handle.config().func.addr);
continue;
};
let mut args = driver.command.iter();
let program = args
.next()
.ok_or_else(|| anyhow!("driver configuration entry did not have any command!"))?;
let program = if program.starts_with('/') {
program.to_owned()
} else {
"/usr/lib/drivers/".to_owned() + program
};
let mut command = Command::new(program);
command.args(args);
log::info!("pcid-spawner: spawn {:?}", command);
handle.enable_device();
let channel_fd = handle.into_inner_fd();
command.env("PCID_CLIENT_CHANNEL", channel_fd.to_string());
#[allow(deprecated, reason = "we can't yet move this to init")]
daemon::Daemon::spawn(command);
syscall::close(channel_fd as usize).unwrap();
}
Ok(())
}