mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-02 21:00:55 +00:00
xenstore: implement xenbus support
This commit is contained in:
parent
3af9ffec34
commit
cf0b62c9f5
@ -1,13 +1,13 @@
|
|||||||
use crate::error::{Error, Result};
|
use crate::error::{Error, Result};
|
||||||
use crate::sys::{XsdMessageHeader, XSD_ERROR};
|
use crate::sys::{XsdMessageHeader, XSD_ERROR};
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::fs::metadata;
|
use std::fs::{self, metadata, File};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
use std::net::Shutdown;
|
use std::os::unix::fs::FileTypeExt;
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
|
|
||||||
const XEN_BUS_PATHS: &[&str] = &["/var/run/xenstored/socket"];
|
const XEN_BUS_PATHS: &[&str] = &["/dev/xen/xenbus", "/var/run/xenstored/socket"];
|
||||||
|
|
||||||
fn find_bus_path() -> Option<String> {
|
fn find_bus_path() -> Option<String> {
|
||||||
for path in XEN_BUS_PATHS {
|
for path in XEN_BUS_PATHS {
|
||||||
@ -19,8 +19,46 @@ fn find_bus_path() -> Option<String> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait XsdTransport {
|
||||||
|
fn xsd_write_all(&mut self, buf: &[u8]) -> Result<()>;
|
||||||
|
fn xsd_read_exact(&mut self, buf: &mut [u8]) -> Result<()>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl XsdTransport for UnixStream {
|
||||||
|
fn xsd_write_all(&mut self, buf: &[u8]) -> Result<()> {
|
||||||
|
Ok(self.write_all(buf)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn xsd_read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
|
||||||
|
Ok(self.read_exact(buf)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct XsdFileTransport {
|
||||||
|
handle: File,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl XsdFileTransport {
|
||||||
|
pub fn new(path: &str) -> Result<XsdFileTransport> {
|
||||||
|
let handle = File::options().read(true).write(true).open(path)?;
|
||||||
|
Ok(XsdFileTransport { handle })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl XsdTransport for XsdFileTransport {
|
||||||
|
fn xsd_read_exact(&mut self, buf: &mut [u8]) -> Result<()> {
|
||||||
|
Ok(self.handle.read_exact(buf)?)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn xsd_write_all(&mut self, buf: &[u8]) -> Result<()> {
|
||||||
|
self.handle.write_all(buf)?;
|
||||||
|
self.handle.flush()?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct XsdSocket {
|
pub struct XsdSocket {
|
||||||
handle: UnixStream,
|
handle: Box<dyn XsdTransport>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -60,8 +98,19 @@ impl XsdSocket {
|
|||||||
Some(path) => path,
|
Some(path) => path,
|
||||||
None => return Err(Error::BusNotFound),
|
None => return Err(Error::BusNotFound),
|
||||||
};
|
};
|
||||||
let stream = UnixStream::connect(path)?;
|
|
||||||
Ok(XsdSocket { handle: stream })
|
let metadata = fs::metadata(&path)?;
|
||||||
|
let file_type = metadata.file_type();
|
||||||
|
if file_type.is_socket() {
|
||||||
|
let stream = UnixStream::connect(&path)?;
|
||||||
|
return Ok(XsdSocket {
|
||||||
|
handle: Box::new(stream),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let transport = XsdFileTransport::new(&path)?;
|
||||||
|
Ok(XsdSocket {
|
||||||
|
handle: Box::new(transport),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send(&mut self, tx: u32, typ: u32, buf: &[u8]) -> Result<XsdResponse> {
|
pub fn send(&mut self, tx: u32, typ: u32, buf: &[u8]) -> Result<XsdResponse> {
|
||||||
@ -71,13 +120,16 @@ impl XsdSocket {
|
|||||||
tx,
|
tx,
|
||||||
len: buf.len() as u32,
|
len: buf.len() as u32,
|
||||||
};
|
};
|
||||||
self.handle.write_all(bytemuck::bytes_of(&header))?;
|
let header_bytes = bytemuck::bytes_of(&header);
|
||||||
self.handle.write_all(buf)?;
|
let mut composed: Vec<u8> = Vec::new();
|
||||||
|
composed.extend_from_slice(header_bytes);
|
||||||
|
composed.extend_from_slice(buf);
|
||||||
|
self.handle.xsd_write_all(&composed)?;
|
||||||
let mut result_buf = vec![0u8; size_of::<XsdMessageHeader>()];
|
let mut result_buf = vec![0u8; size_of::<XsdMessageHeader>()];
|
||||||
self.handle.read_exact(result_buf.as_mut_slice())?;
|
self.handle.xsd_read_exact(result_buf.as_mut_slice())?;
|
||||||
let result_header = bytemuck::from_bytes::<XsdMessageHeader>(&result_buf);
|
let result_header = bytemuck::from_bytes::<XsdMessageHeader>(&result_buf);
|
||||||
let mut payload = vec![0u8; result_header.len as usize];
|
let mut payload = vec![0u8; result_header.len as usize];
|
||||||
self.handle.read_exact(payload.as_mut_slice())?;
|
self.handle.xsd_read_exact(payload.as_mut_slice())?;
|
||||||
if result_header.typ == XSD_ERROR {
|
if result_header.typ == XSD_ERROR {
|
||||||
let error = CString::from_vec_with_nul(payload)?;
|
let error = CString::from_vec_with_nul(payload)?;
|
||||||
return Err(Error::ResponseError(error.into_string()?));
|
return Err(Error::ResponseError(error.into_string()?));
|
||||||
@ -101,9 +153,3 @@ impl XsdSocket {
|
|||||||
self.send(tx, typ, buf.as_slice())
|
self.send(tx, typ, buf.as_slice())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for XsdSocket {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.handle.shutdown(Shutdown::Both).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user