diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 270488d08..ebd2f4ae1 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -10,6 +10,7 @@ extern crate vmm_sys_util; use libc::EFD_NONBLOCK; use std::fmt::{self, Display}; use std::io; +use std::os::unix::io::{AsRawFd, RawFd}; use std::result; use std::sync::Arc; use vmm_sys_util::eventfd::EventFd; @@ -52,6 +53,74 @@ impl Display for Error { } } +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum EpollDispatch { + Exit, + Reset, + Stdin, + Api, +} + +pub struct EpollContext { + raw_fd: RawFd, + dispatch_table: Vec>, +} + +impl EpollContext { + pub fn new() -> result::Result { + let raw_fd = epoll::create(true)?; + + // Initial capacity needs to be large enough to hold: + // * 1 exit event + // * 1 reset event + // * 1 stdin event + // * 1 API event + let mut dispatch_table = Vec::with_capacity(5); + dispatch_table.push(None); + + Ok(EpollContext { + raw_fd, + dispatch_table, + }) + } + + pub fn add_stdin(&mut self) -> result::Result<(), io::Error> { + let dispatch_index = self.dispatch_table.len() as u64; + epoll::ctl( + self.raw_fd, + epoll::ControlOptions::EPOLL_CTL_ADD, + libc::STDIN_FILENO, + epoll::Event::new(epoll::Events::EPOLLIN, dispatch_index), + )?; + + self.dispatch_table.push(Some(EpollDispatch::Stdin)); + + Ok(()) + } + + fn add_event(&mut self, fd: &T, token: EpollDispatch) -> result::Result<(), io::Error> + where + T: AsRawFd, + { + let dispatch_index = self.dispatch_table.len() as u64; + epoll::ctl( + self.raw_fd, + epoll::ControlOptions::EPOLL_CTL_ADD, + fd.as_raw_fd(), + epoll::Event::new(epoll::Events::EPOLLIN, dispatch_index), + )?; + self.dispatch_table.push(Some(token)); + + Ok(()) + } +} + +impl AsRawFd for EpollContext { + fn as_raw_fd(&self) -> RawFd { + self.raw_fd + } +} + pub fn start_vm_loop(config: Arc) -> Result<()> { let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFd)?; let reset_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFd)?; diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index b7af3dd52..78a107edc 100755 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -25,6 +25,7 @@ extern crate vm_virtio; use crate::config::{ConsoleOutputMode, VmConfig}; use crate::device_manager::{get_win_size, Console, DeviceManager, DeviceManagerError}; +use crate::{EpollContext, EpollDispatch}; use arch::RegionType; use devices::ioapic; use kvm_bindings::{ @@ -39,7 +40,7 @@ use std::ffi::CString; use std::fs::{File, OpenOptions}; use std::io; use std::ops::Deref; -use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; +use std::os::unix::io::{AsRawFd, FromRawFd}; use std::os::unix::thread::JoinHandleExt; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::{Arc, Barrier, Mutex, RwLock}; @@ -430,71 +431,6 @@ pub struct VmInfo<'a> { pub vm_cfg: &'a VmConfig, } -#[derive(Debug, Clone, Copy, PartialEq)] -enum EpollDispatch { - Exit, - Reset, - Stdin, -} - -pub struct EpollContext { - raw_fd: RawFd, - dispatch_table: Vec>, -} - -impl EpollContext { - pub fn new() -> result::Result { - let raw_fd = epoll::create(true)?; - - // Initial capacity needs to be large enough to hold: - // * 1 exit event - // * 1 stdin event - let mut dispatch_table = Vec::with_capacity(4); - dispatch_table.push(None); - - Ok(EpollContext { - raw_fd, - dispatch_table, - }) - } - - pub fn add_stdin(&mut self) -> result::Result<(), io::Error> { - let dispatch_index = self.dispatch_table.len() as u64; - epoll::ctl( - self.raw_fd, - epoll::ControlOptions::EPOLL_CTL_ADD, - libc::STDIN_FILENO, - epoll::Event::new(epoll::Events::EPOLLIN, dispatch_index), - )?; - - self.dispatch_table.push(Some(EpollDispatch::Stdin)); - - Ok(()) - } - - fn add_event(&mut self, fd: &T, token: EpollDispatch) -> result::Result<(), io::Error> - where - T: AsRawFd, - { - let dispatch_index = self.dispatch_table.len() as u64; - epoll::ctl( - self.raw_fd, - epoll::ControlOptions::EPOLL_CTL_ADD, - fd.as_raw_fd(), - epoll::Event::new(epoll::Events::EPOLLIN, dispatch_index), - )?; - self.dispatch_table.push(Some(token)); - - Ok(()) - } -} - -impl AsRawFd for EpollContext { - fn as_raw_fd(&self) -> RawFd { - self.raw_fd - } -} - #[derive(PartialEq)] pub enum ExitBehaviour { Shutdown = 1, @@ -886,6 +822,7 @@ impl Vm { break 'outer; } EpollDispatch::Stdin => self.handle_stdin()?, + EpollDispatch::Api => {} } } }