From cf0b62c9f57323dd863a137f64306ff20245c85f Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Fri, 23 Feb 2024 03:52:48 +0000 Subject: [PATCH] xenstore: implement xenbus support --- libs/xen/xenstore/src/bus.rs | 78 ++++++++++++++++++++++++++++-------- 1 file changed, 62 insertions(+), 16 deletions(-) diff --git a/libs/xen/xenstore/src/bus.rs b/libs/xen/xenstore/src/bus.rs index db6cb08..6a71b01 100644 --- a/libs/xen/xenstore/src/bus.rs +++ b/libs/xen/xenstore/src/bus.rs @@ -1,13 +1,13 @@ use crate::error::{Error, Result}; use crate::sys::{XsdMessageHeader, XSD_ERROR}; use std::ffi::CString; -use std::fs::metadata; +use std::fs::{self, metadata, File}; use std::io::{Read, Write}; use std::mem::size_of; -use std::net::Shutdown; +use std::os::unix::fs::FileTypeExt; 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 { for path in XEN_BUS_PATHS { @@ -19,8 +19,46 @@ fn find_bus_path() -> Option { 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 { + 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 { - handle: UnixStream, + handle: Box, } #[derive(Debug)] @@ -60,8 +98,19 @@ impl XsdSocket { Some(path) => path, 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 { @@ -71,13 +120,16 @@ impl XsdSocket { tx, len: buf.len() as u32, }; - self.handle.write_all(bytemuck::bytes_of(&header))?; - self.handle.write_all(buf)?; + let header_bytes = bytemuck::bytes_of(&header); + let mut composed: Vec = 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::()]; - 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::(&result_buf); 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 { let error = CString::from_vec_with_nul(payload)?; return Err(Error::ResponseError(error.into_string()?)); @@ -101,9 +153,3 @@ impl XsdSocket { self.send(tx, typ, buf.as_slice()) } } - -impl Drop for XsdSocket { - fn drop(&mut self) { - self.handle.shutdown(Shutdown::Both).unwrap() - } -}