vhost_user_*: Create a vhost::Listener in advance

Changes is vhost crate require VhostUserDaemon users to create and
provide a vhost::Listener in advance. This allows us to adopt
sandboxing strategies in the future, by being able to create the UNIX
socket before switching to a restricted namespace.

Update also the reference to vhost crate in Cargo.lock to point to the
latest commit from the dragonball branch.

Signed-off-by: Sergio Lopez <slp@redhat.com>
This commit is contained in:
Sergio Lopez 2020-04-24 13:33:00 +02:00 committed by Sebastien Boeuf
parent fa844865a5
commit c4bf383fd7
5 changed files with 23 additions and 30 deletions

2
Cargo.lock generated
View File

@ -1368,7 +1368,7 @@ dependencies = [
[[package]] [[package]]
name = "vhost" name = "vhost"
version = "0.1.0" version = "0.1.0"
source = "git+https://github.com/cloud-hypervisor/vhost?branch=dragonball#d756e08224973cae7d9191e80adaa59b1101b35a" source = "git+https://github.com/cloud-hypervisor/vhost?branch=dragonball#3e80cf531d278aeb7f947335a4eeca655e0f2c54"
dependencies = [ dependencies = [
"bitflags 1.2.1", "bitflags 1.2.1",
"libc", "libc",

View File

@ -19,7 +19,7 @@ use std::sync::{Arc, Mutex, RwLock};
use std::{convert, error, fmt, io, process}; use std::{convert, error, fmt, io, process};
use vhost_rs::vhost_user::message::*; use vhost_rs::vhost_user::message::*;
use vhost_rs::vhost_user::SlaveFsCacheReq; use vhost_rs::vhost_user::{Listener, SlaveFsCacheReq};
use vhost_user_backend::{VhostUserBackend, VhostUserDaemon, Vring}; use vhost_user_backend::{VhostUserBackend, VhostUserDaemon, Vring};
use vhost_user_fs::descriptor_utils::Error as VufDescriptorError; use vhost_user_fs::descriptor_utils::Error as VufDescriptorError;
use vhost_user_fs::descriptor_utils::{Reader, Writer}; use vhost_user_fs::descriptor_utils::{Reader, Writer};
@ -325,8 +325,7 @@ fn main() {
}; };
let xattr: bool = !cmd_arguments.is_present("disable-xattr"); let xattr: bool = !cmd_arguments.is_present("disable-xattr");
// Convert into appropriate types let listener = Listener::new(sock, true).unwrap();
let sock = String::from(sock);
let fs_cfg = passthrough::Config { let fs_cfg = passthrough::Config {
root_dir: shared_dir.to_string(), root_dir: shared_dir.to_string(),
@ -338,14 +337,10 @@ fn main() {
VhostUserFsBackend::new(fs, thread_pool_size).unwrap(), VhostUserFsBackend::new(fs, thread_pool_size).unwrap(),
)); ));
let mut daemon = VhostUserDaemon::new( let mut daemon =
String::from("vhost-user-fs-backend"), VhostUserDaemon::new(String::from("vhost-user-fs-backend"), fs_backend.clone()).unwrap();
sock,
fs_backend.clone(),
)
.unwrap();
if let Err(e) = daemon.start() { if let Err(e) = daemon.start(listener) {
error!("Failed to start daemon: {:?}", e); error!("Failed to start daemon: {:?}", e);
process::exit(1); process::exit(1);
} }

View File

@ -20,7 +20,7 @@ use vhost_rs::vhost_user::message::{
VhostUserVirtioFeatures, VhostUserVringAddrFlags, VhostUserVringState, VhostUserVirtioFeatures, VhostUserVringAddrFlags, VhostUserVringState,
}; };
use vhost_rs::vhost_user::{ use vhost_rs::vhost_user::{
Error as VhostUserError, Result as VhostUserResult, SlaveFsCacheReq, SlaveListener, Error as VhostUserError, Listener, Result as VhostUserResult, SlaveFsCacheReq, SlaveListener,
VhostUserSlaveReqHandler, VhostUserSlaveReqHandler,
}; };
use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX; use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
@ -124,7 +124,6 @@ pub trait VhostUserBackend: Send + Sync + 'static {
/// in order to run a fully functional vhost-user daemon. /// in order to run a fully functional vhost-user daemon.
pub struct VhostUserDaemon<S: VhostUserBackend> { pub struct VhostUserDaemon<S: VhostUserBackend> {
name: String, name: String,
sock_path: String,
handler: Arc<Mutex<VhostUserHandler<S>>>, handler: Arc<Mutex<VhostUserHandler<S>>>,
main_thread: Option<thread::JoinHandle<Result<()>>>, main_thread: Option<thread::JoinHandle<Result<()>>>,
} }
@ -136,14 +135,13 @@ impl<S: VhostUserBackend> VhostUserDaemon<S> {
/// listening onto registered event. Those events can be vring events or /// listening onto registered event. Those events can be vring events or
/// custom events from the backend, but they get to be registered later /// custom events from the backend, but they get to be registered later
/// during the sequence. /// during the sequence.
pub fn new(name: String, sock_path: String, backend: Arc<RwLock<S>>) -> Result<Self> { pub fn new(name: String, backend: Arc<RwLock<S>>) -> Result<Self> {
let handler = Arc::new(Mutex::new( let handler = Arc::new(Mutex::new(
VhostUserHandler::new(backend).map_err(Error::NewVhostUserHandler)?, VhostUserHandler::new(backend).map_err(Error::NewVhostUserHandler)?,
)); ));
Ok(VhostUserDaemon { Ok(VhostUserDaemon {
name, name,
sock_path,
handler, handler,
main_thread: None, main_thread: None,
}) })
@ -153,9 +151,8 @@ impl<S: VhostUserBackend> VhostUserDaemon<S> {
/// all requests coming through this socket. This runs in an infinite loop /// all requests coming through this socket. This runs in an infinite loop
/// that should be terminating once the other end of the socket (the VMM) /// that should be terminating once the other end of the socket (the VMM)
/// disconnects. /// disconnects.
pub fn start(&mut self) -> Result<()> { pub fn start(&mut self, listener: Listener) -> Result<()> {
let mut slave_listener = let mut slave_listener = SlaveListener::new(listener, self.handler.clone())
SlaveListener::new(self.sock_path.as_str(), true, self.handler.clone())
.map_err(Error::CreateSlaveListener)?; .map_err(Error::CreateSlaveListener)?;
let mut slave_handler = slave_listener let mut slave_handler = slave_listener
.accept() .accept()

View File

@ -33,6 +33,7 @@ use std::time::Instant;
use std::vec::Vec; use std::vec::Vec;
use std::{convert, error, fmt, io}; use std::{convert, error, fmt, io};
use vhost_rs::vhost_user::message::*; use vhost_rs::vhost_user::message::*;
use vhost_rs::vhost_user::Listener;
use vhost_user_backend::{VhostUserBackend, VhostUserDaemon, Vring}; use vhost_user_backend::{VhostUserBackend, VhostUserDaemon, Vring};
use virtio_bindings::bindings::virtio_blk::*; use virtio_bindings::bindings::virtio_blk::*;
use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX; use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
@ -452,12 +453,14 @@ pub fn start_block_backend(backend_command: &str) {
debug!("blk_backend is created!\n"); debug!("blk_backend is created!\n");
let listener = Listener::new(&backend_config.socket, true).unwrap();
let name = "vhost-user-blk-backend"; let name = "vhost-user-blk-backend";
let mut blk_daemon = let mut blk_daemon = VhostUserDaemon::new(name.to_string(), blk_backend.clone()).unwrap();
VhostUserDaemon::new(name.to_string(), backend_config.socket, blk_backend.clone()).unwrap();
debug!("blk_daemon is created!\n"); debug!("blk_daemon is created!\n");
if let Err(e) = blk_daemon.start() { if let Err(e) = blk_daemon.start(listener) {
error!( error!(
"Failed to start daemon for vhost-user-block with error: {:?}\n", "Failed to start daemon for vhost-user-block with error: {:?}\n",
e e

View File

@ -26,7 +26,7 @@ use std::process;
use std::sync::{Arc, Mutex, RwLock}; use std::sync::{Arc, Mutex, RwLock};
use std::vec::Vec; use std::vec::Vec;
use vhost_rs::vhost_user::message::*; use vhost_rs::vhost_user::message::*;
use vhost_rs::vhost_user::Error as VhostUserError; use vhost_rs::vhost_user::{Error as VhostUserError, Listener};
use vhost_user_backend::{VhostUserBackend, VhostUserDaemon, Vring, VringWorker}; use vhost_user_backend::{VhostUserBackend, VhostUserDaemon, Vring, VringWorker};
use virtio_bindings::bindings::virtio_net::*; use virtio_bindings::bindings::virtio_net::*;
use vm_memory::GuestMemoryMmap; use vm_memory::GuestMemoryMmap;
@ -428,12 +428,10 @@ pub fn start_net_backend(backend_command: &str) {
.unwrap(), .unwrap(),
)); ));
let mut net_daemon = VhostUserDaemon::new( let listener = Listener::new(&backend_config.socket, true).unwrap();
"vhost-user-net-backend".to_string(),
backend_config.socket.to_string(), let mut net_daemon =
net_backend.clone(), VhostUserDaemon::new("vhost-user-net-backend".to_string(), net_backend.clone()).unwrap();
)
.unwrap();
let mut vring_workers = net_daemon.get_vring_workers(); let mut vring_workers = net_daemon.get_vring_workers();
@ -449,7 +447,7 @@ pub fn start_net_backend(backend_command: &str) {
.set_vring_worker(Some(vring_workers.remove(0))); .set_vring_worker(Some(vring_workers.remove(0)));
} }
if let Err(e) = net_daemon.start() { if let Err(e) = net_daemon.start(listener) {
error!( error!(
"failed to start daemon for vhost-user-net with error: {:?}", "failed to start daemon for vhost-user-net with error: {:?}",
e e