mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-22 19:32:20 +00:00
vmm: Move the EpollContext implementation to lib
The VMM thread and control loop will be the sole consumer of the EpollContext and EpollDispatch API, so let's move it to lib.rs. Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
parent
03ab6839c1
commit
4671a5831f
@ -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<Option<EpollDispatch>>,
|
||||
}
|
||||
|
||||
impl EpollContext {
|
||||
pub fn new() -> result::Result<EpollContext, io::Error> {
|
||||
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<T>(&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<VmConfig>) -> Result<()> {
|
||||
let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFd)?;
|
||||
let reset_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFd)?;
|
||||
|
@ -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<Option<EpollDispatch>>,
|
||||
}
|
||||
|
||||
impl EpollContext {
|
||||
pub fn new() -> result::Result<EpollContext, io::Error> {
|
||||
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<T>(&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 => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user