15d0707e74
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.
116 lines
3.9 KiB
Rust
116 lines
3.9 KiB
Rust
//! Fbbootlogd renders the boot log and presents it on VT1.
|
|
//!
|
|
//! While fbbootlogd is superficially similar to fbcond, the major difference is:
|
|
//!
|
|
//! * Fbbootlogd doesn't accept input coming from the keyboard. It only allows getting written to.
|
|
//!
|
|
//! In the future fbbootlogd may also pull from logd as opposed to have logd push logs to it. And it
|
|
//! it could display a boot splash like plymouth instead of a boot log when booting in quiet mode.
|
|
|
|
use std::ops::ControlFlow;
|
|
use std::os::fd::AsRawFd;
|
|
|
|
use event::EventQueue;
|
|
use inputd::ConsumerHandleEvent;
|
|
use orbclient::Event;
|
|
use redox_scheme::Socket;
|
|
use scheme_utils::Blocking;
|
|
|
|
use crate::scheme::FbbootlogScheme;
|
|
|
|
mod scheme;
|
|
|
|
fn main() {
|
|
daemon::SchemeDaemon::new(daemon);
|
|
}
|
|
fn daemon(daemon: daemon::SchemeDaemon) -> ! {
|
|
let event_queue = EventQueue::new().expect("fbbootlogd: failed to create event queue");
|
|
|
|
event::user_data! {
|
|
enum Source {
|
|
Scheme,
|
|
Input,
|
|
}
|
|
}
|
|
|
|
let socket = Socket::nonblock().expect("fbbootlogd: failed to create fbbootlog scheme");
|
|
|
|
let mut scheme = FbbootlogScheme::new();
|
|
let mut handler = Blocking::new(&socket, 16);
|
|
|
|
event_queue
|
|
.subscribe(
|
|
socket.inner().raw(),
|
|
Source::Scheme,
|
|
event::EventFlags::READ,
|
|
)
|
|
.expect("fbbootlogd: failed to subscribe to scheme events");
|
|
|
|
event_queue
|
|
.subscribe(
|
|
scheme.input_handle.event_handle().as_raw_fd() as usize,
|
|
Source::Input,
|
|
event::EventFlags::READ,
|
|
)
|
|
.expect("fbbootlogd: failed to subscribe to scheme events");
|
|
|
|
{
|
|
let log_fd = socket
|
|
.create_this_scheme_fd(0, 0, 0, 0)
|
|
.expect("fbbootlogd: failed to create log fd");
|
|
// Add ourself as log sink
|
|
let log_file = libredox::Fd::open(
|
|
"/scheme/log/add_sink",
|
|
libredox::flag::O_WRONLY | libredox::flag::O_CLOEXEC,
|
|
0,
|
|
)
|
|
.expect("fbbootlogd: failed to open log/add_sink");
|
|
log_file
|
|
.call_wo(&log_fd.to_ne_bytes(), syscall::CallFlags::FD, &[])
|
|
.expect("fbbootlogd: failed to send log fd to log scheme.");
|
|
}
|
|
|
|
let _ = daemon.ready_sync_scheme(&socket, &mut scheme);
|
|
|
|
// This is not possible for now as fbbootlogd needs to open new displays at runtime for graphics
|
|
// driver handoff. In the future inputd may directly pass a handle to the display instead.
|
|
//libredox::call::setrens(0, 0).expect("fbbootlogd: failed to enter null namespace");
|
|
|
|
for event in event_queue {
|
|
match event.expect("fbbootlogd: failed to get event").user_data {
|
|
Source::Scheme => loop {
|
|
match handler
|
|
.process_requests_nonblocking(&mut scheme)
|
|
.expect("fbbootlogd: failed to process requests")
|
|
{
|
|
ControlFlow::Continue(()) => {}
|
|
ControlFlow::Break(()) => break,
|
|
}
|
|
},
|
|
Source::Input => {
|
|
let mut events = [Event::new(); 16];
|
|
loop {
|
|
match scheme
|
|
.input_handle
|
|
.read_events(&mut events)
|
|
.expect("fbbootlogd: error while reading events")
|
|
{
|
|
ConsumerHandleEvent::Events(&[]) => break,
|
|
ConsumerHandleEvent::Events(events) => {
|
|
for event in events {
|
|
scheme.handle_input(&event);
|
|
}
|
|
}
|
|
ConsumerHandleEvent::Handoff => {
|
|
eprintln!("fbbootlogd: handoff requested");
|
|
scheme.handle_handoff();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
std::process::exit(0);
|
|
}
|