Skip to content

Commit

Permalink
Merge pull request #3 from tathanhdinh/error_support_wip
Browse files Browse the repository at this point in the history
error handling
  • Loading branch information
Wenzel committed Jul 7, 2019
2 parents 43c50e1 + c5add66 commit bbb8b2f
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 58 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Expand Up @@ -10,4 +10,4 @@ description = "Rust bindings for Xen's xenctrl library"
license = "GPL-3.0-only"

[dependencies]
xenctrl-sys = { git = "https://github.com/Wenzel/xenctrl-sys" }
xenctrl-sys = { git = "https://github.com/Wenzel/xenctrl-sys.git" }
6 changes: 6 additions & 0 deletions rustfmt.toml
@@ -0,0 +1,6 @@
edition = "2018"
indent_style = "block"
format_strings = true
merge_imports = true
reorder_imports = true
wrap_comments = true
10 changes: 10 additions & 0 deletions src/consts.rs
@@ -0,0 +1,10 @@
pub const PAGE_SHIFT: u32 = xenctrl_sys::XC_PAGE_SHIFT;
pub const PAGE_SIZE: u32 = xenctrl_sys::XC_PAGE_SIZE;
pub const PAGE_MASK: i32 = xenctrl_sys::XC_PAGE_MASK;

pub const CORE_MAGIC: u32 = xenctrl_sys::XC_CORE_MAGIC;
pub const CORE_MAGIC_HVM: u32 = xenctrl_sys::XC_CORE_MAGIC_HVM;

pub const CPUPOOL_POOLID_ANY: u32 = xenctrl_sys::XC_CPUPOOL_POOLID_ANY;

pub const MAX_ERROR_MSG_LEN: u32 = xenctrl_sys::XC_MAX_ERROR_MSG_LEN;
38 changes: 38 additions & 0 deletions src/error.rs
@@ -0,0 +1,38 @@
use std::{
error, ffi,
fmt::{self, Debug, Display, Formatter},
};

use xenctrl_sys::{xc_error_code, xc_error_code_to_desc};

#[derive(Copy, Clone)]
pub struct Error(xc_error_code);

impl Error {
pub fn new(code: xc_error_code) -> Self {
Self(code)
}

pub fn desc(self) -> &'static str {
unsafe {
let desc = xc_error_code_to_desc(self.0 as _);
ffi::CStr::from_ptr(desc).to_str().unwrap()
}
}
}

impl Display for Error {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.desc())
}
}

impl Debug for Error {
#[inline]
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.desc())
}
}

impl error::Error for Error {}
141 changes: 84 additions & 57 deletions src/lib.rs
@@ -1,90 +1,117 @@
pub mod error;
pub mod support;
pub mod consts;

#[macro_use]
mod macros;

extern crate xenctrl_sys;
use std::io::Error;
use std::ptr::{null_mut};
use std::os::raw::{c_void, c_ulong};
use std::{
mem,
ptr::{null_mut, NonNull},
};

use xenctrl_sys::{
xc_clear_last_error, xc_domain_maximum_gpfn, xc_domain_pause, xc_domain_unpause, xc_error_code,
xc_get_last_error, xc_interface, xc_interface_close, xc_interface_open, xc_monitor_disable,
xc_monitor_enable, xentoollog_logger,
};

pub const PAGE_SHIFT: u32 = xenctrl_sys::XC_PAGE_SHIFT;
pub const PAGE_SIZE: u32 = xenctrl_sys::XC_PAGE_SIZE;
use error::Error;
use support::PageInfo;

type Result<T> = std::result::Result<T, Error>;

