vmm: Create vsock backend

This commit relies on the new vsock::unix module to create the backend
that will be used from the virtio-vsock device.

The concept of backend is interesting here as it would allow for a vhost
kernel backend to be plugged if that was needed someday.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2019-09-04 14:19:16 -07:00
parent 434a5d0edf
commit 475e487ac3
5 changed files with 41 additions and 9 deletions

View File

@ -27,7 +27,7 @@ pub mod net;
mod pmem;
mod queue;
mod rng;
mod vsock;
pub mod vsock;
pub mod transport;
pub mod vhost_user;
@ -49,6 +49,7 @@ const DEVICE_FEATURES_OK: u32 = 0x08;
const DEVICE_FAILED: u32 = 0x80;
const VIRTIO_F_VERSION_1: u32 = 32;
const VIRTIO_F_IN_ORDER: u32 = 35;
// Types taken from linux/virtio_ids.h
#[derive(Copy, Clone)]

View File

@ -36,11 +36,12 @@ use std::result;
use std::sync::{Arc, RwLock};
use std::thread;
use super::VsockBackend;
use crate::Error as DeviceError;
use crate::VirtioInterrupt;
use crate::{
ActivateError, ActivateResult, DeviceEventT, Queue, VirtioDevice, VirtioDeviceType,
VIRTIO_F_VERSION_1,
VIRTIO_F_IN_ORDER, VIRTIO_F_VERSION_1,
};
use byteorder::{ByteOrder, LittleEndian};
use vm_memory::GuestMemoryMmap;
@ -167,19 +168,26 @@ impl VsockEpollHandler {
}
/// Virtio device exposing virtual socket to the guest.
pub struct Vsock {
pub struct Vsock<B: VsockBackend> {
cid: u64,
_backend: Option<B>,
kill_evt: Option<EventFd>,
avail_features: u64,
acked_features: u64,
}
impl Vsock {
pub fn new(cid: u64) -> io::Result<Vsock> {
let avail_features = 1u64 << VIRTIO_F_VERSION_1;
impl<B> Vsock<B>
where
B: VsockBackend,
{
/// Create a new virtio-vsock device with the given VM CID and vsock
/// backend.
pub fn new(cid: u64, backend: B) -> io::Result<Vsock<B>> {
let avail_features = 1u64 << VIRTIO_F_VERSION_1 | 1u64 << VIRTIO_F_IN_ORDER;
Ok(Vsock {
cid,
_backend: Some(backend),
kill_evt: None,
avail_features,
acked_features: 0u64,
@ -187,7 +195,10 @@ impl Vsock {
}
}
impl Drop for Vsock {
impl<B> Drop for Vsock<B>
where
B: VsockBackend,
{
fn drop(&mut self) {
if let Some(kill_evt) = self.kill_evt.take() {
// Ignore the result because there is nothing we can do about it.
@ -196,7 +207,10 @@ impl Drop for Vsock {
}
}
impl VirtioDevice for Vsock {
impl<B> VirtioDevice for Vsock<B>
where
B: VsockBackend,
{
fn device_type(&self) -> u32 {
VirtioDeviceType::TYPE_VSOCK as u32
}

View File

@ -14,6 +14,8 @@ mod packet;
mod unix;
pub use self::device::Vsock;
pub use self::unix::VsockUnixBackend;
pub use self::unix::VsockUnixError;
use std::os::unix::io::RawFd;

View File

@ -13,6 +13,7 @@ mod muxer_killq;
mod muxer_rxq;
pub use muxer::VsockMuxer as VsockUnixBackend;
pub use Error as VsockUnixError;
mod defs {
/// Maximum number of established connections that we can handle.

View File

@ -76,6 +76,12 @@ pub enum DeviceManagerError {
/// Cannot create virtio-vsock device
CreateVirtioVsock(io::Error),
/// Failed converting Path to &str for the virtio-vsock device.
CreateVsockConvertPath,
/// Cannot create virtio-vsock backend
CreateVsockBackend(vm_virtio::vsock::VsockUnixError),
/// Failed parsing disk image format
DetectImageType(qcow::Error),
@ -801,7 +807,15 @@ impl DeviceManager {
// Add vsock if required
if let Some(vsock_list_cfg) = &vm_info.vm_cfg.vsock {
for vsock_cfg in vsock_list_cfg.iter() {
let vsock_device = vm_virtio::Vsock::new(vsock_cfg.cid)
let socket_path = vsock_cfg
.sock
.to_str()
.ok_or(DeviceManagerError::CreateVsockConvertPath)?;
let backend =
vm_virtio::vsock::VsockUnixBackend::new(vsock_cfg.cid, socket_path.to_string())
.map_err(DeviceManagerError::CreateVsockBackend)?;
let vsock_device = vm_virtio::Vsock::new(vsock_cfg.cid, backend)
.map_err(DeviceManagerError::CreateVirtioVsock)?;
DeviceManager::add_virtio_pci_device(