diff --git a/.gitignore b/.gitignore index ea8c4bf..06f5fec 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ /target +/.idea +/.vscode diff --git a/crates/xen/xenplatform/src/boot.rs b/crates/xen/xenplatform/src/boot.rs index 58d184d..b766846 100644 --- a/crates/xen/xenplatform/src/boot.rs +++ b/crates/xen/xenplatform/src/boot.rs @@ -63,7 +63,7 @@ impl BootDomain { } let local_page_size: u32 = (1i64 << XEN_PAGE_SHIFT) as u32; - let pages = (size + local_page_size as u64 - 1) / local_page_size as u64; + let pages = size.div_ceil(local_page_size as u64); let start = self.virt_alloc_end; let mut segment = DomainSegment { diff --git a/crates/xen/xenstore/examples/list.rs b/crates/xen/xenstore/examples/list.rs index cd564d9..bbd6922 100644 --- a/crates/xen/xenstore/examples/list.rs +++ b/crates/xen/xenstore/examples/list.rs @@ -10,11 +10,12 @@ async fn list_recursive(client: &XsdClient, path: &str) -> Result<()> { let children = client.list(path).await?; for child in children { let full = format!("{}/{}", if path == "/" { "" } else { path }, child); - let value = client - .read_string(full.as_str()) - .await? - .expect("expected value"); - println!("{} = {:?}", full, value,); + let value = client.read(full.as_str()).await?.expect("expected value"); + let stringified = match String::from_utf8(value) { + Ok(string) => format!("\"{}\"", string), + Err(error) => format!("{:?}", error.into_bytes()), + }; + println!("{} = {}", full, stringified); pending.push(full); } } diff --git a/crates/xen/xenstore/src/error.rs b/crates/xen/xenstore/src/error.rs index 7bdb85a..4c1b86a 100644 --- a/crates/xen/xenstore/src/error.rs +++ b/crates/xen/xenstore/src/error.rs @@ -48,6 +48,13 @@ impl Error { _ => false, } } + + pub fn is_again_response(&self) -> bool { + match self { + Error::ResponseError(message) => message == "EAGAIN", + _ => false, + } + } } pub type Result = std::result::Result; diff --git a/crates/xen/xenstore/src/lib.rs b/crates/xen/xenstore/src/lib.rs index 5749110..95cd1d7 100644 --- a/crates/xen/xenstore/src/lib.rs +++ b/crates/xen/xenstore/src/lib.rs @@ -55,6 +55,27 @@ impl Drop for XsdWatchHandle { } } +pub struct XsdMultiWatchHandle { + pub paths: Vec, + pub id: u32, + unwatch_sender: Sender<(u32, String)>, + pub receiver: Receiver, +} + +impl XsdMultiWatchHandle { + pub fn add_path(&mut self, path: impl AsRef) { + self.paths.push(path.as_ref().to_string()); + } +} + +impl Drop for XsdMultiWatchHandle { + fn drop(&mut self) { + for path in &self.paths { + let _ = self.unwatch_sender.try_send((self.id, path.clone())); + } + } +} + #[allow(async_fn_in_trait)] pub trait XsdInterface { async fn list>(&self, path: P) -> Result>; @@ -141,7 +162,7 @@ impl XsdClient { } return Err(error); } - result.unwrap().parse_bool() + result?.parse_bool() } async fn set_perms>( @@ -197,6 +218,16 @@ impl XsdClient { response.parse_bool() } + pub async fn create_multi_watch(&self) -> Result { + let (id, receiver, unwatch_sender) = self.socket.add_watch().await?; + Ok(XsdMultiWatchHandle { + paths: vec![], + id, + receiver, + unwatch_sender, + }) + } + pub async fn create_watch>(&self, path: P) -> Result { let (id, receiver, unwatch_sender) = self.socket.add_watch().await?; Ok(XsdWatchHandle { @@ -319,6 +350,20 @@ impl XsdTransaction { .parse_bool() } + pub async fn maybe_commit(&self) -> Result { + match self.end(false).await { + Ok(result) => Ok(result), + + Err(error) => { + if error.is_again_response() { + Ok(false) + } else { + Err(error) + } + } + } + } + pub async fn commit(&self) -> Result { self.end(false).await }