Use redox-scheme in driver-network

This commit is contained in:
bjorn3
2024-12-26 14:17:47 +01:00
parent be6e942a08
commit c4dbcbecf2
8 changed files with 82 additions and 87 deletions
Generated
+1
View File
@@ -401,6 +401,7 @@ name = "driver-network"
version = "0.1.0"
dependencies = [
"libredox",
"redox-scheme",
"redox_syscall",
]
+1
View File
@@ -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"
+65 -57
View File
@@ -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<T: NetworkAdapter> {
adapter: T,
scheme_name: String,
scheme: File,
socket: Socket,
next_id: usize,
handles: BTreeMap<usize, Handle>,
todo_packets: Vec<Packet>,
blocked: Vec<CallRequest>,
}
#[derive(Copy, Clone)]
@@ -47,26 +45,20 @@ enum Handle {
impl<T: NetworkAdapter> NetworkScheme<T> {
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<T: NetworkAdapter> NetworkScheme<T> {
// 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<T: NetworkAdapter> NetworkScheme<T> {
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<T: NetworkAdapter> SchemeBlockMut for NetworkScheme<T> {
Ok(Some(self.next_id))
}
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
fn read(
&mut self,
id: usize,
buf: &mut [u8],
_offset: u64,
_fcntl_flags: u32,
) -> Result<Option<usize>> {
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
let flags = match *handle {
@@ -200,7 +202,13 @@ impl<T: NetworkAdapter> SchemeBlockMut for NetworkScheme<T> {
}
}
fn write(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
fn write(
&mut self,
id: usize,
buf: &[u8],
_offset: u64,
_fcntl_flags: u32,
) -> Result<Option<usize>> {
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
match handle {
+3 -7
View File
@@ -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::<Source>::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,
)
+3 -7
View File
@@ -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::<Source>::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,
)
+4 -7
View File
@@ -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::<Source>::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,
)
+4 -8
View File
@@ -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::<Source>::new().expect("rtl8168d: Could not create event queue.");
let event_queue = EventQueue::<Source>::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,
)
+1 -1
View File
@@ -97,7 +97,7 @@ fn deamon(daemon: redox_daemon::Daemon) -> Result<(), Box<dyn std::error::Error>
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,
})?;