From f06923b20196ad9f66403e484e5620f7874478ce Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 3 Dec 2025 22:19:16 +0100 Subject: [PATCH 1/7] Standardize main function of all daemons --- audiod/src/main.rs | 8 +- drivers/audio/ac97d/src/main.rs | 195 ++++++++++---------- drivers/audio/ihdad/src/main.rs | 1 - drivers/audio/sb16d/src/main.rs | 159 +++++++++-------- drivers/graphics/bgad/src/main.rs | 72 ++++---- drivers/graphics/fbbootlogd/src/main.rs | 4 +- drivers/graphics/fbcond/src/main.rs | 8 +- drivers/graphics/vesad/src/main.rs | 12 +- drivers/graphics/virtio-gpud/src/main.rs | 10 +- drivers/net/alxd/src/main.rs | 172 +++++++++--------- drivers/net/e1000d/src/main.rs | 91 +++++----- drivers/net/ixgbed/src/main.rs | 99 ++++++----- drivers/net/virtio-netd/src/main.rs | 10 +- drivers/pcid/src/main.rs | 8 +- drivers/storage/lived/src/main.rs | 84 ++++----- drivers/storage/usbscsid/src/main.rs | 6 +- drivers/storage/virtio-blkd/src/main.rs | 14 +- drivers/vboxd/src/main.rs | 217 +++++++++++------------ ipcd/src/main.rs | 20 ++- netstack/src/main.rs | 20 ++- ptyd/src/main.rs | 119 +++++++------ ramfs/src/main.rs | 54 +++--- zerod/src/main.rs | 56 +++--- 23 files changed, 729 insertions(+), 710 deletions(-) diff --git a/audiod/src/main.rs b/audiod/src/main.rs index 2aeda1c817..192967572f 100644 --- a/audiod/src/main.rs +++ b/audiod/src/main.rs @@ -88,7 +88,11 @@ fn daemon(daemon: Daemon) -> anyhow::Result<()> { } fn main() { - Daemon::new(|x| match daemon(x) { + Daemon::new(inner); +} + +fn inner(x: Daemon) -> ! { + match daemon(x) { Ok(()) => { process::exit(0); } @@ -96,5 +100,5 @@ fn main() { eprintln!("audiod: {}", err); process::exit(1); } - }); + } } diff --git a/drivers/audio/ac97d/src/main.rs b/drivers/audio/ac97d/src/main.rs index d31be1a00d..1aa36ca774 100644 --- a/drivers/audio/ac97d/src/main.rs +++ b/drivers/audio/ac97d/src/main.rs @@ -18,6 +18,10 @@ use std::cell::RefCell; pub mod device; fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let pcid_handle = PciFunctionHandle::connect_default(); let pci_config = pcid_handle.config(); @@ -34,106 +38,101 @@ fn main() { println!(" + ac97 {}", pci_config.func.display()); - // Daemonize - daemon::Daemon::new(move |daemon| { - common::setup_logging( - "audio", - "pci", - &name, - common::output_level(), - common::file_level(), - ); + common::setup_logging( + "audio", + "pci", + &name, + common::output_level(), + common::file_level(), + ); - common::acquire_port_io_rights() - .expect("ac97d: failed to set I/O privilege level to Ring 3"); + common::acquire_port_io_rights().expect("ac97d: failed to set I/O privilege level to Ring 3"); - let mut irq_file = irq.irq_handle("ac97d"); + let mut irq_file = irq.irq_handle("ac97d"); - let device = RefCell::new(unsafe { - device::Ac97::new(bar0, bar1).expect("ac97d: failed to allocate device") - }); - let socket = Socket::nonblock("audiohw").expect("ac97d: failed to create socket"); - let mut readiness_based = ReadinessBased::new(&socket, 16); - - user_data! { - enum Source { - Irq, - Scheme, - } - } - - let event_queue = - EventQueue::::new().expect("ac97d: Could not create event queue."); - event_queue - .subscribe( - irq_file.as_raw_fd() as usize, - Source::Irq, - event::EventFlags::READ, - ) - .unwrap(); - event_queue - .subscribe( - socket.inner().raw(), - Source::Scheme, - event::EventFlags::READ, - ) - .unwrap(); - - daemon.ready(); - - libredox::call::setrens(0, 0).expect("ac97d: failed to enter null namespace"); - - let all = [Source::Irq, Source::Scheme]; - for event in all - .into_iter() - .chain(event_queue.map(|e| e.expect("ac97d: failed to get next event").user_data)) - { - match event { - Source::Irq => { - let mut irq = [0; 8]; - irq_file.read(&mut irq).unwrap(); - - if !device.borrow_mut().irq() { - continue; - } - irq_file.write(&mut irq).unwrap(); - - readiness_based - .poll_all_requests(|| device.borrow_mut()) - .expect("ac97d: failed to poll requests"); - - /* - let next_read = device_irq.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ - } - Source::Scheme => { - if !readiness_based - .read_requests() - .expect("ac97d: failed to read from socket") - { - break; - } - readiness_based.process_requests(|| device.borrow_mut()); - if !readiness_based - .write_responses() - .expect("ac97d: failed to write to socket") - { - break; - } - - /* - let next_read = device.borrow().next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ - } - } - } - - std::process::exit(0); + let device = RefCell::new(unsafe { + device::Ac97::new(bar0, bar1).expect("ac97d: failed to allocate device") }); + let socket = Socket::nonblock("audiohw").expect("ac97d: failed to create socket"); + let mut readiness_based = ReadinessBased::new(&socket, 16); + + user_data! { + enum Source { + Irq, + Scheme, + } + } + + let event_queue = EventQueue::::new().expect("ac97d: Could not create event queue."); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); + event_queue + .subscribe( + socket.inner().raw(), + Source::Scheme, + event::EventFlags::READ, + ) + .unwrap(); + + daemon.ready(); + + libredox::call::setrens(0, 0).expect("ac97d: failed to enter null namespace"); + + let all = [Source::Irq, Source::Scheme]; + for event in all + .into_iter() + .chain(event_queue.map(|e| e.expect("ac97d: failed to get next event").user_data)) + { + match event { + Source::Irq => { + let mut irq = [0; 8]; + irq_file.read(&mut irq).unwrap(); + + if !device.borrow_mut().irq() { + continue; + } + irq_file.write(&mut irq).unwrap(); + + readiness_based + .poll_all_requests(|| device.borrow_mut()) + .expect("ac97d: failed to poll requests"); + + /* + let next_read = device_irq.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ + } + Source::Scheme => { + if !readiness_based + .read_requests() + .expect("ac97d: failed to read from socket") + { + break; + } + readiness_based.process_requests(|| device.borrow_mut()); + if !readiness_based + .write_responses() + .expect("ac97d: failed to write to socket") + { + break; + } + + /* + let next_read = device.borrow().next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ + } + } + } + + std::process::exit(0); } diff --git a/drivers/audio/ihdad/src/main.rs b/drivers/audio/ihdad/src/main.rs index 7660681a71..4bb4652fdb 100755 --- a/drivers/audio/ihdad/src/main.rs +++ b/drivers/audio/ihdad/src/main.rs @@ -140,6 +140,5 @@ fn daemon(daemon: daemon::Daemon) -> ! { } fn main() { - // Daemonize daemon::Daemon::new(daemon); } diff --git a/drivers/audio/sb16d/src/main.rs b/drivers/audio/sb16d/src/main.rs index 72e9c82c8e..7701f55b87 100644 --- a/drivers/audio/sb16d/src/main.rs +++ b/drivers/audio/sb16d/src/main.rs @@ -11,6 +11,10 @@ use event::{user_data, EventQueue}; pub mod device; fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let mut args = env::args().skip(1); let addr_str = args.next().unwrap_or("220".to_string()); @@ -18,99 +22,94 @@ fn main() { println!(" + sb16 at 0x{:X}\n", addr); - // Daemonize - daemon::Daemon::new(move |daemon| { - common::setup_logging( - "audio", - "pci", - "sb16", - common::output_level(), - common::file_level(), - ); + common::setup_logging( + "audio", + "pci", + "sb16", + common::output_level(), + common::file_level(), + ); - common::acquire_port_io_rights().expect("sb16d: failed to acquire port IO rights"); + common::acquire_port_io_rights().expect("sb16d: failed to acquire port IO rights"); - let device = RefCell::new(unsafe { - device::Sb16::new(addr).expect("sb16d: failed to allocate device") - }); - let socket = Socket::nonblock("audiohw").expect("sb16d: failed to create socket"); - let mut readiness_based = ReadinessBased::new(&socket, 16); + let device = + RefCell::new(unsafe { device::Sb16::new(addr).expect("sb16d: failed to allocate device") }); + let socket = Socket::nonblock("audiohw").expect("sb16d: failed to create socket"); + let mut readiness_based = ReadinessBased::new(&socket, 16); - //TODO: error on multiple IRQs? - let irq_file = match device.borrow().irqs.first() { - Some(irq) => Fd::open(&format!("/scheme/irq/{}", irq), flag::O_RDWR, 0) - .expect("sb16d: failed to open IRQ file"), - None => panic!("sb16d: no IRQs found"), - }; - user_data! { - enum Source { - Irq, - Scheme, - } + //TODO: error on multiple IRQs? + let irq_file = match device.borrow().irqs.first() { + Some(irq) => Fd::open(&format!("/scheme/irq/{}", irq), flag::O_RDWR, 0) + .expect("sb16d: failed to open IRQ file"), + None => panic!("sb16d: no IRQs found"), + }; + user_data! { + enum Source { + Irq, + Scheme, } + } - let event_queue = - EventQueue::::new().expect("sb16d: Could not create event queue."); - event_queue - .subscribe(irq_file.raw(), Source::Irq, event::EventFlags::READ) - .unwrap(); - event_queue - .subscribe( - socket.inner().raw(), - Source::Scheme, - event::EventFlags::READ, - ) - .unwrap(); + let event_queue = EventQueue::::new().expect("sb16d: Could not create event queue."); + event_queue + .subscribe(irq_file.raw(), Source::Irq, event::EventFlags::READ) + .unwrap(); + event_queue + .subscribe( + socket.inner().raw(), + Source::Scheme, + event::EventFlags::READ, + ) + .unwrap(); - daemon.ready(); + daemon.ready(); - libredox::call::setrens(0, 0).expect("sb16d: failed to enter null namespace"); + libredox::call::setrens(0, 0).expect("sb16d: failed to enter null namespace"); - let all = [Source::Irq, Source::Scheme]; + let all = [Source::Irq, Source::Scheme]; - for event in all - .into_iter() - .chain(event_queue.map(|e| e.expect("sb16d: failed to get next event").user_data)) - { - match event { - Source::Irq => { - let mut irq = [0; 8]; - irq_file.read(&mut irq).unwrap(); + for event in all + .into_iter() + .chain(event_queue.map(|e| e.expect("sb16d: failed to get next event").user_data)) + { + match event { + Source::Irq => { + let mut irq = [0; 8]; + irq_file.read(&mut irq).unwrap(); - if !device.borrow_mut().irq() { - continue; - } - irq_file.write(&mut irq).unwrap(); - - readiness_based - .poll_all_requests(|| device.borrow_mut()) - .expect("sb16d: failed to poll requests"); - - /* - let next_read = device_irq.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + if !device.borrow_mut().irq() { + continue; } - Source::Scheme => { - if !readiness_based - .read_requests() - .expect("sb16d: failed to read from socket") - { - break; - } - readiness_based.process_requests(|| device.borrow_mut()); - if !readiness_based - .write_responses() - .expect("sb16d: failed to write to socket") - { - break; - } + irq_file.write(&mut irq).unwrap(); + + readiness_based + .poll_all_requests(|| device.borrow_mut()) + .expect("sb16d: failed to poll requests"); + + /* + let next_read = device_irq.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ + } + Source::Scheme => { + if !readiness_based + .read_requests() + .expect("sb16d: failed to read from socket") + { + break; + } + readiness_based.process_requests(|| device.borrow_mut()); + if !readiness_based + .write_responses() + .expect("sb16d: failed to write to socket") + { + break; } } } + } - std::process::exit(0); - }); + std::process::exit(0); } diff --git a/drivers/graphics/bgad/src/main.rs b/drivers/graphics/bgad/src/main.rs index 640908a8d9..7abb2beba0 100644 --- a/drivers/graphics/bgad/src/main.rs +++ b/drivers/graphics/bgad/src/main.rs @@ -13,6 +13,10 @@ mod scheme; // FIXME add a driver-graphics implementation fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let mut pcid_handle = PciFunctionHandle::connect_default(); let pci_config = pcid_handle.config(); @@ -29,46 +33,44 @@ fn main() { log::info!("BGA {}", pci_config.func.display()); - daemon::Daemon::new(move |daemon| { - let socket = Socket::create("bga").expect("bgad: failed to create bga scheme"); + let socket = Socket::create("bga").expect("bgad: failed to create bga scheme"); - let bar = unsafe { pcid_handle.map_bar(2) }.ptr.as_ptr(); + let bar = unsafe { pcid_handle.map_bar(2) }.ptr.as_ptr(); - let mut bga = unsafe { Bga::new(bar) }; - log::debug!("BGA {}x{}", bga.width(), bga.height()); + let mut bga = unsafe { Bga::new(bar) }; + log::debug!("BGA {}x{}", bga.width(), bga.height()); - let mut scheme = BgaScheme { - bga, - display: ProducerHandle::new().ok(), + let mut scheme = BgaScheme { + bga, + display: ProducerHandle::new().ok(), + }; + + scheme.update_size(); + + libredox::call::setrens(0, 0).expect("bgad: failed to enter null namespace"); + + daemon.ready(); + + loop { + let Some(request) = socket + .next_request(SignalBehavior::Restart) + .expect("bgad: failed to get next scheme request") + else { + // Scheme likely got unmounted + std::process::exit(0); }; + match request.kind() { + RequestKind::Call(call) => { + let response = call.handle_sync(&mut scheme); - scheme.update_size(); - - libredox::call::setrens(0, 0).expect("bgad: failed to enter null namespace"); - - daemon.ready(); - - loop { - let Some(request) = socket - .next_request(SignalBehavior::Restart) - .expect("bgad: failed to get next scheme request") - else { - // Scheme likely got unmounted - std::process::exit(0); - }; - match request.kind() { - RequestKind::Call(call) => { - let response = call.handle_sync(&mut scheme); - - socket - .write_response(response, SignalBehavior::Restart) - .expect("bgad: failed to write next scheme response"); - } - RequestKind::OnClose { id } => { - scheme.on_close(id); - } - _ => (), + socket + .write_response(response, SignalBehavior::Restart) + .expect("bgad: failed to write next scheme response"); } + RequestKind::OnClose { id } => { + scheme.on_close(id); + } + _ => (), } - }); + } } diff --git a/drivers/graphics/fbbootlogd/src/main.rs b/drivers/graphics/fbbootlogd/src/main.rs index bee32c5398..69e18659c8 100644 --- a/drivers/graphics/fbbootlogd/src/main.rs +++ b/drivers/graphics/fbbootlogd/src/main.rs @@ -21,9 +21,9 @@ use crate::scheme::FbbootlogScheme; mod scheme; fn main() { - daemon::Daemon::new(|daemon| inner(daemon)); + daemon::Daemon::new(daemon); } -fn inner(daemon: daemon::Daemon) -> ! { +fn daemon(daemon: daemon::Daemon) -> ! { let event_queue = EventQueue::new().expect("fbbootlogd: failed to create event queue"); event::user_data! { diff --git a/drivers/graphics/fbcond/src/main.rs b/drivers/graphics/fbcond/src/main.rs index ad0c88016a..1ecfd30403 100644 --- a/drivers/graphics/fbcond/src/main.rs +++ b/drivers/graphics/fbcond/src/main.rs @@ -13,6 +13,9 @@ mod scheme; mod text; fn main() { + daemon::Daemon::new(daemon); +} +fn daemon(daemon: daemon::Daemon) -> ! { let vt_ids = env::args() .skip(1) .map(|arg| arg.parse().expect("invalid vt number")) @@ -26,9 +29,6 @@ fn main() { common::file_level(), ); - daemon::Daemon::new(|daemon| inner(daemon, &vt_ids)); -} -fn inner(daemon: daemon::Daemon, vt_ids: &[usize]) -> ! { let mut event_queue = EventQueue::new().expect("fbcond: failed to create event queue"); // FIXME listen for resize events from inputd and handle them @@ -42,7 +42,7 @@ fn inner(daemon: daemon::Daemon, vt_ids: &[usize]) -> ! { ) .expect("fbcond: failed to subscribe to scheme events"); - let mut scheme = FbconScheme::new(vt_ids, &mut event_queue); + let mut scheme = FbconScheme::new(&vt_ids, &mut event_queue); // This is not possible for now as fbcond needs to open new displays at runtime for graphics // driver handoff. In the future inputd may directly pass a handle to the display instead. diff --git a/drivers/graphics/vesad/src/main.rs b/drivers/graphics/vesad/src/main.rs index f5457c6fdb..5d71b9d5fb 100644 --- a/drivers/graphics/vesad/src/main.rs +++ b/drivers/graphics/vesad/src/main.rs @@ -12,9 +12,13 @@ use crate::scheme::{FbAdapter, FrameBuffer}; mod scheme; fn main() { + daemon::Daemon::new(daemon); +} +fn daemon(daemon: daemon::Daemon) -> ! { if env::var("FRAMEBUFFER_WIDTH").is_err() { println!("vesad: No boot framebuffer"); - return; + daemon.ready(); + std::process::exit(0); } let width = usize::from_str_radix( @@ -45,7 +49,8 @@ fn main() { if phys == 0 { println!("vesad: Boot framebuffer at address 0"); - return; + daemon.ready(); + std::process::exit(0); } let mut framebuffers = vec![unsafe { FrameBuffer::new(phys, width, height, stride) }]; @@ -69,9 +74,6 @@ fn main() { }; } - daemon::Daemon::new(|daemon| inner(daemon, framebuffers)); -} -fn inner(daemon: daemon::Daemon, framebuffers: Vec) -> ! { let mut inputd_display_handle = DisplayHandle::new_early("vesa").unwrap(); let mut scheme = GraphicsScheme::new(FbAdapter { framebuffers }, "display.vesa".to_owned()); diff --git a/drivers/graphics/virtio-gpud/src/main.rs b/drivers/graphics/virtio-gpud/src/main.rs index fcd0142201..bcd170d905 100644 --- a/drivers/graphics/virtio-gpud/src/main.rs +++ b/drivers/graphics/virtio-gpud/src/main.rs @@ -544,11 +544,6 @@ fn deamon(deamon: daemon::Daemon) -> anyhow::Result<()> { } fn daemon_runner(daemon: daemon::Daemon) -> ! { - deamon(daemon).unwrap(); - unreachable!(); -} - -pub fn main() { common::setup_logging( "graphics", "pci", @@ -556,5 +551,10 @@ pub fn main() { common::output_level(), common::file_level(), ); + deamon(daemon).unwrap(); + unreachable!(); +} + +pub fn main() { daemon::Daemon::new(daemon_runner); } diff --git a/drivers/net/alxd/src/main.rs b/drivers/net/alxd/src/main.rs index 2a481f77ad..6c63136eff 100644 --- a/drivers/net/alxd/src/main.rs +++ b/drivers/net/alxd/src/main.rs @@ -19,6 +19,10 @@ use std::cell::RefCell; pub mod device; fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let mut args = env::args().skip(1); let mut name = args.next().expect("alxd: no name provided"); @@ -32,106 +36,102 @@ fn main() { println!(" + ALX {} on: {:X}, IRQ: {}\n", name, bar, irq); - // Daemonize - daemon::Daemon::new(move |daemon| { - let socket = Socket::nonblock("network").expect("alxd: failed to create socket"); - let mut readiness_based = ReadinessBased::new(&socket, 16); + let socket = Socket::nonblock("network").expect("alxd: failed to create socket"); + let mut readiness_based = ReadinessBased::new(&socket, 16); - daemon.ready(); + daemon.ready(); - let mut irq_file = - File::open(format!("/scheme/irq/{}", irq)).expect("alxd: failed to open IRQ file"); + let mut irq_file = + File::open(format!("/scheme/irq/{}", irq)).expect("alxd: failed to open IRQ file"); - let address = unsafe { - common::physmap( - bar, - 128 * 1024, - common::Prot::RW, - common::MemoryType::Uncacheable, - ) - .expect("alxd: failed to map address") as usize - }; - { - let device = RefCell::new(unsafe { - device::Alx::new(address).expect("alxd: failed to allocate device") - }); + let address = unsafe { + common::physmap( + bar, + 128 * 1024, + common::Prot::RW, + common::MemoryType::Uncacheable, + ) + .expect("alxd: failed to map address") as usize + }; + { + let device = RefCell::new(unsafe { + device::Alx::new(address).expect("alxd: failed to allocate device") + }); - user_data! { - enum Source { - Irq, - Scheme, - } + user_data! { + enum Source { + Irq, + Scheme, } + } - let event_queue = - EventQueue::::new().expect("alxd: failed to create event queue"); - event_queue - .subscribe( - irq_file.as_raw_fd() as usize, - Source::Irq, - event::EventFlags::READ, - ) - .unwrap(); - event_queue - .subscribe( - socket.inner().raw(), - Source::Scheme, - event::EventFlags::READ, - ) - .unwrap(); + let event_queue = EventQueue::::new().expect("alxd: failed to create event queue"); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); + event_queue + .subscribe( + socket.inner().raw(), + Source::Scheme, + event::EventFlags::READ, + ) + .unwrap(); - libredox::call::setrens(0, 0).expect("alxd: failed to enter null namespace"); + libredox::call::setrens(0, 0).expect("alxd: failed to enter null namespace"); - for event in iter::once(Source::Scheme) - .chain(event_queue.map(|e| e.expect("alxd: failed to get next event").user_data)) - { - match event { - Source::Irq => { - let mut irq = [0; 8]; - irq_file.read(&mut irq).unwrap(); - if !unsafe { device.borrow_mut().intr_legacy() } { - continue; - } - irq_file.write(&mut irq).unwrap(); + for event in iter::once(Source::Scheme) + .chain(event_queue.map(|e| e.expect("alxd: failed to get next event").user_data)) + { + match event { + Source::Irq => { + let mut irq = [0; 8]; + irq_file.read(&mut irq).unwrap(); + if !unsafe { device.borrow_mut().intr_legacy() } { + continue; + } + irq_file.write(&mut irq).unwrap(); - readiness_based - .poll_all_requests(|| device.borrow_mut()) - .expect("ihdad: failed to poll requests"); + readiness_based + .poll_all_requests(|| device.borrow_mut()) + .expect("ihdad: failed to poll requests"); - /* TODO: Currently a no-op - let next_read = device.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + /* TODO: Currently a no-op + let next_read = device.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); + } + */ + } + + Source::Scheme => { + if !readiness_based + .read_requests() + .expect("alxd: failed to read from socket") + { + break; + } + readiness_based.process_requests(|| device.borrow_mut()); + if !readiness_based + .write_responses() + .expect("alxd: failed to write to socket") + { + break; } - Source::Scheme => { - if !readiness_based - .read_requests() - .expect("alxd: failed to read from socket") - { - break; - } - readiness_based.process_requests(|| device.borrow_mut()); - if !readiness_based - .write_responses() - .expect("alxd: failed to write to socket") - { - break; - } - - // TODO - /* - let next_read = device.next_read(); - if next_read > 0 { - return Ok(Some(next_read)); - } - */ + // TODO + /* + let next_read = device.next_read(); + if next_read > 0 { + return Ok(Some(next_read)); } + */ } } } - std::process::exit(0); - }); + } + std::process::exit(0); } diff --git a/drivers/net/e1000d/src/main.rs b/drivers/net/e1000d/src/main.rs index 2824d8716b..81e5bd77da 100644 --- a/drivers/net/e1000d/src/main.rs +++ b/drivers/net/e1000d/src/main.rs @@ -8,6 +8,10 @@ use pcid_interface::PciFunctionHandle; pub mod device; fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let mut pcid_handle = PciFunctionHandle::connect_default(); let pci_config = pcid_handle.config(); @@ -29,62 +33,59 @@ fn main() { log::info!("E1000 {}", pci_config.func.display()); - daemon::Daemon::new(move |daemon| { - let mut irq_file = irq.irq_handle("e1000d"); + let mut irq_file = irq.irq_handle("e1000d"); - let address = unsafe { pcid_handle.map_bar(0) }.ptr.as_ptr() as usize; + let address = unsafe { pcid_handle.map_bar(0) }.ptr.as_ptr() as usize; - let mut scheme = NetworkScheme::new( - move || unsafe { - device::Intel8254x::new(address).expect("e1000d: failed to allocate device") - }, - daemon, - format!("network.{name}"), - ); + let mut scheme = NetworkScheme::new( + move || unsafe { + device::Intel8254x::new(address).expect("e1000d: failed to allocate device") + }, + daemon, + format!("network.{name}"), + ); - user_data! { - enum Source { - Irq, - Scheme, - } + user_data! { + enum Source { + Irq, + Scheme, } + } - let event_queue = - EventQueue::::new().expect("e1000d: failed to create event queue"); + let event_queue = EventQueue::::new().expect("e1000d: failed to create event queue"); - event_queue - .subscribe( - irq_file.as_raw_fd() as usize, - Source::Irq, - event::EventFlags::READ, - ) - .expect("e1000d: failed to subscribe to IRQ fd"); - event_queue - .subscribe( - scheme.event_handle().raw(), - Source::Scheme, - event::EventFlags::READ, - ) - .expect("e1000d: failed to subscribe to scheme fd"); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .expect("e1000d: failed to subscribe to IRQ fd"); + event_queue + .subscribe( + scheme.event_handle().raw(), + Source::Scheme, + event::EventFlags::READ, + ) + .expect("e1000d: failed to subscribe to scheme fd"); - libredox::call::setrens(0, 0).expect("e1000d: failed to enter null namespace"); + libredox::call::setrens(0, 0).expect("e1000d: failed to enter null namespace"); - scheme.tick().unwrap(); + scheme.tick().unwrap(); - for event in event_queue.map(|e| e.expect("e1000d: failed to get event")) { - match event.user_data { - Source::Irq => { - let mut irq = [0; 8]; - irq_file.read(&mut irq).unwrap(); - if unsafe { scheme.adapter().irq() } { - irq_file.write(&mut irq).unwrap(); + for event in event_queue.map(|e| e.expect("e1000d: failed to get event")) { + match event.user_data { + Source::Irq => { + let mut irq = [0; 8]; + irq_file.read(&mut irq).unwrap(); + if unsafe { scheme.adapter().irq() } { + irq_file.write(&mut irq).unwrap(); - scheme.tick().expect("e1000d: failed to handle IRQ") - } + scheme.tick().expect("e1000d: failed to handle IRQ") } - Source::Scheme => scheme.tick().expect("e1000d: failed to handle scheme op"), } + Source::Scheme => scheme.tick().expect("e1000d: failed to handle scheme op"), } - unreachable!() - }); + } + unreachable!() } diff --git a/drivers/net/ixgbed/src/main.rs b/drivers/net/ixgbed/src/main.rs index a0431ec920..f3ded2abd0 100644 --- a/drivers/net/ixgbed/src/main.rs +++ b/drivers/net/ixgbed/src/main.rs @@ -10,6 +10,10 @@ pub mod device; mod ixgbe; fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let mut pcid_handle = PciFunctionHandle::connect_default(); let pci_config = pcid_handle.config(); @@ -23,66 +27,63 @@ fn main() { println!(" + IXGBE {}", pci_config.func.display()); - daemon::Daemon::new(move |daemon| { - let mut irq_file = irq.irq_handle("ixgbed"); + let mut irq_file = irq.irq_handle("ixgbed"); - let mapped_bar = unsafe { pcid_handle.map_bar(0) }; - let address = mapped_bar.ptr.as_ptr(); - let size = mapped_bar.bar_size; + let mapped_bar = unsafe { pcid_handle.map_bar(0) }; + let address = mapped_bar.ptr.as_ptr(); + let size = mapped_bar.bar_size; - let mut scheme = NetworkScheme::new( - move || { - device::Intel8259x::new(address as usize, size) - .expect("ixgbed: failed to allocate device") - }, - daemon, - format!("network.{name}"), - ); + let mut scheme = NetworkScheme::new( + move || { + device::Intel8259x::new(address as usize, size) + .expect("ixgbed: failed to allocate device") + }, + daemon, + format!("network.{name}"), + ); - user_data! { - enum Source { - Irq, - Scheme, - } + user_data! { + enum Source { + Irq, + Scheme, } + } - let event_queue = - EventQueue::::new().expect("ixgbed: Could not create event queue."); - event_queue - .subscribe( - irq_file.as_raw_fd() as usize, - Source::Irq, - event::EventFlags::READ, - ) - .unwrap(); - event_queue - .subscribe( - scheme.event_handle().raw(), - Source::Scheme, - event::EventFlags::READ, - ) - .unwrap(); + let event_queue = EventQueue::::new().expect("ixgbed: Could not create event queue."); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); + event_queue + .subscribe( + scheme.event_handle().raw(), + Source::Scheme, + event::EventFlags::READ, + ) + .unwrap(); - libredox::call::setrens(0, 0).expect("ixgbed: failed to enter null namespace"); + libredox::call::setrens(0, 0).expect("ixgbed: failed to enter null namespace"); - scheme.tick().unwrap(); + scheme.tick().unwrap(); - for event in event_queue.map(|e| e.expect("ixgbed: failed to get next event")) { - match event.user_data { - Source::Irq => { - let mut irq = [0; 8]; - irq_file.read(&mut irq).unwrap(); - if scheme.adapter().irq() { - irq_file.write(&mut irq).unwrap(); + for event in event_queue.map(|e| e.expect("ixgbed: failed to get next event")) { + match event.user_data { + Source::Irq => { + let mut irq = [0; 8]; + irq_file.read(&mut irq).unwrap(); + if scheme.adapter().irq() { + irq_file.write(&mut irq).unwrap(); - scheme.tick().unwrap(); - } - } - Source::Scheme => { scheme.tick().unwrap(); } } + Source::Scheme => { + scheme.tick().unwrap(); + } } - unreachable!() - }); + } + unreachable!() } diff --git a/drivers/net/virtio-netd/src/main.rs b/drivers/net/virtio-netd/src/main.rs index 4b1fa76d70..04c943d6ba 100644 --- a/drivers/net/virtio-netd/src/main.rs +++ b/drivers/net/virtio-netd/src/main.rs @@ -120,11 +120,6 @@ fn deamon(daemon: daemon::Daemon) -> Result<(), Box> { } fn daemon_runner(daemon: daemon::Daemon) -> ! { - deamon(daemon).unwrap(); - unreachable!(); -} - -pub fn main() { common::setup_logging( "net", "pci", @@ -132,5 +127,10 @@ pub fn main() { common::output_level(), common::file_level(), ); + deamon(daemon).unwrap(); + unreachable!(); +} + +pub fn main() { daemon::Daemon::new(daemon_runner); } diff --git a/drivers/pcid/src/main.rs b/drivers/pcid/src/main.rs index f1d0b471ef..40a68815f2 100644 --- a/drivers/pcid/src/main.rs +++ b/drivers/pcid/src/main.rs @@ -187,6 +187,10 @@ fn enable_function( } fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let mut args = pico_args::Arguments::from_env(); let verbosity = (0..).find(|_| !args.contains("-v")).unwrap_or(0); let log_level = match verbosity { @@ -197,10 +201,6 @@ fn main() { common::setup_logging("bus", "pci", "pcid", log_level, log::LevelFilter::Info); - daemon::Daemon::new(move |daemon| main_inner(daemon)); -} - -fn main_inner(daemon: daemon::Daemon) -> ! { let pcie = Pcie::new(); let mut tree = BTreeMap::new(); diff --git a/drivers/storage/lived/src/main.rs b/drivers/storage/lived/src/main.rs index 1ba08e2a16..2ca1ff27e5 100644 --- a/drivers/storage/lived/src/main.rs +++ b/drivers/storage/lived/src/main.rs @@ -103,13 +103,18 @@ impl Disk for LiveDisk { } } -fn main() -> anyhow::Result<()> { +fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let mut phys = 0; let mut size = 0; // TODO: handle error for line in std::fs::read_to_string("/scheme/sys/env") - .context("failed to read env")? + .context("failed to read env") + .unwrap() .lines() { let mut parts = line.splitn(2, '='); @@ -126,48 +131,47 @@ fn main() -> anyhow::Result<()> { } if phys == 0 || size == 0 { - // No live disk data, no need to say anything or exit with error + // No live disk data, no need to say anything or exit with + daemon.ready(); std::process::exit(0); } - daemon::Daemon::new(move |daemon| { - let event_queue = event::EventQueue::new().unwrap(); + let event_queue = event::EventQueue::new().unwrap(); - event::user_data! { - enum Event { - Scheme, - } - }; - - let mut scheme = DiskScheme::new( - Some(daemon), - "disk.live".to_owned(), - BTreeMap::from([( - 0, - LiveDisk::new(phys, size).unwrap_or_else(|err| { - eprintln!("failed to initialize livedisk scheme: {}", err); - std::process::exit(1) - }), - )]), - &TrivialExecutor, - ); - - libredox::call::setrens(0, 0).expect("nvmed: failed to enter null namespace"); - - event_queue - .subscribe( - scheme.event_handle().raw(), - Event::Scheme, - event::EventFlags::READ, - ) - .unwrap(); - - for event in event_queue { - match event.unwrap().user_data { - Event::Scheme => TrivialExecutor.block_on(scheme.tick()).unwrap(), - } + event::user_data! { + enum Event { + Scheme, } + }; - std::process::exit(0); - }); + let mut scheme = DiskScheme::new( + Some(daemon), + "disk.live".to_owned(), + BTreeMap::from([( + 0, + LiveDisk::new(phys, size).unwrap_or_else(|err| { + eprintln!("failed to initialize livedisk scheme: {}", err); + std::process::exit(1) + }), + )]), + &TrivialExecutor, + ); + + libredox::call::setrens(0, 0).expect("nvmed: failed to enter null namespace"); + + event_queue + .subscribe( + scheme.event_handle().raw(), + Event::Scheme, + event::EventFlags::READ, + ) + .unwrap(); + + for event in event_queue { + match event.unwrap().user_data { + Event::Scheme => TrivialExecutor.block_on(scheme.tick()).unwrap(), + } + } + + std::process::exit(0); } diff --git a/drivers/storage/usbscsid/src/main.rs b/drivers/storage/usbscsid/src/main.rs index 118f915ca2..c438c8781f 100644 --- a/drivers/storage/usbscsid/src/main.rs +++ b/drivers/storage/usbscsid/src/main.rs @@ -12,6 +12,9 @@ use crate::protocol::Protocol; use crate::scsi::Scsi; fn main() { + daemon::Daemon::new(daemon); +} +fn daemon(daemon: daemon::Daemon) -> ! { let mut args = env::args().skip(1); const USAGE: &'static str = "usbscsid "; @@ -33,9 +36,6 @@ fn main() { scheme, port, protocol ); - daemon::Daemon::new(move |d| daemon(d, scheme, port, protocol)); -} -fn daemon(daemon: daemon::Daemon, scheme: String, port: PortId, protocol: u8) -> ! { let disk_scheme_name = format!("disk.usb-{scheme}+{port}-scsi"); // TODO: Use eventfds. diff --git a/drivers/storage/virtio-blkd/src/main.rs b/drivers/storage/virtio-blkd/src/main.rs index 414b67d713..4f47c6ecd6 100644 --- a/drivers/storage/virtio-blkd/src/main.rs +++ b/drivers/storage/virtio-blkd/src/main.rs @@ -31,13 +31,6 @@ pub enum Error { } pub fn main() { - common::setup_logging( - "disk", - "pci", - "virtio-blkd", - common::output_level(), - common::file_level(), - ); daemon::Daemon::new(daemon_runner); } @@ -178,6 +171,13 @@ fn daemon(daemon: daemon::Daemon) -> anyhow::Result<()> { } fn daemon_runner(redox_daemon: daemon::Daemon) -> ! { + common::setup_logging( + "disk", + "pci", + "virtio-blkd", + common::output_level(), + common::file_level(), + ); daemon(redox_daemon).unwrap(); unreachable!(); } diff --git a/drivers/vboxd/src/main.rs b/drivers/vboxd/src/main.rs index 59715708ca..341bdcc130 100644 --- a/drivers/vboxd/src/main.rs +++ b/drivers/vboxd/src/main.rs @@ -191,6 +191,10 @@ impl VboxGuestInfo { } fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let mut pcid_handle = PciFunctionHandle::connect_default(); let pci_config = pcid_handle.config(); @@ -206,129 +210,124 @@ fn main() { println!(" + VirtualBox {}", pci_config.func.display()); - // Daemonize - daemon::Daemon::new(move |daemon| { - common::acquire_port_io_rights().expect("vboxd: failed to get I/O permission"); + common::acquire_port_io_rights().expect("vboxd: failed to get I/O permission"); - let mut width = 0; - let mut height = 0; - let mut display_opt = File::open("inputd:producer").ok(); - if let Some(ref display) = display_opt { - let mut buf: [u8; 4096] = [0; 4096]; - if let Ok(count) = libredox::call::fpath(display.as_raw_fd() as usize, &mut buf) { - let path = unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) }; - let res = path.split(":").nth(1).unwrap_or(""); - width = res - .split("/") - .nth(1) - .unwrap_or("") - .parse::() - .unwrap_or(0); - height = res - .split("/") - .nth(2) - .unwrap_or("") - .parse::() - .unwrap_or(0); + let mut width = 0; + let mut height = 0; + let mut display_opt = File::open("inputd:producer").ok(); + if let Some(ref display) = display_opt { + let mut buf: [u8; 4096] = [0; 4096]; + if let Ok(count) = libredox::call::fpath(display.as_raw_fd() as usize, &mut buf) { + let path = unsafe { String::from_utf8_unchecked(Vec::from(&buf[..count])) }; + let res = path.split(":").nth(1).unwrap_or(""); + width = res + .split("/") + .nth(1) + .unwrap_or("") + .parse::() + .unwrap_or(0); + height = res + .split("/") + .nth(2) + .unwrap_or("") + .parse::() + .unwrap_or(0); + } + } + + let mut irq_file = irq.irq_handle("vboxd"); + + let mut port = Pio::::new(bar0 as u16); + let address = unsafe { pcid_handle.map_bar(1) }.ptr.as_ptr(); + { + let vmmdev = unsafe { &mut *(address as *mut VboxVmmDev) }; + + let mut guest_info = VboxGuestInfo::new().expect("vboxd: failed to map GuestInfo"); + guest_info.version.write(VBOX_VMMDEV_VERSION); + guest_info.ostype.write(0x100); + port.write(guest_info.physical() as u32); + + let mut guest_caps = VboxGuestCaps::new().expect("vboxd: failed to map GuestCaps"); + guest_caps.caps.write(1 << 2); + port.write(guest_caps.physical() as u32); + + let mut set_mouse = VboxSetMouse::new().expect("vboxd: failed to map SetMouse"); + set_mouse.features.write(1 << 4 | 1); + port.write(set_mouse.physical() as u32); + + vmmdev + .guest_events + .write(VBOX_EVENT_DISPLAY | VBOX_EVENT_MOUSE); + + user_data! { + enum Source { + Irq, } } - let mut irq_file = irq.irq_handle("vboxd"); + let event_queue = + EventQueue::::new().expect("vboxd: Could not create event queue."); + event_queue + .subscribe( + irq_file.as_raw_fd() as usize, + Source::Irq, + event::EventFlags::READ, + ) + .unwrap(); - let mut port = Pio::::new(bar0 as u16); - let address = unsafe { pcid_handle.map_bar(1) }.ptr.as_ptr(); + daemon.ready(); + + libredox::call::setrens(0, 0).expect("vboxd: failed to enter null namespace"); + + let mut bga = Bga::new(); + let get_mouse = VboxGetMouse::new().expect("vboxd: failed to map GetMouse"); + let display_change = VboxDisplayChange::new().expect("vboxd: failed to map DisplayChange"); + let ack_events = VboxAckEvents::new().expect("vboxd: failed to map AckEvents"); + + for Source::Irq in iter::once(Source::Irq) + .chain(event_queue.map(|e| e.expect("vboxd: failed to get next event").user_data)) { - let vmmdev = unsafe { &mut *(address as *mut VboxVmmDev) }; + let mut irq = [0; 8]; + if irq_file.read(&mut irq).unwrap() >= irq.len() { + let host_events = vmmdev.host_events.read(); + if host_events != 0 { + port.write(ack_events.physical() as u32); + irq_file.write(&irq).unwrap(); - let mut guest_info = VboxGuestInfo::new().expect("vboxd: failed to map GuestInfo"); - guest_info.version.write(VBOX_VMMDEV_VERSION); - guest_info.ostype.write(0x100); - port.write(guest_info.physical() as u32); - - let mut guest_caps = VboxGuestCaps::new().expect("vboxd: failed to map GuestCaps"); - guest_caps.caps.write(1 << 2); - port.write(guest_caps.physical() as u32); - - let mut set_mouse = VboxSetMouse::new().expect("vboxd: failed to map SetMouse"); - set_mouse.features.write(1 << 4 | 1); - port.write(set_mouse.physical() as u32); - - vmmdev - .guest_events - .write(VBOX_EVENT_DISPLAY | VBOX_EVENT_MOUSE); - - user_data! { - enum Source { - Irq, - } - } - - let event_queue = - EventQueue::::new().expect("vboxd: Could not create event queue."); - event_queue - .subscribe( - irq_file.as_raw_fd() as usize, - Source::Irq, - event::EventFlags::READ, - ) - .unwrap(); - - daemon.ready(); - - libredox::call::setrens(0, 0).expect("vboxd: failed to enter null namespace"); - - let mut bga = Bga::new(); - let get_mouse = VboxGetMouse::new().expect("vboxd: failed to map GetMouse"); - let display_change = - VboxDisplayChange::new().expect("vboxd: failed to map DisplayChange"); - let ack_events = VboxAckEvents::new().expect("vboxd: failed to map AckEvents"); - - for Source::Irq in iter::once(Source::Irq) - .chain(event_queue.map(|e| e.expect("vboxd: failed to get next event").user_data)) - { - let mut irq = [0; 8]; - if irq_file.read(&mut irq).unwrap() >= irq.len() { - let host_events = vmmdev.host_events.read(); - if host_events != 0 { - port.write(ack_events.physical() as u32); - irq_file.write(&irq).unwrap(); - - if host_events & VBOX_EVENT_DISPLAY == VBOX_EVENT_DISPLAY { - port.write(display_change.physical() as u32); - if let Some(ref mut display) = display_opt { - let new_width = display_change.xres.read(); - let new_height = display_change.yres.read(); - if width != new_width || height != new_height { - width = new_width; - height = new_height; - println!("Display {}, {}", width, height); - bga.set_size(width as u16, height as u16); - let _ = display.write( - &orbclient::ResizeEvent { width, height }.to_event(), - ); - } + if host_events & VBOX_EVENT_DISPLAY == VBOX_EVENT_DISPLAY { + port.write(display_change.physical() as u32); + if let Some(ref mut display) = display_opt { + let new_width = display_change.xres.read(); + let new_height = display_change.yres.read(); + if width != new_width || height != new_height { + width = new_width; + height = new_height; + println!("Display {}, {}", width, height); + bga.set_size(width as u16, height as u16); + let _ = display + .write(&orbclient::ResizeEvent { width, height }.to_event()); } } + } - if host_events & VBOX_EVENT_MOUSE == VBOX_EVENT_MOUSE { - port.write(get_mouse.physical() as u32); - if let Some(ref mut display) = display_opt { - let x = get_mouse.x.read() * width / 0x10000; - let y = get_mouse.y.read() * height / 0x10000; - let _ = display.write( - &orbclient::MouseEvent { - x: x as i32, - y: y as i32, - } - .to_event(), - ); - } + if host_events & VBOX_EVENT_MOUSE == VBOX_EVENT_MOUSE { + port.write(get_mouse.physical() as u32); + if let Some(ref mut display) = display_opt { + let x = get_mouse.x.read() * width / 0x10000; + let y = get_mouse.y.read() * height / 0x10000; + let _ = display.write( + &orbclient::MouseEvent { + x: x as i32, + y: y as i32, + } + .to_event(), + ); } } } } } + } - std::process::exit(0); - }); + std::process::exit(0); } diff --git a/ipcd/src/main.rs b/ipcd/src/main.rs index 91d67ab68d..76797de798 100644 --- a/ipcd/src/main.rs +++ b/ipcd/src/main.rs @@ -14,16 +14,18 @@ use self::uds::dgram::UdsDgramScheme; use self::uds::stream::UdsStreamScheme; fn main() { - daemon::Daemon::new(move |daemon| { - // TODO: Better error handling - match inner(daemon) { - Ok(()) => std::process::exit(0), - Err(error) => { - println!("ipcd failed: {error}"); - std::process::exit(1); - } + daemon::Daemon::new(daemon_runner); +} + +fn daemon_runner(daemon: daemon::Daemon) -> ! { + // TODO: Better error handling + match inner(daemon) { + Ok(()) => std::process::exit(0), + Err(error) => { + println!("ipcd failed: {error}"); + std::process::exit(1); } - }); + } } fn inner(daemon: daemon::Daemon) -> anyhow::Result<()> { diff --git a/netstack/src/main.rs b/netstack/src/main.rs index 186f8d3f02..cf77bd430f 100644 --- a/netstack/src/main.rs +++ b/netstack/src/main.rs @@ -164,13 +164,15 @@ fn run(daemon: daemon::Daemon) -> Result<()> { } fn main() { - daemon::Daemon::new(move |daemon| { - logger::init_logger("smolnetd"); - - if let Err(err) = run(daemon) { - error!("smoltcpd: {}", err); - process::exit(1); - } - process::exit(0); - }); + daemon::Daemon::new(daemon_runner); +} + +fn daemon_runner(daemon: daemon::Daemon) -> ! { + logger::init_logger("smolnetd"); + + if let Err(err) = run(daemon) { + error!("smoltcpd: {}", err); + process::exit(1); + } + process::exit(0); } diff --git a/ptyd/src/main.rs b/ptyd/src/main.rs index 8e38a2de01..335f2ff856 100644 --- a/ptyd/src/main.rs +++ b/ptyd/src/main.rs @@ -19,71 +19,72 @@ mod winsize; use scheme::PtyScheme; fn main() { - daemon::Daemon::new(move |daemon| { - user_data! { - enum EventSource { - Socket, - Time, + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { + user_data! { + enum EventSource { + Socket, + Time, + } + } + + let event_queue = EventQueue::::new().expect("pty: failed to open event:"); + + let time_path = format!("/scheme/time/{}", flag::CLOCK_MONOTONIC); + let mut time_file = + Fd::open(&time_path, flag::O_NONBLOCK, 0).expect("pty: failed to open time:"); + + let socket = redox_scheme::Socket::nonblock("pty").expect("pty: failed to create pty scheme"); + + libredox::call::setrens(0, 0).expect("ptyd: failed to enter null namespace"); + + event_queue + .subscribe(socket.inner().raw(), EventSource::Socket, EventFlags::READ) + .expect("pty: failed to watch events on pty:"); + event_queue + .subscribe(time_file.raw(), EventSource::Time, EventFlags::READ) + .expect("pty: failed to watch events on time:"); + + daemon.ready(); + + //TODO: do not set timeout if not necessary + timeout(&mut time_file).expect("pty: failed to set timeout"); + + let mut scheme = PtyScheme::new(); + let mut todo = Vec::new(); + let mut timeout_count = 0u64; + + scan_requests(&socket, &mut scheme, &mut todo).expect("pty: could not scan requests"); + do_todos(&socket, &mut scheme, &mut todo); + issue_events(&socket, &mut scheme); + + for event_res in event_queue { + let event = event_res.expect("pty: failed to read from event queue"); + + match event.user_data { + EventSource::Socket => { + if scan_requests(&socket, &mut scheme, &mut todo).is_err() { + break; + } + } + EventSource::Time => { + timeout(&mut time_file).expect("pty: failed to set timeout"); + + timeout_count = timeout_count.wrapping_add(1); + + for (_id, handle) in scheme.handles.iter_mut() { + handle.timeout(timeout_count); + } } } - let event_queue = EventQueue::::new().expect("pty: failed to open event:"); - - let time_path = format!("/scheme/time/{}", flag::CLOCK_MONOTONIC); - let mut time_file = - Fd::open(&time_path, flag::O_NONBLOCK, 0).expect("pty: failed to open time:"); - - let socket = - redox_scheme::Socket::nonblock("pty").expect("pty: failed to create pty scheme"); - - libredox::call::setrens(0, 0).expect("ptyd: failed to enter null namespace"); - - event_queue - .subscribe(socket.inner().raw(), EventSource::Socket, EventFlags::READ) - .expect("pty: failed to watch events on pty:"); - event_queue - .subscribe(time_file.raw(), EventSource::Time, EventFlags::READ) - .expect("pty: failed to watch events on time:"); - - daemon.ready(); - - //TODO: do not set timeout if not necessary - timeout(&mut time_file).expect("pty: failed to set timeout"); - - let mut scheme = PtyScheme::new(); - let mut todo = Vec::new(); - let mut timeout_count = 0u64; - - scan_requests(&socket, &mut scheme, &mut todo).expect("pty: could not scan requests"); do_todos(&socket, &mut scheme, &mut todo); issue_events(&socket, &mut scheme); + } - for event_res in event_queue { - let event = event_res.expect("pty: failed to read from event queue"); - - match event.user_data { - EventSource::Socket => { - if scan_requests(&socket, &mut scheme, &mut todo).is_err() { - break; - } - } - EventSource::Time => { - timeout(&mut time_file).expect("pty: failed to set timeout"); - - timeout_count = timeout_count.wrapping_add(1); - - for (_id, handle) in scheme.handles.iter_mut() { - handle.timeout(timeout_count); - } - } - } - - do_todos(&socket, &mut scheme, &mut todo); - issue_events(&socket, &mut scheme); - } - - std::process::exit(0); - }); + std::process::exit(0); } struct Todo { diff --git a/ramfs/src/main.rs b/ramfs/src/main.rs index ccd2c61f91..45fb3bcd36 100644 --- a/ramfs/src/main.rs +++ b/ramfs/src/main.rs @@ -8,40 +8,42 @@ use redox_scheme::{RequestKind, SignalBehavior}; use self::scheme::Scheme; fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let scheme_name = env::args().nth(1).expect("Usage:\n\tramfs SCHEME_NAME"); - daemon::Daemon::new(move |daemon| { - let socket = - redox_scheme::Socket::create(&scheme_name).expect("ramfs: failed to create socket"); + let socket = + redox_scheme::Socket::create(&scheme_name).expect("ramfs: failed to create socket"); - let mut scheme = Scheme::new(scheme_name).expect("ramfs: failed to initialize scheme"); + let mut scheme = Scheme::new(scheme_name).expect("ramfs: failed to initialize scheme"); - libredox::call::setrens(0, 0).expect("ramfs: failed to enter null namespace"); + libredox::call::setrens(0, 0).expect("ramfs: failed to enter null namespace"); - daemon.ready(); + daemon.ready(); - loop { - let Some(request) = socket - .next_request(SignalBehavior::Restart) - .expect("ramfs: failed to get next scheme request") - else { - break; - }; - match request.kind() { - RequestKind::Call(call) => { - let response = call.handle_sync(&mut scheme); + loop { + let Some(request) = socket + .next_request(SignalBehavior::Restart) + .expect("ramfs: failed to get next scheme request") + else { + break; + }; + match request.kind() { + RequestKind::Call(call) => { + let response = call.handle_sync(&mut scheme); - socket - .write_responses(&[response], SignalBehavior::Restart) - .expect("ramfs: failed to write next scheme response"); - } - RequestKind::OnClose { id } => { - scheme.on_close(id); - } - _ => (), + socket + .write_responses(&[response], SignalBehavior::Restart) + .expect("ramfs: failed to write next scheme response"); } + RequestKind::OnClose { id } => { + scheme.on_close(id); + } + _ => (), } + } - process::exit(0); - }); + process::exit(0); } diff --git a/zerod/src/main.rs b/zerod/src/main.rs index c500775e31..f34ec93bc3 100644 --- a/zerod/src/main.rs +++ b/zerod/src/main.rs @@ -10,41 +10,43 @@ enum Ty { } fn main() { + daemon::Daemon::new(daemon); +} + +fn daemon(daemon: daemon::Daemon) -> ! { let ty = match &*std::env::args().next().unwrap() { "nulld" => Ty::Null, "zerod" => Ty::Zero, _ => panic!("needs to be called as either nulld or zerod"), }; - daemon::Daemon::new(move |daemon| { - let name = match ty { - Ty::Null => "null", - Ty::Zero => "zero", + let name = match ty { + Ty::Null => "null", + Ty::Zero => "zero", + }; + let socket = Socket::::create(name).expect("zerod: failed to create zero scheme"); + let mut zero_scheme = ZeroScheme(ty); + + libredox::call::setrens(0, 0).expect("zerod: failed to enter null namespace"); + + daemon.ready(); + + loop { + let Some(request) = socket + .next_request(SignalBehavior::Restart) + .expect("zerod: failed to read events from zero scheme") + else { + std::process::exit(0); }; - let socket = Socket::::create(name).expect("zerod: failed to create zero scheme"); - let mut zero_scheme = ZeroScheme(ty); + match request.kind() { + RequestKind::Call(request) => { + let response = request.handle_scheme_mut(&mut zero_scheme); - libredox::call::setrens(0, 0).expect("zerod: failed to enter null namespace"); - - daemon.ready(); - - loop { - let Some(request) = socket - .next_request(SignalBehavior::Restart) - .expect("zerod: failed to read events from zero scheme") - else { - std::process::exit(0); - }; - match request.kind() { - RequestKind::Call(request) => { - let response = request.handle_scheme_mut(&mut zero_scheme); - - socket - .write_responses(&[response], SignalBehavior::Restart) - .expect("zerod: failed to write responses to zero scheme"); - } - _ => (), + socket + .write_responses(&[response], SignalBehavior::Restart) + .expect("zerod: failed to write responses to zero scheme"); } + _ => (), } - }); + } } From 3abe41d258402111a0aff89a950da1e2e8c4192e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 3 Dec 2025 22:40:52 +0100 Subject: [PATCH 2/7] drivers/pcid: Add pci_daemon function This handles daemonization and getting the PciFunctionHandle. --- drivers/audio/ac97d/src/main.rs | 5 ++-- drivers/audio/ihdad/src/main.rs | 10 +++---- drivers/graphics/bgad/src/main.rs | 5 ++-- drivers/graphics/virtio-gpud/src/main.rs | 35 +++++++++++----------- drivers/net/e1000d/src/main.rs | 5 ++-- drivers/net/ixgbed/src/main.rs | 5 ++-- drivers/net/rtl8139d/src/main.rs | 10 +++---- drivers/net/rtl8168d/src/main.rs | 10 +++---- drivers/net/virtio-netd/src/main.rs | 37 ++++++++++++------------ drivers/pcid/src/driver_interface/mod.rs | 10 ++++++- drivers/pcid/src/lib.rs | 2 ++ drivers/storage/ahcid/src/main.rs | 5 ++-- drivers/storage/ided/src/main.rs | 6 ++-- drivers/storage/nvmed/src/main.rs | 6 ++-- drivers/storage/virtio-blkd/src/main.rs | 35 +++++++++++----------- drivers/usb/xhcid/src/main.rs | 11 ++++--- drivers/vboxd/src/main.rs | 5 ++-- 17 files changed, 98 insertions(+), 104 deletions(-) diff --git a/drivers/audio/ac97d/src/main.rs b/drivers/audio/ac97d/src/main.rs index 1aa36ca774..9d9e785199 100644 --- a/drivers/audio/ac97d/src/main.rs +++ b/drivers/audio/ac97d/src/main.rs @@ -18,11 +18,10 @@ use std::cell::RefCell; pub mod device; fn main() { - daemon::Daemon::new(daemon); + pcid_interface::pci_daemon(daemon); } -fn daemon(daemon: daemon::Daemon) -> ! { - let pcid_handle = PciFunctionHandle::connect_default(); +fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); diff --git a/drivers/audio/ihdad/src/main.rs b/drivers/audio/ihdad/src/main.rs index 4bb4652fdb..7331a59197 100755 --- a/drivers/audio/ihdad/src/main.rs +++ b/drivers/audio/ihdad/src/main.rs @@ -23,9 +23,11 @@ QEMU ICH9 8086:293E 82801H ICH8 8086:284B */ -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn main() { + pcid_interface::pci_daemon(daemon); +} +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); @@ -138,7 +140,3 @@ fn daemon(daemon: daemon::Daemon) -> ! { std::process::exit(0); } } - -fn main() { - daemon::Daemon::new(daemon); -} diff --git a/drivers/graphics/bgad/src/main.rs b/drivers/graphics/bgad/src/main.rs index 7abb2beba0..2170d21b2d 100644 --- a/drivers/graphics/bgad/src/main.rs +++ b/drivers/graphics/bgad/src/main.rs @@ -13,11 +13,10 @@ mod scheme; // FIXME add a driver-graphics implementation fn main() { - daemon::Daemon::new(daemon); + pcid_interface::pci_daemon(daemon); } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); diff --git a/drivers/graphics/virtio-gpud/src/main.rs b/drivers/graphics/virtio-gpud/src/main.rs index bcd170d905..5852efaebb 100644 --- a/drivers/graphics/virtio-gpud/src/main.rs +++ b/drivers/graphics/virtio-gpud/src/main.rs @@ -430,8 +430,23 @@ impl MoveCursor { static DEVICE: spin::Once = spin::Once::new(); -fn deamon(deamon: daemon::Daemon) -> anyhow::Result<()> { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn main() { + pcid_interface::pci_daemon(daemon_runner); +} + +fn daemon_runner(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! { + deamon(daemon, pcid_handle).unwrap(); + unreachable!(); +} + +fn deamon(deamon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> anyhow::Result<()> { + common::setup_logging( + "graphics", + "pci", + "virtio-gpud", + common::output_level(), + common::file_level(), + ); // Double check that we have the right device. // @@ -542,19 +557,3 @@ fn deamon(deamon: daemon::Daemon) -> anyhow::Result<()> { std::process::exit(0); } - -fn daemon_runner(daemon: daemon::Daemon) -> ! { - common::setup_logging( - "graphics", - "pci", - "virtio-gpud", - common::output_level(), - common::file_level(), - ); - deamon(daemon).unwrap(); - unreachable!(); -} - -pub fn main() { - daemon::Daemon::new(daemon_runner); -} diff --git a/drivers/net/e1000d/src/main.rs b/drivers/net/e1000d/src/main.rs index 81e5bd77da..373ea9b38b 100644 --- a/drivers/net/e1000d/src/main.rs +++ b/drivers/net/e1000d/src/main.rs @@ -8,11 +8,10 @@ use pcid_interface::PciFunctionHandle; pub mod device; fn main() { - daemon::Daemon::new(daemon); + pcid_interface::pci_daemon(daemon); } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); diff --git a/drivers/net/ixgbed/src/main.rs b/drivers/net/ixgbed/src/main.rs index f3ded2abd0..4a6ce74dcd 100644 --- a/drivers/net/ixgbed/src/main.rs +++ b/drivers/net/ixgbed/src/main.rs @@ -10,11 +10,10 @@ pub mod device; mod ixgbe; fn main() { - daemon::Daemon::new(daemon); + pcid_interface::pci_daemon(daemon); } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); diff --git a/drivers/net/rtl8139d/src/main.rs b/drivers/net/rtl8139d/src/main.rs index df736ec565..d470e814df 100644 --- a/drivers/net/rtl8139d/src/main.rs +++ b/drivers/net/rtl8139d/src/main.rs @@ -35,9 +35,11 @@ fn map_bar(pcid_handle: &mut PciFunctionHandle) -> *mut u8 { panic!("rtl8139d: failed to find BAR"); } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn main() { + pcid_interface::pci_daemon(daemon); +} +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); @@ -111,7 +113,3 @@ fn daemon(daemon: daemon::Daemon) -> ! { } unreachable!() } - -fn main() { - daemon::Daemon::new(daemon); -} diff --git a/drivers/net/rtl8168d/src/main.rs b/drivers/net/rtl8168d/src/main.rs index 11742dd574..1d9963a3ad 100644 --- a/drivers/net/rtl8168d/src/main.rs +++ b/drivers/net/rtl8168d/src/main.rs @@ -35,9 +35,11 @@ fn map_bar(pcid_handle: &mut PciFunctionHandle) -> *mut u8 { panic!("rtl8168d: failed to find BAR"); } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn main() { + pcid_interface::pci_daemon(daemon); +} +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); @@ -111,7 +113,3 @@ fn daemon(daemon: daemon::Daemon) -> ! { } unreachable!() } - -fn main() { - daemon::Daemon::new(daemon); -} diff --git a/drivers/net/virtio-netd/src/main.rs b/drivers/net/virtio-netd/src/main.rs index 04c943d6ba..17d168efdf 100644 --- a/drivers/net/virtio-netd/src/main.rs +++ b/drivers/net/virtio-netd/src/main.rs @@ -26,9 +26,26 @@ pub struct VirtHeader { static_assertions::const_assert_eq!(core::mem::size_of::(), 12); const MAX_BUFFER_LEN: usize = 65535; +fn main() { + pcid_interface::pci_daemon(daemon_runner); +} -fn deamon(daemon: daemon::Daemon) -> Result<(), Box> { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn daemon_runner(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! { + deamon(daemon, pcid_handle).unwrap(); + unreachable!(); +} + +fn deamon( + daemon: daemon::Daemon, + mut pcid_handle: PciFunctionHandle, +) -> Result<(), Box> { + common::setup_logging( + "net", + "pci", + "virtio-netd", + common::output_level(), + common::file_level(), + ); // Double check that we have the right device. // @@ -118,19 +135,3 @@ fn deamon(daemon: daemon::Daemon) -> Result<(), Box> { scheme.tick()?; } } - -fn daemon_runner(daemon: daemon::Daemon) -> ! { - common::setup_logging( - "net", - "pci", - "virtio-netd", - common::output_level(), - common::file_level(), - ); - deamon(daemon).unwrap(); - unreachable!(); -} - -pub fn main() { - daemon::Daemon::new(daemon_runner); -} diff --git a/drivers/pcid/src/driver_interface/mod.rs b/drivers/pcid/src/driver_interface/mod.rs index d1fa8d733d..f7c93b51f8 100644 --- a/drivers/pcid/src/driver_interface/mod.rs +++ b/drivers/pcid/src/driver_interface/mod.rs @@ -6,6 +6,7 @@ use std::ptr::NonNull; use std::{env, io}; use std::{fmt, process}; +use daemon::Daemon; use serde::{de::DeserializeOwned, Deserialize, Serialize}; pub use bar::PciBar; @@ -297,7 +298,7 @@ fn recv(r: &mut File) -> T { } impl PciFunctionHandle { - pub fn connect_default() -> Self { + fn connect_default() -> Self { let channel_fd = match env::var("PCID_CLIENT_CHANNEL") { Ok(channel_fd) => channel_fd, Err(err) => { @@ -471,3 +472,10 @@ impl PciFunctionHandle { } } } + +pub fn pci_daemon !>(f: F) -> ! { + Daemon::new(|daemon| { + let pcid_handle = PciFunctionHandle::connect_default(); + f(daemon, pcid_handle) + }) +} diff --git a/drivers/pcid/src/lib.rs b/drivers/pcid/src/lib.rs index 312a886cf5..e8098a1786 100644 --- a/drivers/pcid/src/lib.rs +++ b/drivers/pcid/src/lib.rs @@ -1,4 +1,6 @@ //! Interface to `pcid`. +#![feature(never_type)] + mod driver_interface; pub use driver_interface::*; diff --git a/drivers/storage/ahcid/src/main.rs b/drivers/storage/ahcid/src/main.rs index 4b6a34523f..45415732bf 100644 --- a/drivers/storage/ahcid/src/main.rs +++ b/drivers/storage/ahcid/src/main.rs @@ -14,11 +14,10 @@ use log::{error, info}; pub mod ahci; fn main() { - daemon::Daemon::new(daemon); + pcid_interface::pci_daemon(daemon); } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); diff --git a/drivers/storage/ided/src/main.rs b/drivers/storage/ided/src/main.rs index a5c07e331d..e94998a713 100644 --- a/drivers/storage/ided/src/main.rs +++ b/drivers/storage/ided/src/main.rs @@ -18,12 +18,10 @@ use crate::ide::{AtaCommand, AtaDisk, Channel}; pub mod ide; fn main() { - daemon::Daemon::new(daemon); + pcid_interface::pci_daemon(daemon); } -fn daemon(daemon: daemon::Daemon) -> ! { - let pcid_handle = PciFunctionHandle::connect_default(); - +fn daemon(daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); diff --git a/drivers/storage/nvmed/src/main.rs b/drivers/storage/nvmed/src/main.rs index bdf4a8c08f..beb1b68940 100644 --- a/drivers/storage/nvmed/src/main.rs +++ b/drivers/storage/nvmed/src/main.rs @@ -57,10 +57,10 @@ fn time_arm(time_handle: &mut File, secs: i64) -> io::Result<()> { } fn main() { - daemon::Daemon::new(daemon); + pcid_interface::pci_daemon(daemon); } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); + +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let scheme_name = format!("disk.{}-nvme", pci_config.func.name()); diff --git a/drivers/storage/virtio-blkd/src/main.rs b/drivers/storage/virtio-blkd/src/main.rs index 4f47c6ecd6..d21236b377 100644 --- a/drivers/storage/virtio-blkd/src/main.rs +++ b/drivers/storage/virtio-blkd/src/main.rs @@ -30,10 +30,6 @@ pub enum Error { SyscallError(syscall::Error), } -pub fn main() { - daemon::Daemon::new(daemon_runner); -} - #[repr(C)] pub struct BlockGeometry { pub cylinders: VolatileCell, @@ -102,8 +98,23 @@ pub struct BlockVirtRequest { const_assert_eq!(core::mem::size_of::(), 16); -fn daemon(daemon: daemon::Daemon) -> anyhow::Result<()> { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn main() { + pcid_interface::pci_daemon(daemon_runner); +} + +fn daemon_runner(redox_daemon: daemon::Daemon, pcid_handle: PciFunctionHandle) -> ! { + daemon(redox_daemon, pcid_handle).unwrap(); + unreachable!(); +} + +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> anyhow::Result<()> { + common::setup_logging( + "disk", + "pci", + "virtio-blkd", + common::output_level(), + common::file_level(), + ); // Double check that we have the right device. // @@ -169,15 +180,3 @@ fn daemon(daemon: daemon::Daemon) -> anyhow::Result<()> { Ok(()) } - -fn daemon_runner(redox_daemon: daemon::Daemon) -> ! { - common::setup_logging( - "disk", - "pci", - "virtio-blkd", - common::output_level(), - common::file_level(), - ); - daemon(redox_daemon).unwrap(); - unreachable!(); -} diff --git a/drivers/usb/xhcid/src/main.rs b/drivers/usb/xhcid/src/main.rs index 0a20f84d71..613bd1c7be 100644 --- a/drivers/usb/xhcid/src/main.rs +++ b/drivers/usb/xhcid/src/main.rs @@ -115,10 +115,6 @@ fn get_int_method(pcid_handle: &mut PciFunctionHandle) -> (Option, Interru } } -fn main() { - daemon::Daemon::new(daemon); -} - //TODO: cleanup CSZ support fn daemon_with_context_size( daemon: daemon::Daemon, @@ -185,8 +181,11 @@ fn daemon_with_context_size( } } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn main() { + pcid_interface::pci_daemon(daemon); +} + +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let address = unsafe { pcid_handle.map_bar(0) }.ptr.as_ptr() as usize; let cap = unsafe { &mut *(address as *mut xhci::CapabilityRegs) }; if cap.csz() { diff --git a/drivers/vboxd/src/main.rs b/drivers/vboxd/src/main.rs index 341bdcc130..710f6afa06 100644 --- a/drivers/vboxd/src/main.rs +++ b/drivers/vboxd/src/main.rs @@ -191,11 +191,10 @@ impl VboxGuestInfo { } fn main() { - daemon::Daemon::new(daemon); + pcid_interface::pci_daemon(daemon); } -fn daemon(daemon: daemon::Daemon) -> ! { - let mut pcid_handle = PciFunctionHandle::connect_default(); +fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! { let pci_config = pcid_handle.config(); let mut name = pci_config.func.name(); From 4a182077c9266cb0b42588402a9ffd82ad0366f8 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 3 Dec 2025 22:45:09 +0100 Subject: [PATCH 3/7] ipcd: Fix a couple of warnings --- ipcd/src/uds/dgram.rs | 6 +++--- ipcd/src/uds/stream.rs | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ipcd/src/uds/dgram.rs b/ipcd/src/uds/dgram.rs index 57cd811ccb..ef5b9f53a6 100644 --- a/ipcd/src/uds/dgram.rs +++ b/ipcd/src/uds/dgram.rs @@ -737,9 +737,9 @@ impl<'sock> SchemeSync for UdsDgramScheme<'sock> { } } - fn fevent(&mut self, id: usize, flags: EventFlags, ctx: &CallerCtx) -> Result { + fn fevent(&mut self, id: usize, flags: EventFlags, _ctx: &CallerCtx) -> Result { let socket_rc = self.get_socket(id)?; - let mut socket = socket_rc.borrow_mut(); + let socket = socket_rc.borrow_mut(); let mut ready = EventFlags::empty(); if flags.contains(EVENT_READ) && !socket.messages.is_empty() { @@ -752,7 +752,7 @@ impl<'sock> SchemeSync for UdsDgramScheme<'sock> { Ok(ready) } - fn fstat(&mut self, id: usize, stat: &mut Stat, ctx: &CallerCtx) -> Result<()> { + fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> { self.get_socket(id)?; *stat = Stat { diff --git a/ipcd/src/uds/stream.rs b/ipcd/src/uds/stream.rs index 3f41638446..8b084b12a1 100644 --- a/ipcd/src/uds/stream.rs +++ b/ipcd/src/uds/stream.rs @@ -16,7 +16,7 @@ use std::{ cell::RefCell, cmp, collections::{HashMap, HashSet, VecDeque}, - mem, ptr, + mem, rc::Rc, slice, }; @@ -383,7 +383,7 @@ impl<'sock> UdsStreamScheme<'sock> { }) } - fn post_fevent(&self, id: usize, mut flags: EventFlags) -> Result<()> { + fn post_fevent(&self, id: usize, flags: EventFlags) -> Result<()> { /*TODO: filter out unnecessary flags? if let Ok(socket_rc) = self.get_socket(id) { let socket = socket_rc.borrow(); @@ -1324,13 +1324,13 @@ impl<'sock> SchemeSync for UdsStreamScheme<'sock> { } } - fn fevent(&mut self, id: usize, flags: EventFlags, ctx: &CallerCtx) -> Result { + fn fevent(&mut self, id: usize, flags: EventFlags, _ctx: &CallerCtx) -> Result { let socket_rc = self.get_socket(id)?; let socket = socket_rc.borrow(); Ok(socket.events() & flags) } - fn fstat(&mut self, id: usize, stat: &mut Stat, ctx: &CallerCtx) -> Result<()> { + fn fstat(&mut self, id: usize, stat: &mut Stat, _ctx: &CallerCtx) -> Result<()> { self.get_socket(id)?; *stat = Stat { From c7adb019b5cc7eb9f72236c7c8c284526e836f1c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 5 Dec 2025 20:45:44 +0100 Subject: [PATCH 4/7] Use file as default scheme from the start This removes one piece of state that init has to manage for the processes it spawns. This also allows getting rid of the concept of a default scheme from relibc if we want. --- bootstrap/src/exec.rs | 2 +- init.rc | 3 +-- init/src/main.rs | 39 +-------------------------------------- init_drivers.rc | 2 +- 4 files changed, 4 insertions(+), 42 deletions(-) diff --git a/bootstrap/src/exec.rs b/bootstrap/src/exec.rs index 9f5a32bdec..7d32305718 100644 --- a/bootstrap/src/exec.rs +++ b/bootstrap/src/exec.rs @@ -90,7 +90,7 @@ pub fn main() -> ! { // from this point, this_thr_fd is no longer valid const CWD: &[u8] = b"/scheme/initfs"; - const DEFAULT_SCHEME: &[u8] = b"initfs"; + const DEFAULT_SCHEME: &[u8] = b"file"; let extrainfo = ExtraInfo { cwd: Some(CWD), default_scheme: Some(DEFAULT_SCHEME), diff --git a/init.rc b/init.rc index 6fb3094f77..dc716b7582 100644 --- a/init.rc +++ b/init.rc @@ -1,6 +1,6 @@ # Various daemons that relibc needs to function as well as a bunch of env vars # that should be set for every program. -export PATH /bin +export PATH /scheme/initfs/bin export RUST_BACKTRACE 1 rtcd nulld @@ -34,7 +34,6 @@ redoxfs --uuid $REDOXFS_UUID file $REDOXFS_BLOCK unset REDOXFS_UUID REDOXFS_BLOCK REDOXFS_PASSWORD_ADDR REDOXFS_PASSWORD_SIZE # Exit initfs -set-default-scheme file cd / export PATH /usr/bin run.d /usr/lib/init.d /etc/init.d diff --git a/init/src/main.rs b/init/src/main.rs index a20e489f32..086b3e4fe7 100644 --- a/init/src/main.rs +++ b/init/src/main.rs @@ -1,33 +1,12 @@ use std::collections::BTreeMap; use std::env; -use std::ffi::CString; use std::fs::{read_dir, File}; use std::io::{BufRead, BufReader, Result}; use std::path::Path; use std::process::Command; -use libredox::error::Error as OsError; - use libredox::flag::{O_RDONLY, O_WRONLY}; -fn set_default_scheme(scheme: &str) -> std::result::Result<(), OsError> { - use std::ffi::{c_char, c_int}; - - extern "C" { - fn set_default_scheme(scheme: *const c_char) -> c_int; - } - - let cstr = - CString::new(scheme.as_bytes()).expect(&format!("init: invalid default scheme {}", scheme)); - - let res = unsafe { set_default_scheme(cstr.as_ptr()) }; - - match res { - 0 => Ok(()), - error_code => Err(OsError::new(error_code)), - } -} - fn switch_stdio(stdio: &str) -> Result<()> { let stdin = libredox::Fd::open(stdio, O_RDONLY, 0)?; let stdout = libredox::Fd::open(stdio, O_WRONLY, 0)?; @@ -66,18 +45,6 @@ pub fn run(file: &Path) -> Result<()> { println!("init: failed to cd: no argument"); } } - "set-default-scheme" => { - if let Some(scheme) = args.next() { - if let Err(err) = set_default_scheme(&scheme) { - println!( - "init: failed to set default scheme to '{}': {}", - scheme, err - ); - } - } else { - println!("init: failed to set default scheme: no argument"); - } - } "echo" => { if let Some(arg) = args.next() { print!("{}", arg); @@ -224,11 +191,7 @@ pub fn run(file: &Path) -> Result<()> { } pub fn main() { - if let Err(err) = set_default_scheme("initfs") { - println!("init: failed to set default scheme: {}", err); - } - - let config = "/etc/init.rc"; + let config = "/scheme/initfs/etc/init.rc"; if let Err(err) = run(&Path::new(config)) { println!("init: failed to run {}: {}", config, err); } diff --git a/init_drivers.rc b/init_drivers.rc index 586b45ac87..4ccdf61475 100644 --- a/init_drivers.rc +++ b/init_drivers.rc @@ -1,3 +1,3 @@ ps2d us hwd -pcid-spawner /etc/pcid/initfs.toml +pcid-spawner /scheme/initfs/etc/pcid/initfs.toml From 1d834c23933800db72cdf0665efda4c7f1d9e99e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 5 Dec 2025 20:52:33 +0100 Subject: [PATCH 5/7] init: Read config files all at once This is simpler than streaming and likely a bit faster. Config files are expected to be tiny. --- init/src/main.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/init/src/main.rs b/init/src/main.rs index 086b3e4fe7..8a348f235a 100644 --- a/init/src/main.rs +++ b/init/src/main.rs @@ -1,9 +1,9 @@ use std::collections::BTreeMap; -use std::env; -use std::fs::{read_dir, File}; -use std::io::{BufRead, BufReader, Result}; +use std::fs::read_dir; +use std::io::Result; use std::path::Path; use std::process::Command; +use std::{env, fs}; use libredox::flag::{O_RDONLY, O_WRONLY}; @@ -20,10 +20,7 @@ fn switch_stdio(stdio: &str) -> Result<()> { } pub fn run(file: &Path) -> Result<()> { - let file = File::open(file)?; - let reader = BufReader::new(file); - for line_res in reader.lines() { - let line_raw = line_res?; + for line_raw in fs::read_to_string(file)?.lines() { let line = line_raw.trim(); if !line.is_empty() && !line.starts_with('#') { let mut args = line.split(' ').map(|arg| { From 858ff9cea91629d4ac1263a56228589d49b11f8d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 5 Dec 2025 21:02:38 +0100 Subject: [PATCH 6/7] init: Refactor the run function to reduce indentation --- init/Cargo.toml | 2 +- init/src/main.rs | 295 +++++++++++++++++++++++------------------------ 2 files changed, 146 insertions(+), 151 deletions(-) diff --git a/init/Cargo.toml b/init/Cargo.toml index 1c2eee4630..8362f047a1 100644 --- a/init/Cargo.toml +++ b/init/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "init" version = "0.1.0" -edition = "2021" +edition = "2024" license = "MIT" [dependencies] diff --git a/init/src/main.rs b/init/src/main.rs index 8a348f235a..78b6dc4094 100644 --- a/init/src/main.rs +++ b/init/src/main.rs @@ -20,171 +20,166 @@ fn switch_stdio(stdio: &str) -> Result<()> { } pub fn run(file: &Path) -> Result<()> { - for line_raw in fs::read_to_string(file)?.lines() { - let line = line_raw.trim(); - if !line.is_empty() && !line.starts_with('#') { - let mut args = line.split(' ').map(|arg| { - if arg.starts_with('$') { - env::var(&arg[1..]).unwrap_or(String::new()) - } else { - arg.to_string() + for line in fs::read_to_string(file)?.lines() { + run_command(line); + } + + Ok(()) +} + +fn run_command(line_raw: &str) { + let line = line_raw.trim(); + if line.is_empty() || line.starts_with('#') { + return; + } + let mut args = line.split(' ').map(|arg| { + if arg.starts_with('$') { + env::var(&arg[1..]).unwrap_or(String::new()) + } else { + arg.to_string() + } + }); + + if let Some(cmd) = args.next() { + match cmd.as_str() { + "cd" => { + let Some(dir) = args.next() else { + println!("init: failed to cd: no argument"); + return; + }; + if let Err(err) = env::set_current_dir(&dir) { + println!("init: failed to cd to '{}': {}", dir, err); } - }); + } + "echo" => { + println!("{}", args.collect::>().join(" ")); + } + "export" => { + let Some(var) = args.next() else { + println!("init: failed to export: no argument"); + return; + }; + let mut value = String::new(); + if let Some(arg) = args.next() { + value.push_str(&arg); + } + for arg in args { + value.push(' '); + value.push_str(&arg); + } + unsafe { env::set_var(var, value) }; + } + "run" => { + let Some(new_file) = args.next() else { + println!("init: failed to run: no argument"); + return; + }; + if let Err(err) = run(&Path::new(&new_file)) { + println!("init: failed to run '{}': {}", new_file, err); + } + } + "run.d" => { + // This must be a BTreeMap to iterate in sorted order. + let mut entries = BTreeMap::new(); + let mut missing_arg = true; - if let Some(cmd) = args.next() { - match cmd.as_str() { - "cd" => { - if let Some(dir) = args.next() { - if let Err(err) = env::set_current_dir(&dir) { - println!("init: failed to cd to '{}': {}", dir, err); - } - } else { - println!("init: failed to cd: no argument"); - } + for new_dir in args { + if !Path::new(&new_dir).exists() { + // Skip non-existent dirs + continue; } - "echo" => { - if let Some(arg) = args.next() { - print!("{}", arg); - } - for arg in args { - print!(" {}", arg); - } - print!("\n"); - } - "export" => { - if let Some(var) = args.next() { - let mut value = String::new(); - if let Some(arg) = args.next() { - value.push_str(&arg); - } - for arg in args { - value.push(' '); - value.push_str(&arg); - } - env::set_var(var, value); - } else { - println!("init: failed to export: no argument"); - } - } - "run" => { - if let Some(new_file) = args.next() { - if let Err(err) = run(&Path::new(&new_file)) { - println!("init: failed to run '{}': {}", new_file, err); - } - } else { - println!("init: failed to run: no argument"); - } - } - "run.d" => { - // This must be a BTreeMap to iterate in sorted order. - let mut entries = BTreeMap::new(); - let mut missing_arg = true; + missing_arg = false; - for new_dir in args { - if !Path::new(&new_dir).exists() { - // Skip non-existent dirs - continue; - } - missing_arg = false; - - match read_dir(&new_dir) { - Ok(list) => { - for entry_res in list { - match entry_res { - Ok(entry) => { - // This intentionally overwrites older entries with - // the same filename to allow overriding entries in - // one search dir with those in a later search dir. - entries.insert(entry.file_name(), entry.path()); - } - Err(err) => { - println!( - "init: failed to run.d: '{}': {}", - new_dir, err - ); - } - } - } - } - Err(err) => { - println!("init: failed to run.d: '{}': {}", new_dir, err); - } - } + let list = match read_dir(&new_dir) { + Ok(list) => list, + Err(err) => { + println!("init: failed to run.d: '{}': {}", new_dir, err); + continue; } - - if missing_arg { - println!( - "init: failed to run.d: no argument or all dirs are non-existent" - ); - } else { - // This takes advantage of BTreeMap iterating in sorted order. - for (_, entry_path) in entries { - if let Err(err) = run(&entry_path) { - println!( - "init: failed to run '{}': {}", - entry_path.display(), - err - ); - } + }; + for entry_res in list { + match entry_res { + Ok(entry) => { + // This intentionally overwrites older entries with + // the same filename to allow overriding entries in + // one search dir with those in a later search dir. + entries.insert(entry.file_name(), entry.path()); + } + Err(err) => { + println!("init: failed to run.d: '{}': {}", new_dir, err); } } } - "stdio" => { - if let Some(stdio) = args.next() { - if let Err(err) = switch_stdio(&stdio) { - println!("init: failed to switch stdio to '{}': {}", stdio, err); - } - } else { - println!("init: failed to set stdio: no argument"); + } + + if missing_arg { + println!("init: failed to run.d: no argument or all dirs are non-existent"); + return; + } + + // This takes advantage of BTreeMap iterating in sorted order. + for (_, entry_path) in entries { + if let Err(err) = run(&entry_path) { + println!("init: failed to run '{}': {}", entry_path.display(), err); + } + } + } + "stdio" => { + let Some(stdio) = args.next() else { + println!("init: failed to set stdio: no argument"); + return; + }; + if let Err(err) = switch_stdio(&stdio) { + println!("init: failed to switch stdio to '{}': {}", stdio, err); + } + } + "unset" => { + for arg in args { + unsafe { env::remove_var(&arg) }; + } + } + "nowait" => { + let Some(cmd) = args.next() else { + println!("init: failed to run nowait: no argument"); + return; + }; + let mut command = Command::new(cmd); + + for arg in args { + command.arg(arg); + } + + match command.spawn() { + Ok(_child) => {} + Err(err) => println!("init: failed to execute '{}': {}", line, err), + } + } + _ => { + let mut command = Command::new(cmd.clone()); + for arg in args { + command.arg(arg); + } + + let mut child = match command.spawn() { + Ok(child) => child, + Err(err) => { + println!("init: failed to execute '{}': {}", line, err); + return; + } + }; + match child.wait() { + Ok(exit_status) => { + if !exit_status.success() { + println!("{cmd} failed with {exit_status}"); } } - "unset" => { - for arg in args { - env::remove_var(&arg); - } - } - "nowait" => { - if let Some(cmd) = args.next() { - let mut command = Command::new(cmd); - - for arg in args { - command.arg(arg); - } - - match command.spawn() { - Ok(_child) => {} - Err(err) => println!("init: failed to execute '{}': {}", line, err), - } - } else { - println!("init: failed to run nowait: no argument"); - } - } - _ => { - let mut command = Command::new(cmd.clone()); - for arg in args { - command.arg(arg); - } - - match command.spawn() { - Ok(mut child) => match child.wait() { - Ok(exit_status) => { - if !exit_status.success() { - println!("{cmd} failed with {exit_status}"); - } - } - Err(err) => { - println!("init: failed to wait for '{}': {}", line, err) - } - }, - Err(err) => println!("init: failed to execute '{}': {}", line, err), - } + Err(err) => { + println!("init: failed to wait for '{}': {}", line, err) } } } } } - - Ok(()) } pub fn main() { From 6c39bea37af017543d0422114c908f1acbbe7203 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 5 Dec 2025 22:06:39 +0100 Subject: [PATCH 7/7] Only depend on redox-rt when compiling for redox This fixes rust-analyzer when it is not configured to use redox as target. --- bootstrap/Cargo.toml | 4 +++- ipcd/Cargo.toml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bootstrap/Cargo.toml b/bootstrap/Cargo.toml index 4e47886def..c7a17745f1 100644 --- a/bootstrap/Cargo.toml +++ b/bootstrap/Cargo.toml @@ -20,11 +20,13 @@ plain = "0.2" redox-initfs = { path = "../initfs", default-features = false } redox_syscall = { version = "0.5.4", default-features = false } redox-scheme = { version = "0.6", default-features = false } -redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc.git", default-features = false } redox-path = "0.3.1" slab = { version = "0.4.9", default-features = false } arrayvec = { version = "0.7.6", default-features = false } +[target.'cfg(target_os = "redox")'.dependencies] +redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc.git", default-features = false } + [profile.release] panic = "abort" lto = "fat" diff --git a/ipcd/Cargo.toml b/ipcd/Cargo.toml index 594b6ac889..53586a144a 100644 --- a/ipcd/Cargo.toml +++ b/ipcd/Cargo.toml @@ -8,8 +8,10 @@ libredox = { version = "0.1.8", features = ["call"]} daemon = { path = "../daemon" } redox_syscall = "0.5.17" redox-scheme = "0.8.0" -redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc.git", default-features = false } redox_event = "0.4.0" anyhow = "1.0.97" libc = "0.2" rand = { version = "0.8", features = ["small_rng"] } + +[target.'cfg(target_os = "redox")'.dependencies] +redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc.git", default-features = false }