virtio-devices: vhost_user: Factorize backend connection

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2021-06-01 16:48:58 +02:00
parent 6bce7f7937
commit 3e00247a47
3 changed files with 41 additions and 33 deletions

View File

@ -41,6 +41,8 @@ pub enum Error {
FailedSignalingUsedQueue(io::Error), FailedSignalingUsedQueue(io::Error),
/// Failed to read vhost eventfd. /// Failed to read vhost eventfd.
MemoryRegions(MmapError), MemoryRegions(MmapError),
/// Failed removing socket path
RemoveSocketPath(io::Error),
/// Failed to create master. /// Failed to create master.
VhostUserCreateMaster(VhostError), VhostUserCreateMaster(VhostError),
/// Failed to open vhost device. /// Failed to open vhost device.

View File

@ -6,8 +6,8 @@ use super::super::{
VirtioCommon, VirtioDevice, VirtioDeviceType, EPOLL_HELPER_EVENT_LAST, VirtioCommon, VirtioDevice, VirtioDeviceType, EPOLL_HELPER_EVENT_LAST,
}; };
use super::vu_common_ctrl::{ use super::vu_common_ctrl::{
add_memory_region, negotiate_features_vhost_user, reinitialize_vhost_user, reset_vhost_user, add_memory_region, connect_vhost_user, negotiate_features_vhost_user, reinitialize_vhost_user,
setup_vhost_user, update_mem_table, VhostUserConfig, reset_vhost_user, setup_vhost_user, update_mem_table, VhostUserConfig,
}; };
use super::{Error, Result}; use super::{Error, Result};
use crate::seccomp_filters::{get_seccomp_filter, Thread}; use crate::seccomp_filters::{get_seccomp_filter, Thread};
@ -16,7 +16,6 @@ use net_util::{build_net_config_space, CtrlQueue, MacAddr, VirtioNetConfig};
use seccomp::{SeccompAction, SeccompFilter}; use seccomp::{SeccompAction, SeccompFilter};
use std::ops::Deref; use std::ops::Deref;
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use std::os::unix::net::UnixListener;
use std::result; use std::result;
use std::sync::atomic::AtomicBool; use std::sync::atomic::AtomicBool;
use std::sync::{Arc, Barrier, Mutex}; use std::sync::{Arc, Barrier, Mutex};
@ -135,25 +134,18 @@ impl ReconnectEpollHandler {
epoll::Events::EPOLLHUP, epoll::Events::EPOLLHUP,
)?; )?;
let num_queues = self.queues.len() as u64; let mut vhost_user_net = connect_vhost_user(
self.server,
let mut vhost_user_net = if self.server { &self.socket_path,
std::fs::remove_file(&self.socket_path).map_err(EpollHelperError::IoError)?; self.queues.len() as u64,
info!("Binding vhost-user-net listener..."); true,
let listener = )
UnixListener::bind(&self.socket_path).map_err(EpollHelperError::IoError)?; .map_err(|e| {
info!("Waiting for incoming vhost-user-net connection..."); EpollHelperError::IoError(std::io::Error::new(
let (stream, _) = listener.accept().map_err(EpollHelperError::IoError)?; std::io::ErrorKind::Other,
format!("failed connecting vhost-user backend{:?}", e),
Master::from_stream(stream, num_queues) ))
} else { })?;
Master::connect(&self.socket_path, num_queues).map_err(|e| {
EpollHelperError::IoError(std::io::Error::new(
std::io::ErrorKind::Other,
format!("failed connecting vhost-user backend{:?}", e),
))
})?
};
// Initialize the backend // Initialize the backend
reinitialize_vhost_user( reinitialize_vhost_user(
@ -254,17 +246,8 @@ impl Net {
let mut config = VirtioNetConfig::default(); let mut config = VirtioNetConfig::default();
build_net_config_space(&mut config, mac_addr, num_queues, &mut avail_features); build_net_config_space(&mut config, mac_addr, num_queues, &mut avail_features);
let mut vhost_user_net = if server { let mut vhost_user_net =
info!("Binding vhost-user-net listener..."); connect_vhost_user(server, &vu_cfg.socket, num_queues as u64, false)?;
let listener = UnixListener::bind(&vu_cfg.socket).map_err(Error::BindSocket)?;
info!("Waiting for incoming vhost-user-net connection...");
let (stream, _) = listener.accept().map_err(Error::AcceptConnection)?;
Master::from_stream(stream, num_queues as u64)
} else {
Master::connect(&vu_cfg.socket, num_queues as u64)
.map_err(Error::VhostUserCreateMaster)?
};
let avail_protocol_features = VhostUserProtocolFeatures::MQ let avail_protocol_features = VhostUserProtocolFeatures::MQ
| VhostUserProtocolFeatures::CONFIGURE_MEM_SLOTS | VhostUserProtocolFeatures::CONFIGURE_MEM_SLOTS

View File

@ -6,6 +6,7 @@ use super::{Error, Result};
use crate::{get_host_address_range, VirtioInterrupt, VirtioInterruptType}; use crate::{get_host_address_range, VirtioInterrupt, VirtioInterruptType};
use std::convert::TryInto; use std::convert::TryInto;
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use std::os::unix::net::UnixListener;
use std::sync::Arc; use std::sync::Arc;
use std::vec::Vec; use std::vec::Vec;
use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures};
@ -204,3 +205,25 @@ pub fn reinitialize_vhost_user(
acked_features, acked_features,
) )
} }
pub fn connect_vhost_user(
server: bool,
socket_path: &str,
num_queues: u64,
unlink_socket: bool,
) -> Result<Master> {
Ok(if server {
if unlink_socket {
std::fs::remove_file(socket_path).map_err(Error::RemoveSocketPath)?;
}
info!("Binding vhost-user listener...");
let listener = UnixListener::bind(socket_path).map_err(Error::BindSocket)?;
info!("Waiting for incoming vhost-user connection...");
let (stream, _) = listener.accept().map_err(Error::AcceptConnection)?;
Master::from_stream(stream, num_queues)
} else {
Master::connect(socket_path, num_queues).map_err(Error::VhostUserConnect)?
})
}