#[derive(Debug)]
pub struct Xc {
handle: *mut xenctrl_sys::xc_interface,
evtchn_port: *mut u32,
pub struct XenControl {
handle: NonNull<xc_interface>,
evtchn_port: u32,
}

impl Xc {

pub fn new() -> Result<Self,Error> {
impl XenControl {
pub fn new(
logger: Option<&mut xentoollog_logger>,
dombuild_logger: Option<&mut xentoollog_logger>,
open_flags: u32,
) -> Result<Self> {
let xc_handle = unsafe {
xenctrl_sys::xc_interface_open(null_mut(), null_mut(), 0)
xc_interface_open(
logger.map_or_else(|| null_mut(), |l| l as *mut _),
dombuild_logger.map_or_else(|| null_mut(), |l| l as *mut _),
open_flags,
)
};
if xc_handle == null_mut() {
return Err(Error::last_os_error());
}
Ok(Xc {
handle: xc_handle,
evtchn_port: null_mut()
})

NonNull::new(xc_handle)
.ok_or_else(|| Error::new(xc_error_code::XC_INTERNAL_ERROR))
.map(|handle| XenControl {
handle,
evtchn_port: 0u32,
})
}

pub fn monitor_enable(&self, domid: u32) -> *mut c_void {
unsafe {
xenctrl_sys::xc_monitor_enable(self.handle, domid, self.evtchn_port)
}
pub fn default() -> Result<Self> {
Self::new(None, None, 0)
}

pub fn monitor_disable(&self, domid: u32) {
pub fn monitor_enable(&mut self, domid: u32) -> Result<&PageInfo> {
let xc = self.handle.as_ptr();
let ring_page = unsafe {
xc_clear_last_error(xc);
xc_monitor_enable(xc, domid, &mut self.evtchn_port as _) as *const PageInfo
};
last_error!(xc, &*ring_page)
}

pub fn monitor_disable(&self, domid: u32) -> Result<()> {
let xc = self.handle.as_ptr();
unsafe {
xenctrl_sys::xc_monitor_disable(self.handle, domid);
xc_clear_last_error(xc);
xc_monitor_disable(xc, domid);
};
last_error!(xc, ())
}

pub fn domain_pause(&self, domid: u32) -> Result<(),&str> {
pub fn domain_pause(&self, domid: u32) -> Result<()> {
let xc = self.handle.as_ptr();
unsafe {
match xenctrl_sys::xc_domain_pause(self.handle, domid) {
0 => Ok(()),
-1 => Err("Fail to pause domain"),
_ => panic!("unexpected value"),
}
}
xc_clear_last_error(xc);
xc_domain_pause(xc, domid);
};
last_error!(xc, ())
}

pub fn domain_unpause(&self, domid: u32) -> Result<(),&str> {
pub fn domain_unpause(&self, domid: u32) -> Result<()> {
let xc = self.handle.as_ptr();
unsafe {
match xenctrl_sys::xc_domain_unpause(self.handle, domid) {
0 => Ok(()),
-1 => Err("Fail to unpause domain"),
_ => panic!("unexpected value"),
}
xc_clear_last_error(xc);
xc_domain_unpause(xc, domid);
}
last_error!(xc, ())
}

pub fn domain_maximum_gpfn(&self, domid: u32) -> Result<u64,&str> {
let mut max_gpfn: c_ulong = 0;
let ptr_max_gpfn: *mut c_ulong = &mut max_gpfn;
let result = unsafe {
xenctrl_sys::xc_domain_maximum_gpfn(self.handle, domid, ptr_max_gpfn)
};
match result {
0 => Ok(max_gpfn as u64),
-1 => Err("Fail to get max gpfn"),
_ => panic!("unexpected value"),
pub fn domain_maximum_gpfn(&self, domid: u32) -> Result<u64> {
let xc = self.handle.as_ptr();
let mut max_gpfn: u64;
unsafe {
max_gpfn = mem::uninitialized();
xc_clear_last_error(xc);
xc_domain_maximum_gpfn(xc, domid, &mut max_gpfn as _);
}
last_error!(xc, max_gpfn)
}

fn close(&mut self) -> Result<(),&str>{
let result = unsafe {
xenctrl_sys::xc_interface_close(self.handle)
};
match result {
0 => Ok(()),
-1 => Err("Fail to close xc interface"),
_ => panic!("unexpected value"),
fn close(&mut self) -> Result<()> {
let xc = self.handle.as_ptr();
unsafe {
xc_clear_last_error(xc);
xc_interface_close(xc);
}
last_error!(xc, ())
}
}

impl Drop for Xc {
impl Drop for XenControl {
fn drop(&mut self) {
self.close().unwrap();
}
Expand Down
11 changes: 11 additions & 0 deletions src/macros.rs
@@ -0,0 +1,11 @@
macro_rules! last_error {
($xc:expr, $ok:expr) => {
unsafe {
let err = xc_get_last_error($xc);
match (*err).code {
xc_error_code::XC_ERROR_NONE => Ok($ok),
code => Err(Error::new(code)),
}
}
};
}
4 changes: 4 additions & 0 deletions src/support.rs
@@ -0,0 +1,4 @@
#[repr(C)]
pub struct PageInfo {
opaque: [u8; 0],
}

0 comments on commit bbb8b2f

Please sign in to comment.