1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
use std::os::unix::io::RawFd; use std::result::Result as StdResult; use nix; use super::{sys, Core, ErrorKind, Result, ResultExt, CheckCapability, Capability}; #[derive(Debug)] pub struct Machine(pub(super) RawFd); fn chain_then(res: StdResult<i32, nix::Error>) -> Result<()> { res .chain_err(|| ErrorKind::KvmMachineOperationError) .and_then(|v| if v == 0 { Ok(())} else { Err(ErrorKind::KvmMachineOperationError.into())} ) } impl Machine { pub fn create_core(&mut self, id: i32) -> Result<Core> { unsafe { sys::kvm_create_vcpu(self.0, id).map(|v| Core(v)) } .chain_err(|| ErrorKind::KvmMachineOperationError) } pub fn create_irq(&mut self) -> Result<()> { chain_then(unsafe { sys::kvm_create_irqchip(self.0) }) } pub fn get_clock(&mut self, stable: bool) -> Result<u64> { unsafe { let flags = if stable { sys::KVM_CLOCK_TSC_STABLE } else { 0 }; let mut clock = sys::ClockData { clock: 0, flags: flags, _pad: [0; 9] }; chain_then(sys::kvm_get_clock(self.0, &mut clock as *mut sys::ClockData))?; Ok(clock.clock) } } pub fn set_clock(&mut self, clock: u64) -> Result<()> { unsafe { let clock = sys::ClockData { clock: clock, flags: 0, _pad: [0; 9] }; chain_then(sys::kvm_set_clock(self.0, &clock as *const sys::ClockData)) } } } impl Drop for Machine { fn drop(&mut self) { nix::unistd::close(self.0).unwrap() } } impl CheckCapability for Machine { fn check_capability(&mut self, cap: Capability) -> Result<i32> { unsafe { sys::kvm_check_extension(self.0, cap.into()) } .chain_err(|| ErrorKind::KvmCapabilityCheckError) } } unsafe impl Send for Machine {}