diff --git a/Cargo.lock b/Cargo.lock index 3bd00c9a93..98e288a0d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -401,6 +401,7 @@ name = "driver-network" version = "0.1.0" dependencies = [ "libredox", + "redox-scheme", "redox_syscall", ] diff --git a/net/driver-network/Cargo.toml b/net/driver-network/Cargo.toml index bfec9b86d1..26535c8627 100644 --- a/net/driver-network/Cargo.toml +++ b/net/driver-network/Cargo.toml @@ -5,4 +5,5 @@ edition = "2021" [dependencies] libredox = "0.1.3" +redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" } redox_syscall = "0.5" diff --git a/net/driver-network/src/lib.rs b/net/driver-network/src/lib.rs index ce108dcd70..33b33172c2 100644 --- a/net/driver-network/src/lib.rs +++ b/net/driver-network/src/lib.rs @@ -1,13 +1,11 @@ use std::collections::BTreeMap; -use std::fs::File; -use std::io::{ErrorKind, Read, Write}; -use std::os::fd::{AsRawFd, FromRawFd, RawFd}; use std::{cmp, io}; -use libredox::flag; +use libredox::Fd; +use redox_scheme::{CallRequest, RequestKind, Response, SchemeBlockMut, SignalBehavior, Socket}; use syscall::{ - Error, EventFlags, Packet, Result, SchemeBlockMut, Stat, EACCES, EBADF, EINVAL, EWOULDBLOCK, - MODE_FILE, O_NONBLOCK, + Error, EventFlags, Result, Stat, EACCES, EAGAIN, EBADF, EINTR, EINVAL, EWOULDBLOCK, MODE_FILE, + O_NONBLOCK, }; pub trait NetworkAdapter { @@ -32,10 +30,10 @@ pub trait NetworkAdapter { pub struct NetworkScheme { adapter: T, scheme_name: String, - scheme: File, + socket: Socket, next_id: usize, handles: BTreeMap, - todo_packets: Vec, + blocked: Vec, } #[derive(Copy, Clone)] @@ -47,26 +45,20 @@ enum Handle { impl NetworkScheme { pub fn new(adapter: T, scheme_name: String) -> Self { assert!(scheme_name.starts_with("network")); - let scheme_fd = libredox::call::open( - format!(":{scheme_name}"), - flag::O_RDWR | flag::O_CREAT | flag::O_NONBLOCK, - 0, - ) - .expect("failed to create network scheme"); - let scheme = unsafe { File::from_raw_fd(scheme_fd as RawFd) }; + let socket = Socket::nonblock(&scheme_name).expect("failed to create network scheme"); NetworkScheme { adapter, scheme_name, - scheme, + socket, next_id: 0, handles: BTreeMap::new(), - todo_packets: vec![], + blocked: vec![], } } - pub fn event_handle(&self) -> RawFd { - self.scheme.as_raw_fd() + pub fn event_handle(&self) -> &Fd { + self.socket.inner() } pub fn adapter(&self) -> &T { @@ -86,41 +78,53 @@ impl NetworkScheme { // to call when an irq is received to indicate that blocked packets can // be processed. pub fn tick(&mut self) -> io::Result<()> { - // Handle any blocked packets + // Handle any blocked requests let mut i = 0; - while i < self.todo_packets.len() { - let mut packet = self.todo_packets[i].clone(); - if let Some(a) = self.handle(&packet) { - self.todo_packets.remove(i); - packet.a = a; - self.scheme.write(&packet)?; + while i < self.blocked.len() { + if let Some(resp) = self.blocked[i].handle_scheme_block_mut(self) { + self.socket + .write_response(resp, SignalBehavior::Restart) + .expect("vesad: failed to write display scheme"); + self.blocked.remove(i); } else { i += 1; } } - // Handle new scheme packets + // Handle new scheme requests loop { - let mut packet = Packet::default(); - match self.scheme.read(&mut packet) { - Ok(0) => { - return Err(io::Error::new( - ErrorKind::BrokenPipe, - "scheme has been closed by the kernel", - )); + let request = match self.socket.next_request(SignalBehavior::Restart) { + Ok(Some(request)) => request, + Ok(None) => { + // Scheme likely got unmounted + std::process::exit(0); } - Ok(_) => {} - Err(err) if err.kind() == ErrorKind::WouldBlock => break, - Err(err) => { - return Err(err); - } - } + Err(err) if err.errno == EAGAIN => break, + Err(err) => return Err(err.into()), + }; - if let Some(a) = self.handle(&packet) { - packet.a = a; - self.scheme.write(&packet)?; - } else { - self.todo_packets.push(packet); + match request.kind() { + RequestKind::Call(call_request) => { + if let Some(resp) = call_request.handle_scheme_block_mut(self) { + self.socket.write_response(resp, SignalBehavior::Restart)?; + } else { + self.blocked.push(call_request); + } + } + RequestKind::Cancellation(cancellation_request) => { + if let Some(i) = self + .blocked + .iter() + .position(|req| req.request().request_id() == cancellation_request.id) + { + let blocked_req = self.blocked.remove(i); + let resp = Response::new(&blocked_req, Err(syscall::Error::new(EINTR))); + self.socket.write_response(resp, SignalBehavior::Restart)?; + } + } + RequestKind::MsyncMsg | RequestKind::MunmapMsg | RequestKind::MmapMsg => { + unreachable!() + } } } @@ -128,16 +132,8 @@ impl NetworkScheme { let available_for_read = self.adapter.available_for_read(); if available_for_read > 0 { for &handle_id in self.handles.keys() { - self.scheme.write(&Packet { - id: 0, - pid: 0, - uid: 0, - gid: 0, - a: syscall::number::SYS_FEVENT, - b: handle_id, - c: syscall::flag::EVENT_READ.bits(), - d: available_for_read, - })?; + self.socket + .post_fevent(handle_id, syscall::flag::EVENT_READ.bits())?; } return Ok(()); } @@ -174,7 +170,13 @@ impl SchemeBlockMut for NetworkScheme { Ok(Some(self.next_id)) } - fn read(&mut self, id: usize, buf: &mut [u8]) -> Result> { + fn read( + &mut self, + id: usize, + buf: &mut [u8], + _offset: u64, + _fcntl_flags: u32, + ) -> Result> { let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?; let flags = match *handle { @@ -200,7 +202,13 @@ impl SchemeBlockMut for NetworkScheme { } } - fn write(&mut self, id: usize, buf: &[u8]) -> Result> { + fn write( + &mut self, + id: usize, + buf: &[u8], + _offset: u64, + _fcntl_flags: u32, + ) -> Result> { let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?; match handle { diff --git a/net/e1000d/src/main.rs b/net/e1000d/src/main.rs index ca506185c3..4d2299d89e 100644 --- a/net/e1000d/src/main.rs +++ b/net/e1000d/src/main.rs @@ -1,13 +1,9 @@ -use std::cell::RefCell; -use std::convert::Infallible; -use std::io::{Read, Result, Write}; +use std::io::{Read, Write}; use std::os::unix::io::AsRawFd; -use std::rc::Rc; use driver_network::NetworkScheme; use event::{user_data, EventQueue}; use pcid_interface::PciFunctionHandle; -use syscall::EventFlags; pub mod device; @@ -46,7 +42,7 @@ fn main() { } } - let mut event_queue = + let event_queue = EventQueue::::new().expect("e1000d: failed to create event queue"); event_queue @@ -58,7 +54,7 @@ fn main() { .expect("e1000d: failed to subscribe to IRQ fd"); event_queue .subscribe( - scheme.event_handle() as usize, + scheme.event_handle().raw(), Source::Scheme, event::EventFlags::READ, ) diff --git a/net/ixgbed/src/main.rs b/net/ixgbed/src/main.rs index cd4090c319..a066c3db0a 100644 --- a/net/ixgbed/src/main.rs +++ b/net/ixgbed/src/main.rs @@ -1,13 +1,9 @@ -use std::cell::RefCell; -use std::convert::Infallible; -use std::io::{Read, Result, Write}; +use std::io::{Read, Write}; use std::os::unix::io::AsRawFd; -use std::rc::Rc; use driver_network::NetworkScheme; use event::{user_data, EventQueue}; use pcid_interface::PciFunctionHandle; -use syscall::EventFlags; pub mod device; #[rustfmt::skip] @@ -47,7 +43,7 @@ fn main() { } } - let mut event_queue = + let event_queue = EventQueue::::new().expect("ixgbed: Could not create event queue."); event_queue .subscribe( @@ -58,7 +54,7 @@ fn main() { .unwrap(); event_queue .subscribe( - scheme.event_handle() as usize, + scheme.event_handle().raw(), Source::Scheme, event::EventFlags::READ, ) diff --git a/net/rtl8139d/src/main.rs b/net/rtl8139d/src/main.rs index c6db719c9d..70e56cd655 100644 --- a/net/rtl8139d/src/main.rs +++ b/net/rtl8139d/src/main.rs @@ -1,12 +1,10 @@ #![feature(int_roundings)] -use std::cell::RefCell; -use std::convert::{Infallible, TryInto}; +use std::convert::TryInto; use std::fs::File; -use std::io::{Read, Result, Write}; +use std::io::{Read, Write}; use std::os::unix::io::AsRawFd; use std::ptr::NonNull; -use std::rc::Rc; use driver_network::NetworkScheme; use event::{user_data, EventQueue}; @@ -18,7 +16,6 @@ use pcid_interface::{ MsiSetFeatureInfo, PciFeature, PciFeatureInfo, PciFunctionHandle, SetFeatureInfo, SubdriverArguments, }; -use syscall::EventFlags; pub mod device; @@ -221,7 +218,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { } } - let mut event_queue = + let event_queue = EventQueue::::new().expect("rtl8139d: Could not create event queue."); event_queue .subscribe( @@ -232,7 +229,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { .unwrap(); event_queue .subscribe( - scheme.event_handle() as usize, + scheme.event_handle().raw(), Source::Scheme, event::EventFlags::READ, ) diff --git a/net/rtl8168d/src/main.rs b/net/rtl8168d/src/main.rs index 49ebc8491c..49dfef09c3 100644 --- a/net/rtl8168d/src/main.rs +++ b/net/rtl8168d/src/main.rs @@ -1,10 +1,8 @@ -use std::cell::RefCell; -use std::convert::{Infallible, TryInto}; +use std::convert::TryInto; use std::fs::File; -use std::io::{Read, Result, Write}; +use std::io::{Read, Write}; use std::os::unix::io::AsRawFd; use std::ptr::NonNull; -use std::rc::Rc; use driver_network::NetworkScheme; use event::{user_data, EventQueue}; @@ -16,7 +14,6 @@ use pcid_interface::{ MsiSetFeatureInfo, PciFeature, PciFeatureInfo, PciFunctionHandle, SetFeatureInfo, SubdriverArguments, }; -use syscall::EventFlags; pub mod device; @@ -219,8 +216,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { } } - let mut event_queue = - EventQueue::::new().expect("rtl8168d: Could not create event queue."); + let event_queue = EventQueue::::new().expect("rtl8168d: Could not create event queue."); event_queue .subscribe( irq_file.as_raw_fd() as usize, @@ -230,7 +226,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! { .unwrap(); event_queue .subscribe( - scheme.event_handle() as usize, + scheme.event_handle().raw(), Source::Scheme, event::EventFlags::READ, ) diff --git a/net/virtio-netd/src/main.rs b/net/virtio-netd/src/main.rs index b054534a7a..c2c4a798dc 100644 --- a/net/virtio-netd/src/main.rs +++ b/net/virtio-netd/src/main.rs @@ -97,7 +97,7 @@ fn deamon(daemon: redox_daemon::Daemon) -> Result<(), Box let mut event_queue = File::open("/scheme/event")?; event_queue.write(&syscall::Event { - id: scheme.event_handle() as usize, + id: scheme.event_handle().raw(), flags: syscall::EVENT_READ, data: 0, })?;