mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-02 12:50:54 +00:00
implement evtchn support
This commit is contained in:
parent
7ca32dd413
commit
47b924d618
@ -1,5 +1,6 @@
|
|||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"xsd"
|
"xenstore",
|
||||||
|
"xenevtchn"
|
||||||
]
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
16
xenevtchn/Cargo.toml
Normal file
16
xenevtchn/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "xenevtchn"
|
||||||
|
version = "0.0.1"
|
||||||
|
edition = "2021"
|
||||||
|
resolver = "2"
|
||||||
|
|
||||||
|
[dependencies.nix]
|
||||||
|
version = "0.27.1"
|
||||||
|
features = ["ioctl"]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
|
||||||
|
[[example]]
|
||||||
|
name = "xenevtchn-simple"
|
||||||
|
path = "examples/simple.rs"
|
10
xenevtchn/examples/simple.rs
Normal file
10
xenevtchn/examples/simple.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
use xenevtchn::{EventChannel, EventChannelError};
|
||||||
|
|
||||||
|
fn main() -> Result<(), EventChannelError> {
|
||||||
|
let mut channel = EventChannel::open()?;
|
||||||
|
println!("Channel opened.");
|
||||||
|
let port = channel.bind_unbound_port(1)?;
|
||||||
|
println!("port: {}", port);
|
||||||
|
channel.unbind(port)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
103
xenevtchn/src/lib.rs
Normal file
103
xenevtchn/src/lib.rs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
pub mod sys;
|
||||||
|
|
||||||
|
use crate::sys::{BindInterdomain, BindUnboundPort, BindVirq, Notify, UnbindPort};
|
||||||
|
use nix::errno::Errno;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
use std::fs::{File, OpenOptions};
|
||||||
|
use std::os::fd::AsRawFd;
|
||||||
|
|
||||||
|
pub struct EventChannel {
|
||||||
|
pub handle: File,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct EventChannelError {
|
||||||
|
message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventChannelError {
|
||||||
|
pub fn new(msg: &str) -> EventChannelError {
|
||||||
|
EventChannelError {
|
||||||
|
message: msg.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for EventChannelError {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for EventChannelError {
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
&self.message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::io::Error> for EventChannelError {
|
||||||
|
fn from(value: std::io::Error) -> Self {
|
||||||
|
EventChannelError::new(value.to_string().as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Errno> for EventChannelError {
|
||||||
|
fn from(value: Errno) -> Self {
|
||||||
|
EventChannelError::new(value.to_string().as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventChannel {
|
||||||
|
pub fn open() -> Result<EventChannel, EventChannelError> {
|
||||||
|
let file = OpenOptions::new()
|
||||||
|
.read(true)
|
||||||
|
.write(true)
|
||||||
|
.open("/dev/xen/evtchn")?;
|
||||||
|
Ok(EventChannel { handle: file })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_virq(&mut self, virq: u32) -> Result<u32, EventChannelError> {
|
||||||
|
unsafe {
|
||||||
|
let mut request = BindVirq { virq };
|
||||||
|
Ok(sys::bind_virq(self.handle.as_raw_fd(), &mut request)? as u32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_interdomain(&mut self, domid: u32, port: u32) -> Result<u32, EventChannelError> {
|
||||||
|
unsafe {
|
||||||
|
let mut request = BindInterdomain {
|
||||||
|
remote_domain: domid,
|
||||||
|
remote_port: port,
|
||||||
|
};
|
||||||
|
Ok(sys::bind_interdomain(self.handle.as_raw_fd(), &mut request)? as u32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bind_unbound_port(&mut self, domid: u32) -> Result<u32, EventChannelError> {
|
||||||
|
unsafe {
|
||||||
|
let mut request = BindUnboundPort {
|
||||||
|
remote_domain: domid,
|
||||||
|
};
|
||||||
|
Ok(sys::bind_unbound_port(self.handle.as_raw_fd(), &mut request)? as u32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn unbind(&mut self, port: u32) -> Result<u32, EventChannelError> {
|
||||||
|
unsafe {
|
||||||
|
let mut request = UnbindPort { port };
|
||||||
|
Ok(sys::unbind(self.handle.as_raw_fd(), &mut request)? as u32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn notify(&mut self, port: u32) -> Result<u32, EventChannelError> {
|
||||||
|
unsafe {
|
||||||
|
let mut request = Notify { port };
|
||||||
|
Ok(sys::notify(self.handle.as_raw_fd(), &mut request)? as u32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(&mut self) -> Result<u32, EventChannelError> {
|
||||||
|
unsafe { Ok(sys::reset(self.handle.as_raw_fd())? as u32) }
|
||||||
|
}
|
||||||
|
}
|
43
xenevtchn/src/sys.rs
Normal file
43
xenevtchn/src/sys.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use nix::{ioctl_none, ioctl_readwrite_bad, request_code_none};
|
||||||
|
use std::ffi::c_uint;
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct BindVirq {
|
||||||
|
pub virq: c_uint,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct BindInterdomain {
|
||||||
|
pub remote_domain: c_uint,
|
||||||
|
pub remote_port: c_uint,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct BindUnboundPort {
|
||||||
|
pub remote_domain: c_uint,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct UnbindPort {
|
||||||
|
pub port: c_uint,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Notify {
|
||||||
|
pub port: c_uint,
|
||||||
|
}
|
||||||
|
|
||||||
|
ioctl_readwrite_bad!(bind_virq, request_code_none!(b'E', 0), BindVirq);
|
||||||
|
ioctl_readwrite_bad!(
|
||||||
|
bind_interdomain,
|
||||||
|
request_code_none!(b'E', 1),
|
||||||
|
BindInterdomain
|
||||||
|
);
|
||||||
|
ioctl_readwrite_bad!(
|
||||||
|
bind_unbound_port,
|
||||||
|
request_code_none!(b'E', 2),
|
||||||
|
BindUnboundPort
|
||||||
|
);
|
||||||
|
ioctl_readwrite_bad!(unbind, request_code_none!(b'E', 3), UnbindPort);
|
||||||
|
ioctl_readwrite_bad!(notify, request_code_none!(b'E', 4), Notify);
|
||||||
|
ioctl_none!(reset, b'E', 5);
|
@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "xsd"
|
name = "xenstore"
|
||||||
version = "0.0.1"
|
version = "0.0.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
@ -15,5 +15,5 @@ version = "1.14.0"
|
|||||||
features = ["derive"]
|
features = ["derive"]
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
name = "xsd-list"
|
name = "xenstore-ls"
|
||||||
path = "examples/list.rs"
|
path = "examples/list.rs"
|
@ -1,6 +1,6 @@
|
|||||||
use xsd::bus::XsdBusError;
|
use xenstore::bus::XsdBusError;
|
||||||
use xsd::client::{XsdClient, XsdInterface};
|
use xenstore::client::{XsdClient, XsdInterface};
|
||||||
use xsd::sys::XSD_ERROR_EINVAL;
|
use xenstore::sys::XSD_ERROR_EINVAL;
|
||||||
|
|
||||||
fn list_recursive(client: &mut XsdClient, level: usize, path: &str) -> Result<(), XsdBusError> {
|
fn list_recursive(client: &mut XsdClient, level: usize, path: &str) -> Result<(), XsdBusError> {
|
||||||
let children = match client.list(path) {
|
let children = match client.list(path) {
|
Loading…
Reference in New Issue
Block a user