krata/libs/xen/xenstore/src/bus.rs

138 lines
3.9 KiB
Rust
Raw Normal View History

use crate::error::{Error, Result};
use crate::sys::{XsdMessageHeader, XSD_ERROR};
use std::ffi::CString;
use std::fs::{metadata, File};
2024-01-08 20:43:16 +00:00
use std::io::{Read, Write};
use std::mem::size_of;
const XEN_BUS_PATHS: &[&str] = &["/dev/xen/xenbus"];
2024-01-08 20:43:16 +00:00
fn find_bus_path() -> Option<String> {
for path in XEN_BUS_PATHS {
match metadata(path) {
Ok(_) => return Some(String::from(*path)),
Err(_) => continue,
2024-01-08 20:43:16 +00:00
}
}
None
}
2024-02-23 03:52:48 +00:00
pub struct XsdFileTransport {
handle: File,
}
impl XsdFileTransport {
fn new(path: &str) -> Result<XsdFileTransport> {
2024-02-23 03:52:48 +00:00
let handle = File::options().read(true).write(true).open(path)?;
Ok(XsdFileTransport { handle })
}
2024-02-23 04:37:53 +00:00
async fn xsd_read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
2024-02-23 03:52:48 +00:00
Ok(self.handle.read_exact(buf)?)
}
2024-02-23 04:37:53 +00:00
async fn xsd_write_all(&mut self, buf: &[u8]) -> Result<()> {
2024-02-23 03:52:48 +00:00
self.handle.write_all(buf)?;
self.handle.flush()?;
Ok(())
}
}
2024-01-08 20:43:16 +00:00
pub struct XsdSocket {
handle: XsdFileTransport,
2024-01-08 20:43:16 +00:00
}
#[derive(Debug)]
pub struct XsdResponse {
pub header: XsdMessageHeader,
pub payload: Vec<u8>,
2024-01-08 20:43:16 +00:00
}
impl XsdResponse {
pub fn parse_string(&self) -> Result<String> {
2024-01-17 13:22:47 +00:00
Ok(CString::from_vec_with_nul(self.payload.clone())?.into_string()?)
2024-01-08 23:04:06 +00:00
}
pub fn parse_string_vec(&self) -> Result<Vec<String>> {
2024-01-08 20:43:16 +00:00
let mut strings: Vec<String> = Vec::new();
let mut buffer: Vec<u8> = Vec::new();
for b in &self.payload {
if *b == 0 {
let string = String::from_utf8(buffer.clone())?;
strings.push(string);
buffer.clear();
continue;
}
buffer.push(*b);
2024-01-08 20:43:16 +00:00
}
Ok(strings)
}
pub fn parse_bool(&self) -> Result<bool> {
2024-01-18 14:15:42 +00:00
Ok(true)
}
2024-01-08 20:43:16 +00:00
}
impl XsdSocket {
2024-02-23 04:37:53 +00:00
pub async fn open() -> Result<XsdSocket> {
2024-01-08 20:43:16 +00:00
let path = match find_bus_path() {
Some(path) => path,
None => return Err(Error::BusNotFound),
2024-01-08 20:43:16 +00:00
};
2024-02-23 03:52:48 +00:00
let transport = XsdFileTransport::new(&path)?;
Ok(XsdSocket { handle: transport })
2024-01-08 20:43:16 +00:00
}
2024-02-23 04:37:53 +00:00
pub async fn send(&mut self, tx: u32, typ: u32, buf: &[u8]) -> Result<XsdResponse> {
2024-01-08 20:43:16 +00:00
let header = XsdMessageHeader {
typ,
req: 0,
tx,
len: buf.len() as u32,
2024-01-08 20:43:16 +00:00
};
2024-02-23 03:52:48 +00:00
let header_bytes = bytemuck::bytes_of(&header);
let mut composed: Vec<u8> = Vec::new();
composed.extend_from_slice(header_bytes);
composed.extend_from_slice(buf);
2024-02-23 04:37:53 +00:00
self.handle.xsd_write_all(&composed).await?;
2024-01-08 20:43:16 +00:00
let mut result_buf = vec![0u8; size_of::<XsdMessageHeader>()];
match self.handle.xsd_read_exact(result_buf.as_mut_slice()).await {
Ok(_) => {}
Err(error) => {
if result_buf.first().unwrap() == &0 {
return Err(error);
}
}
}
2024-01-08 20:43:16 +00:00
let result_header = bytemuck::from_bytes::<XsdMessageHeader>(&result_buf);
let mut payload = vec![0u8; result_header.len as usize];
2024-02-23 04:37:53 +00:00
self.handle.xsd_read_exact(payload.as_mut_slice()).await?;
2024-01-08 20:43:16 +00:00
if result_header.typ == XSD_ERROR {
let error = CString::from_vec_with_nul(payload)?;
return Err(Error::ResponseError(error.into_string()?));
2024-01-08 20:43:16 +00:00
}
2024-01-08 22:16:33 +00:00
let response = XsdResponse { header, payload };
2024-01-08 20:43:16 +00:00
Ok(response)
}
2024-02-23 04:37:53 +00:00
pub async fn send_single(&mut self, tx: u32, typ: u32, string: &str) -> Result<XsdResponse> {
2024-01-09 23:40:17 +00:00
let text = CString::new(string)?;
let buf = text.as_bytes_with_nul();
2024-02-23 04:37:53 +00:00
self.send(tx, typ, buf).await
2024-01-08 20:43:16 +00:00
}
2024-01-09 23:40:17 +00:00
2024-02-23 04:37:53 +00:00
pub async fn send_multiple(
&mut self,
tx: u32,
typ: u32,
array: &[&str],
) -> Result<XsdResponse> {
2024-01-09 23:40:17 +00:00
let mut buf: Vec<u8> = Vec::new();
for item in array {
buf.extend_from_slice(item.as_bytes());
buf.push(0);
}
2024-02-23 04:37:53 +00:00
self.send(tx, typ, buf.as_slice()).await
2024-01-09 23:40:17 +00:00
}
2024-01-08 20:43:16 +00:00
}