mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-25 05:03:05 +00:00
vmm_vhost: turn Endpoint into a concrete type
Since VVU support was dropped, there is now only one Endpoint implementation (per platform) and so we can remove the related generics. Change-Id: Ica35a93dc43326ecb182e0ddeb80cba98f68fb2d Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/4844141 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
parent
0419cd9401
commit
4fa985cf0a
22 changed files with 199 additions and 218 deletions
|
@ -74,8 +74,6 @@ use vm_control::VmMemorySource;
|
|||
use vm_memory::GuestAddress;
|
||||
use vm_memory::GuestMemory;
|
||||
use vm_memory::MemoryRegion;
|
||||
use vmm_vhost::connection::Endpoint;
|
||||
use vmm_vhost::message::SlaveReq;
|
||||
use vmm_vhost::message::VhostSharedMemoryRegion;
|
||||
use vmm_vhost::message::VhostUserConfigFlags;
|
||||
use vmm_vhost::message::VhostUserGpuMapMsg;
|
||||
|
@ -88,9 +86,11 @@ use vmm_vhost::message::VhostUserShmemUnmapMsg;
|
|||
use vmm_vhost::message::VhostUserSingleMemoryRegion;
|
||||
use vmm_vhost::message::VhostUserVringAddrFlags;
|
||||
use vmm_vhost::message::VhostUserVringState;
|
||||
use vmm_vhost::Endpoint;
|
||||
use vmm_vhost::Error as VhostError;
|
||||
use vmm_vhost::Result as VhostResult;
|
||||
use vmm_vhost::Slave;
|
||||
use vmm_vhost::SlaveReq;
|
||||
use vmm_vhost::VhostUserMasterReqHandler;
|
||||
use vmm_vhost::VhostUserSlaveReqHandlerMut;
|
||||
use vmm_vhost::VHOST_USER_F_PROTOCOL_FEATURES;
|
||||
|
@ -666,7 +666,7 @@ impl VhostUserSlaveReqHandlerMut for DeviceRequestHandler {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn set_slave_req_fd(&mut self, ep: Box<dyn Endpoint<SlaveReq>>) {
|
||||
fn set_slave_req_fd(&mut self, ep: Endpoint<SlaveReq>) {
|
||||
let conn = VhostBackendReqConnection::new(
|
||||
Slave::new(ep),
|
||||
self.backend.get_shared_memory_region().map(|r| r.id),
|
||||
|
@ -963,7 +963,6 @@ mod tests {
|
|||
use anyhow::anyhow;
|
||||
use anyhow::bail;
|
||||
use base::Event;
|
||||
use vmm_vhost::message::MasterReq;
|
||||
use vmm_vhost::SlaveReqHandler;
|
||||
use vmm_vhost::VhostUserSlaveReqHandler;
|
||||
use zerocopy::AsBytes;
|
||||
|
@ -1177,8 +1176,8 @@ mod tests {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_request<S: VhostUserSlaveReqHandler, E: Endpoint<MasterReq>>(
|
||||
handler: &mut SlaveReqHandler<S, E>,
|
||||
fn handle_request<S: VhostUserSlaveReqHandler>(
|
||||
handler: &mut SlaveReqHandler<S>,
|
||||
) -> Result<(), VhostError> {
|
||||
let (hdr, files) = handler.recv_header()?;
|
||||
handler.process_message(hdr, files)
|
||||
|
|
|
@ -9,17 +9,14 @@ use base::AsRawDescriptor;
|
|||
use base::SafeDescriptor;
|
||||
use cros_async::AsyncWrapper;
|
||||
use cros_async::Executor;
|
||||
use vmm_vhost::connection::Endpoint;
|
||||
use vmm_vhost::message::MasterReq;
|
||||
use vmm_vhost::Error as VhostError;
|
||||
use vmm_vhost::SlaveReqHandler;
|
||||
use vmm_vhost::VhostUserSlaveReqHandler;
|
||||
|
||||
/// Performs the run loop for an already-constructor request handler.
|
||||
pub async fn run_handler<S, E>(mut req_handler: SlaveReqHandler<S, E>, ex: &Executor) -> Result<()>
|
||||
pub async fn run_handler<S>(mut req_handler: SlaveReqHandler<S>, ex: &Executor) -> Result<()>
|
||||
where
|
||||
S: VhostUserSlaveReqHandler,
|
||||
E: Endpoint<MasterReq> + AsRawDescriptor,
|
||||
{
|
||||
let h = SafeDescriptor::try_from(&req_handler as &dyn AsRawDescriptor)
|
||||
.map(AsyncWrapper::new)
|
||||
|
@ -60,9 +57,7 @@ pub mod test_helpers {
|
|||
use std::os::unix::net::UnixStream;
|
||||
|
||||
use tempfile::TempDir;
|
||||
use vmm_vhost::connection::socket::SocketEndpoint;
|
||||
use vmm_vhost::connection::Listener;
|
||||
use vmm_vhost::message::MasterReq;
|
||||
use vmm_vhost::SlaveReqHandler;
|
||||
use vmm_vhost::VhostUserSlaveReqHandler;
|
||||
|
||||
|
@ -87,7 +82,7 @@ pub mod test_helpers {
|
|||
pub(crate) fn listen<S: VhostUserSlaveReqHandler>(
|
||||
mut listener: vmm_vhost::connection::socket::Listener,
|
||||
handler: S,
|
||||
) -> SlaveReqHandler<S, SocketEndpoint<MasterReq>> {
|
||||
) -> SlaveReqHandler<S> {
|
||||
let endpoint = listener.accept().unwrap().unwrap();
|
||||
SlaveReqHandler::new(endpoint, handler)
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ pub mod test_helpers {
|
|||
pub(crate) fn listen<S: VhostUserSlaveReqHandler>(
|
||||
dev_tube: Tube,
|
||||
handler: S,
|
||||
) -> SlaveReqHandler<S, vmm_vhost::connection::TubeEndpoint<MasterReq>> {
|
||||
) -> SlaveReqHandler<S> {
|
||||
SlaveReqHandler::from_stream(dev_tube, handler)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,7 @@ use cros_async::Executor;
|
|||
use futures::Future;
|
||||
use futures::FutureExt;
|
||||
use vmm_vhost::connection::socket::Listener as SocketListener;
|
||||
use vmm_vhost::connection::Endpoint;
|
||||
use vmm_vhost::connection::Listener;
|
||||
use vmm_vhost::message::MasterReq;
|
||||
use vmm_vhost::SlaveReqHandler;
|
||||
use vmm_vhost::VhostUserSlaveReqHandler;
|
||||
|
||||
|
@ -52,7 +50,6 @@ async fn run_with_handler<L>(
|
|||
ex: &Executor,
|
||||
) -> anyhow::Result<()>
|
||||
where
|
||||
L::Endpoint: Endpoint<MasterReq> + AsRawDescriptor,
|
||||
L: Listener + AsRawDescriptor,
|
||||
{
|
||||
listener.set_nonblocking(true)?;
|
||||
|
|
|
@ -398,7 +398,7 @@ impl VhostUserSlaveReqHandlerMut for VsockBackend {
|
|||
Err(Error::InvalidOperation)
|
||||
}
|
||||
|
||||
fn set_slave_req_fd(&mut self, _vu_req: Box<dyn Endpoint<SlaveReq>>) {
|
||||
fn set_slave_req_fd(&mut self, _vu_req: Endpoint<SlaveReq>) {
|
||||
// We didn't set VhostUserProtocolFeatures::SLAVE_REQ
|
||||
unreachable!("unexpected set_slave_req_fd");
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ use vmm_vhost::message::VhostUserProtocolFeatures;
|
|||
use vmm_vhost::message::VhostUserShmemMapMsg;
|
||||
use vmm_vhost::message::VhostUserShmemUnmapMsg;
|
||||
use vmm_vhost::HandlerResult;
|
||||
use vmm_vhost::Master;
|
||||
use vmm_vhost::MasterReqHandler;
|
||||
use vmm_vhost::VhostUserMasterReqHandlerMut;
|
||||
use vmm_vhost::VhostUserMemoryRegionInfo;
|
||||
|
@ -31,7 +32,6 @@ use vmm_vhost::VringConfigData;
|
|||
use vmm_vhost::VHOST_USER_F_PROTOCOL_FEATURES;
|
||||
|
||||
use crate::virtio::vhost::user::vmm::handler::sys::create_backend_req_handler;
|
||||
use crate::virtio::vhost::user::vmm::handler::sys::SocketMaster;
|
||||
use crate::virtio::vhost::user::vmm::Connection;
|
||||
use crate::virtio::vhost::user::vmm::Error;
|
||||
use crate::virtio::vhost::user::vmm::Result;
|
||||
|
@ -43,7 +43,7 @@ use crate::virtio::SharedMemoryRegion;
|
|||
type BackendReqHandler = MasterReqHandler<Mutex<BackendReqHandlerImpl>>;
|
||||
|
||||
pub struct VhostUserHandler {
|
||||
vu: SocketMaster,
|
||||
vu: Master,
|
||||
pub avail_features: u64,
|
||||
acked_features: u64,
|
||||
protocol_features: VhostUserProtocolFeatures,
|
||||
|
@ -62,7 +62,7 @@ impl VhostUserHandler {
|
|||
#[cfg(windows)]
|
||||
let backend_pid = connection.target_pid();
|
||||
|
||||
let mut vu = SocketMaster::from_stream(connection);
|
||||
let mut vu = Master::from_stream(connection);
|
||||
|
||||
vu.set_owner().map_err(Error::SetOwner)?;
|
||||
|
||||
|
|
|
@ -13,10 +13,7 @@ use base::AsRawDescriptor;
|
|||
use base::SafeDescriptor;
|
||||
use cros_async::AsyncWrapper;
|
||||
use cros_async::Executor;
|
||||
use vmm_vhost::connection::socket::SocketEndpoint;
|
||||
use vmm_vhost::message::MasterReq;
|
||||
use vmm_vhost::Error as VhostError;
|
||||
use vmm_vhost::Master;
|
||||
use vmm_vhost::MasterReqHandler;
|
||||
|
||||
use crate::virtio::vhost::user::vmm::handler::BackendReqHandler;
|
||||
|
@ -24,9 +21,6 @@ use crate::virtio::vhost::user::vmm::handler::BackendReqHandlerImpl;
|
|||
use crate::virtio::vhost::user::vmm::Error;
|
||||
use crate::virtio::vhost::user::vmm::Result as VhostResult;
|
||||
|
||||
pub(in crate::virtio::vhost::user::vmm::handler) type SocketMaster =
|
||||
Master<SocketEndpoint<MasterReq>>;
|
||||
|
||||
pub fn create_backend_req_handler(h: BackendReqHandlerImpl) -> VhostResult<BackendReqHandler> {
|
||||
let handler = MasterReqHandler::with_stream(Arc::new(Mutex::new(h)))
|
||||
.map_err(Error::CreateBackendReqHandler)?;
|
||||
|
|
|
@ -27,11 +27,6 @@ use crate::virtio::vhost::user::vmm::handler::BackendReqHandlerImpl;
|
|||
use crate::virtio::vhost::user::vmm::Error;
|
||||
use crate::virtio::vhost::user::vmm::Result as VhostResult;
|
||||
|
||||
// TODO(rizhang): upstream CL so SocketMaster is renamed to EndpointMaster to make it more cross
|
||||
// platform.
|
||||
pub(in crate::virtio::vhost::user::vmm::handler) type SocketMaster =
|
||||
Master<TubeEndpoint<MasterReq>>;
|
||||
|
||||
pub fn create_backend_req_handler(
|
||||
h: BackendReqHandlerImpl,
|
||||
backend_pid: Option<u32>,
|
||||
|
|
150
third_party/vmm_vhost/src/connection.rs
vendored
150
third_party/vmm_vhost/src/connection.rs
vendored
|
@ -20,67 +20,32 @@ use std::io::IoSliceMut;
|
|||
use std::mem;
|
||||
use std::path::Path;
|
||||
|
||||
use base::AsRawDescriptor;
|
||||
use base::RawDescriptor;
|
||||
use zerocopy::AsBytes;
|
||||
use zerocopy::FromBytes;
|
||||
|
||||
use crate::connection::Req;
|
||||
use crate::message::MasterReq;
|
||||
use crate::message::SlaveReq;
|
||||
use crate::message::*;
|
||||
use crate::sys::PlatformEndpoint;
|
||||
use crate::Error;
|
||||
use crate::Result;
|
||||
use crate::SystemStream;
|
||||
|
||||
/// Listener for accepting connections.
|
||||
pub trait Listener: Sized {
|
||||
/// Type of an object created when a connection is accepted.
|
||||
type Connection;
|
||||
/// Type of endpoint created when a connection is accepted.
|
||||
type Endpoint;
|
||||
|
||||
/// Accept an incoming connection.
|
||||
fn accept(&mut self) -> Result<Option<Self::Endpoint>>;
|
||||
fn accept(&mut self) -> Result<Option<Endpoint<MasterReq>>>;
|
||||
|
||||
/// Change blocking status on the listener.
|
||||
fn set_nonblocking(&self, block: bool) -> Result<()>;
|
||||
}
|
||||
|
||||
/// Abstracts a vhost-user connection and related operations.
|
||||
pub trait Endpoint<R: Req>: Send {
|
||||
/// Create a new stream by connecting to server at `str`.
|
||||
fn connect<P: AsRef<Path>>(path: P) -> Result<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
/// Sends bytes from scatter-gather vectors with optional attached file descriptors.
|
||||
///
|
||||
/// # Return:
|
||||
/// * - number of bytes sent on success
|
||||
fn send_iovec(&mut self, iovs: &[IoSlice], fds: Option<&[RawDescriptor]>) -> Result<usize>;
|
||||
|
||||
/// Reads bytes into the given scatter/gather vectors with optional attached file.
|
||||
///
|
||||
/// # Arguements
|
||||
/// * `bufs` - A slice of buffers to store received data.
|
||||
/// * `allow_fd` - Indicates whether we can receive FDs.
|
||||
///
|
||||
/// # Return:
|
||||
/// * - (number of bytes received, [received files]) on success.
|
||||
/// * - `Error::Disconnect` if the client closed.
|
||||
fn recv_into_bufs(
|
||||
&mut self,
|
||||
bufs: &mut [IoSliceMut],
|
||||
allow_fd: bool,
|
||||
) -> Result<(usize, Option<Vec<File>>)>;
|
||||
|
||||
/// Constructs the slave request endpoint for self.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `files` - Files from which to create the endpoint
|
||||
fn create_slave_request_endpoint(
|
||||
&mut self,
|
||||
files: Option<Vec<File>>,
|
||||
) -> Result<Box<dyn Endpoint<SlaveReq>>>;
|
||||
}
|
||||
|
||||
// Advance the internal cursor of the slices.
|
||||
// This is same with a nightly API `IoSlice::advance_slices` but for `&[u8]`.
|
||||
fn advance_slices(bufs: &mut &mut [&[u8]], mut count: usize) {
|
||||
|
@ -121,8 +86,57 @@ fn advance_slices_mut(bufs: &mut &mut [&mut [u8]], mut count: usize) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Abstracts VVU message parsing, sending and receiving.
|
||||
pub trait EndpointExt<R: Req>: Endpoint<R> {
|
||||
/// A vhost-user connection and related operations.
|
||||
pub struct Endpoint<R: Req>(pub(crate) PlatformEndpoint<R>);
|
||||
|
||||
impl<R: Req> From<SystemStream> for Endpoint<R> {
|
||||
fn from(sock: SystemStream) -> Self {
|
||||
Self(PlatformEndpoint::from(sock))
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Req> Endpoint<R> {
|
||||
/// Create a new stream by connecting to server at `path`.
|
||||
pub fn connect<P: AsRef<Path>>(path: P) -> Result<Self> {
|
||||
PlatformEndpoint::connect(path).map(Self)
|
||||
}
|
||||
|
||||
/// Sends bytes from scatter-gather vectors with optional attached file descriptors.
|
||||
///
|
||||
/// # Return:
|
||||
/// * - number of bytes sent on success
|
||||
pub fn send_iovec(&mut self, iovs: &[IoSlice], fds: Option<&[RawDescriptor]>) -> Result<usize> {
|
||||
self.0.send_iovec(iovs, fds)
|
||||
}
|
||||
|
||||
/// Reads bytes into the given scatter/gather vectors with optional attached file.
|
||||
///
|
||||
/// # Arguements
|
||||
/// * `bufs` - A slice of buffers to store received data.
|
||||
/// * `allow_fd` - Indicates whether we can receive FDs.
|
||||
///
|
||||
/// # Return:
|
||||
/// * - (number of bytes received, [received files]) on success.
|
||||
/// * - `Error::Disconnect` if the client closed.
|
||||
pub fn recv_into_bufs(
|
||||
&mut self,
|
||||
bufs: &mut [IoSliceMut],
|
||||
allow_fd: bool,
|
||||
) -> Result<(usize, Option<Vec<File>>)> {
|
||||
self.0.recv_into_bufs(bufs, allow_fd)
|
||||
}
|
||||
|
||||
/// Constructs the slave request endpoint for self.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `files` - Files from which to create the endpoint
|
||||
pub fn create_slave_request_endpoint(
|
||||
&mut self,
|
||||
files: Option<Vec<File>>,
|
||||
) -> Result<super::Endpoint<SlaveReq>> {
|
||||
self.0.create_slave_request_endpoint(files)
|
||||
}
|
||||
|
||||
/// Sends all bytes from scatter-gather vectors with optional attached file descriptors. Will
|
||||
/// loop until all data has been transfered.
|
||||
///
|
||||
|
@ -134,7 +148,7 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
/// cursor needs to be moved by `advance_slices()`.
|
||||
/// Once `IoSlice::advance_slices()` becomes stable, this should be updated.
|
||||
/// <https://github.com/rust-lang/rust/issues/62726>.
|
||||
fn send_iovec_all(
|
||||
pub fn send_iovec_all(
|
||||
&mut self,
|
||||
mut iovs: &mut [&[u8]],
|
||||
mut fds: Option<&[RawDescriptor]>,
|
||||
|
@ -145,7 +159,7 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
let mut data_sent = 0;
|
||||
while !iovs.is_empty() {
|
||||
let iovec: Vec<_> = iovs.iter_mut().map(|i| IoSlice::new(i)).collect();
|
||||
match self.send_iovec(&iovec, fds) {
|
||||
match self.0.send_iovec(&iovec, fds) {
|
||||
Ok(0) => {
|
||||
break;
|
||||
}
|
||||
|
@ -168,8 +182,8 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
/// # Return:
|
||||
/// * - number of bytes sent on success
|
||||
#[cfg(test)]
|
||||
fn send_slice(&mut self, data: IoSlice, fds: Option<&[RawDescriptor]>) -> Result<usize> {
|
||||
self.send_iovec(&[data], fds)
|
||||
pub fn send_slice(&mut self, data: IoSlice, fds: Option<&[RawDescriptor]>) -> Result<usize> {
|
||||
self.0.send_iovec(&[data], fds)
|
||||
}
|
||||
|
||||
/// Sends a header-only message with optional attached file descriptors.
|
||||
|
@ -178,7 +192,7 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
/// * - number of bytes sent on success
|
||||
/// * - PartialMessage: received a partial message.
|
||||
/// * - backend specific errors
|
||||
fn send_header(
|
||||
pub fn send_header(
|
||||
&mut self,
|
||||
hdr: &VhostUserMsgHeader<R>,
|
||||
fds: Option<&[RawDescriptor]>,
|
||||
|
@ -199,7 +213,7 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
/// * - OversizedMsg: message size is too big.
|
||||
/// * - PartialMessage: received a partial message.
|
||||
/// * - backend specific errors
|
||||
fn send_message<T: Sized + AsBytes>(
|
||||
pub fn send_message<T: Sized + AsBytes>(
|
||||
&mut self,
|
||||
hdr: &VhostUserMsgHeader<R>,
|
||||
body: &T,
|
||||
|
@ -224,7 +238,7 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
/// * - PartialMessage: received a partial message.
|
||||
/// * - IncorrectFds: wrong number of attached fds.
|
||||
/// * - backend specific errors
|
||||
fn send_message_with_payload<T: Sized + AsBytes>(
|
||||
pub fn send_message_with_payload<T: Sized + AsBytes>(
|
||||
&mut self,
|
||||
hdr: &VhostUserMsgHeader<R>,
|
||||
body: &T,
|
||||
|
@ -257,10 +271,11 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
///
|
||||
/// # Return:
|
||||
/// * - (number of bytes received, buf) on success
|
||||
fn recv_data(&mut self, len: usize) -> Result<Vec<u8>> {
|
||||
pub fn recv_data(&mut self, len: usize) -> Result<Vec<u8>> {
|
||||
let mut buf = vec![0u8; len];
|
||||
let (data_len, _) =
|
||||
self.recv_into_bufs(&mut [IoSliceMut::new(&mut buf)], false /* allow_fd */)?;
|
||||
let (data_len, _) = self
|
||||
.0
|
||||
.recv_into_bufs(&mut [IoSliceMut::new(&mut buf)], false /* allow_fd */)?;
|
||||
buf.truncate(data_len);
|
||||
Ok(buf)
|
||||
}
|
||||
|
@ -277,7 +292,7 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
/// cursor needs to be moved by `advance_slices_mut()`.
|
||||
/// Once `IoSliceMut::advance_slices()` becomes stable, this should be updated.
|
||||
/// <https://github.com/rust-lang/rust/issues/62726>.
|
||||
fn recv_into_bufs_all(
|
||||
pub fn recv_into_bufs_all(
|
||||
&mut self,
|
||||
mut bufs: &mut [&mut [u8]],
|
||||
) -> Result<(usize, Option<Vec<File>>)> {
|
||||
|
@ -287,7 +302,7 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
|
||||
while (data_total - data_read) > 0 {
|
||||
let mut slices: Vec<IoSliceMut> = bufs.iter_mut().map(|b| IoSliceMut::new(b)).collect();
|
||||
let res = self.recv_into_bufs(&mut slices, true);
|
||||
let res = self.0.recv_into_bufs(&mut slices, true);
|
||||
match res {
|
||||
Ok((0, _)) => return Ok((data_read, rfds)),
|
||||
Ok((n, fds)) => {
|
||||
|
@ -313,10 +328,13 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
/// * - (number of bytes received, buf, [received files]) on success.
|
||||
/// * - backend specific errors
|
||||
#[cfg(test)]
|
||||
fn recv_into_buf(&mut self, buf_size: usize) -> Result<(usize, Vec<u8>, Option<Vec<File>>)> {
|
||||
pub fn recv_into_buf(
|
||||
&mut self,
|
||||
buf_size: usize,
|
||||
) -> Result<(usize, Vec<u8>, Option<Vec<File>>)> {
|
||||
let mut buf = vec![0u8; buf_size];
|
||||
let mut slices = [IoSliceMut::new(buf.as_mut_slice())];
|
||||
let (bytes, files) = self.recv_into_bufs(&mut slices, true /* allow_fd */)?;
|
||||
let (bytes, files) = self.0.recv_into_bufs(&mut slices, true /* allow_fd */)?;
|
||||
Ok((bytes, buf, files))
|
||||
}
|
||||
|
||||
|
@ -330,9 +348,9 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
/// * - PartialMessage: received a partial message.
|
||||
/// * - InvalidMessage: received a invalid message.
|
||||
/// * - backend specific errors
|
||||
fn recv_header(&mut self) -> Result<(VhostUserMsgHeader<R>, Option<Vec<File>>)> {
|
||||
pub fn recv_header(&mut self) -> Result<(VhostUserMsgHeader<R>, Option<Vec<File>>)> {
|
||||
let mut hdr = VhostUserMsgHeader::default();
|
||||
let (bytes, files) = self.recv_into_bufs(
|
||||
let (bytes, files) = self.0.recv_into_bufs(
|
||||
&mut [IoSliceMut::new(hdr.as_bytes_mut())],
|
||||
true, /* allow_fd */
|
||||
)?;
|
||||
|
@ -355,7 +373,7 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
/// * - PartialMessage: received a partial message.
|
||||
/// * - InvalidMessage: received a invalid message.
|
||||
/// * - backend specific errors
|
||||
fn recv_body<T: Sized + AsBytes + FromBytes + Default + VhostUserMsgValidator>(
|
||||
pub fn recv_body<T: Sized + AsBytes + FromBytes + Default + VhostUserMsgValidator>(
|
||||
&mut self,
|
||||
) -> Result<(VhostUserMsgHeader<R>, T, Option<Vec<File>>)> {
|
||||
let mut hdr = VhostUserMsgHeader::default();
|
||||
|
@ -386,7 +404,7 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
/// * - InvalidMessage: received a invalid message.
|
||||
/// * - backend specific errors
|
||||
#[cfg(test)]
|
||||
fn recv_body_into_buf(
|
||||
pub fn recv_body_into_buf(
|
||||
&mut self,
|
||||
buf: &mut [u8],
|
||||
) -> Result<(VhostUserMsgHeader<R>, usize, Option<Vec<File>>)> {
|
||||
|
@ -413,7 +431,9 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
/// * - InvalidMessage: received a invalid message.
|
||||
/// * - backend specific errors
|
||||
#[cfg_attr(feature = "cargo-clippy", allow(clippy::type_complexity))]
|
||||
fn recv_payload_into_buf<T: Sized + AsBytes + FromBytes + Default + VhostUserMsgValidator>(
|
||||
pub fn recv_payload_into_buf<
|
||||
T: Sized + AsBytes + FromBytes + Default + VhostUserMsgValidator,
|
||||
>(
|
||||
&mut self,
|
||||
) -> Result<(VhostUserMsgHeader<R>, T, Vec<u8>, Option<Vec<File>>)> {
|
||||
let mut hdr = VhostUserMsgHeader::default();
|
||||
|
@ -441,7 +461,11 @@ pub trait EndpointExt<R: Req>: Endpoint<R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<R: Req, E: Endpoint<R> + ?Sized> EndpointExt<R> for E {}
|
||||
impl<R: Req> AsRawDescriptor for Endpoint<R> {
|
||||
fn as_raw_descriptor(&self) -> RawDescriptor {
|
||||
self.0.as_raw_descriptor()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
|
|
14
third_party/vmm_vhost/src/connection/linux.rs
vendored
14
third_party/vmm_vhost/src/connection/linux.rs
vendored
|
@ -9,20 +9,18 @@ pub(crate) mod tests {
|
|||
use tempfile::TempDir;
|
||||
|
||||
use crate::connection::socket::Listener as SocketListener;
|
||||
use crate::connection::socket::SocketEndpoint;
|
||||
use crate::connection::Listener;
|
||||
use crate::master::Master;
|
||||
use crate::message::MasterReq;
|
||||
use crate::slave_req_handler::SlaveReqHandler;
|
||||
use crate::slave_req_handler::VhostUserSlaveReqHandler;
|
||||
use crate::Endpoint;
|
||||
|
||||
pub(crate) type TestMaster = Master<SocketEndpoint<MasterReq>>;
|
||||
pub(crate) type TestEndpoint = SocketEndpoint<MasterReq>;
|
||||
pub(crate) fn temp_dir() -> TempDir {
|
||||
Builder::new().prefix("/tmp/vhost_test").tempdir().unwrap()
|
||||
}
|
||||
|
||||
pub(crate) fn create_pair() -> (Master<SocketEndpoint<MasterReq>>, SocketEndpoint<MasterReq>) {
|
||||
pub(crate) fn create_pair() -> (Master, Endpoint<MasterReq>) {
|
||||
let dir = temp_dir();
|
||||
let mut path = dir.path().to_owned();
|
||||
path.push("sock");
|
||||
|
@ -34,9 +32,7 @@ pub(crate) mod tests {
|
|||
}
|
||||
|
||||
#[cfg(feature = "device")]
|
||||
pub(crate) fn create_master_slave_pair<S>(
|
||||
backend: S,
|
||||
) -> (TestMaster, SlaveReqHandler<S, TestEndpoint>)
|
||||
pub(crate) fn create_master_slave_pair<S>(backend: S) -> (Master, SlaveReqHandler<S>)
|
||||
where
|
||||
S: VhostUserSlaveReqHandler,
|
||||
{
|
||||
|
@ -59,13 +55,13 @@ pub(crate) mod tests {
|
|||
path.push("sock");
|
||||
let _ = SocketListener::new(&path, true).unwrap();
|
||||
let _ = SocketListener::new(&path, false).is_err();
|
||||
assert!(Master::<SocketEndpoint<_>>::connect(&path).is_err());
|
||||
assert!(Master::connect(&path).is_err());
|
||||
|
||||
let mut listener = SocketListener::new(&path, true).unwrap();
|
||||
assert!(SocketListener::new(&path, false).is_err());
|
||||
listener.set_nonblocking(true).unwrap();
|
||||
|
||||
let _master = Master::<SocketEndpoint<_>>::connect(&path).unwrap();
|
||||
let _master = Master::connect(&path).unwrap();
|
||||
let _slave = listener.accept().unwrap().unwrap();
|
||||
}
|
||||
}
|
||||
|
|
32
third_party/vmm_vhost/src/connection/socket.rs
vendored
32
third_party/vmm_vhost/src/connection/socket.rs
vendored
|
@ -18,12 +18,12 @@ use base::IntoRawDescriptor;
|
|||
use base::RawDescriptor;
|
||||
use base::ScmSocket;
|
||||
|
||||
use crate::connection::Endpoint as EndpointTrait;
|
||||
use crate::connection::Listener as ListenerTrait;
|
||||
use crate::connection::Req;
|
||||
use crate::linux::SystemListener;
|
||||
use crate::message::*;
|
||||
use crate::take_single_file;
|
||||
use crate::Endpoint;
|
||||
use crate::Error;
|
||||
use crate::Result;
|
||||
use crate::SystemStream;
|
||||
|
@ -73,7 +73,6 @@ impl Listener {
|
|||
|
||||
impl ListenerTrait for Listener {
|
||||
type Connection = SystemStream;
|
||||
type Endpoint = SocketEndpoint<MasterReq>;
|
||||
|
||||
/// Accept an incoming connection.
|
||||
///
|
||||
|
@ -81,14 +80,11 @@ impl ListenerTrait for Listener {
|
|||
/// * - Some(SystemListener): new SystemListener object if new incoming connection is available.
|
||||
/// * - None: no incoming connection available.
|
||||
/// * - SocketError: errors from accept().
|
||||
fn accept(&mut self) -> Result<Option<Self::Endpoint>> {
|
||||
fn accept(&mut self) -> Result<Option<Endpoint<MasterReq>>> {
|
||||
loop {
|
||||
match self.fd.accept() {
|
||||
Ok((stream, _addr)) => {
|
||||
return Ok(Some(SocketEndpoint {
|
||||
sock: stream.try_into()?,
|
||||
_r: PhantomData,
|
||||
}))
|
||||
return Ok(Some(Endpoint::from(stream)));
|
||||
}
|
||||
Err(e) => {
|
||||
match e.kind() {
|
||||
|
@ -127,6 +123,7 @@ pub struct SocketEndpoint<R: Req> {
|
|||
_r: PhantomData<R>,
|
||||
}
|
||||
|
||||
// TODO: Switch to TryFrom to avoid the unwrap.
|
||||
impl<R: Req> From<SystemStream> for SocketEndpoint<R> {
|
||||
fn from(sock: SystemStream) -> Self {
|
||||
Self {
|
||||
|
@ -136,13 +133,13 @@ impl<R: Req> From<SystemStream> for SocketEndpoint<R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<R: Req> EndpointTrait<R> for SocketEndpoint<R> {
|
||||
impl<R: Req> SocketEndpoint<R> {
|
||||
/// Create a new stream by connecting to server at `str`.
|
||||
///
|
||||
/// # Return:
|
||||
/// * - the new SocketEndpoint object on success.
|
||||
/// * - SocketConnect: failed to connect to peer.
|
||||
fn connect<P: AsRef<Path>>(path: P) -> Result<Self> {
|
||||
pub fn connect<P: AsRef<Path>>(path: P) -> Result<Self> {
|
||||
let sock = SystemStream::connect(path).map_err(Error::SocketConnect)?;
|
||||
Ok(Self::from(sock))
|
||||
}
|
||||
|
@ -155,7 +152,7 @@ impl<R: Req> EndpointTrait<R> for SocketEndpoint<R> {
|
|||
/// * - SocketRetry: temporary error caused by signals or short of resources.
|
||||
/// * - SocketBroken: the underline socket is broken.
|
||||
/// * - SocketError: other socket related errors.
|
||||
fn send_iovec(&mut self, iovs: &[IoSlice], fds: Option<&[RawDescriptor]>) -> Result<usize> {
|
||||
pub fn send_iovec(&mut self, iovs: &[IoSlice], fds: Option<&[RawDescriptor]>) -> Result<usize> {
|
||||
let rfds = match fds {
|
||||
Some(rfds) => rfds,
|
||||
_ => &[],
|
||||
|
@ -182,7 +179,7 @@ impl<R: Req> EndpointTrait<R> for SocketEndpoint<R> {
|
|||
/// * - SocketRetry: temporary error caused by signals or short of resources.
|
||||
/// * - SocketBroken: the underline socket is broken.
|
||||
/// * - SocketError: other socket related errors.
|
||||
fn recv_into_bufs(
|
||||
pub fn recv_into_bufs(
|
||||
&mut self,
|
||||
bufs: &mut [IoSliceMut],
|
||||
allow_fd: bool,
|
||||
|
@ -217,14 +214,14 @@ impl<R: Req> EndpointTrait<R> for SocketEndpoint<R> {
|
|||
Ok((bytes, files))
|
||||
}
|
||||
|
||||
fn create_slave_request_endpoint(
|
||||
pub fn create_slave_request_endpoint(
|
||||
&mut self,
|
||||
files: Option<Vec<File>>,
|
||||
) -> Result<Box<dyn EndpointTrait<SlaveReq>>> {
|
||||
) -> Result<Endpoint<SlaveReq>> {
|
||||
let file = take_single_file(files).ok_or(Error::InvalidMessage)?;
|
||||
// Safe because we own the file
|
||||
let tube = unsafe { SystemStream::from_raw_descriptor(file.into_raw_descriptor()) };
|
||||
Ok(Box::new(SocketEndpoint::from(tube)))
|
||||
Ok(Endpoint::<SlaveReq>::from(tube))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,7 +251,6 @@ mod tests {
|
|||
use tempfile::TempDir;
|
||||
|
||||
use super::*;
|
||||
use crate::connection::EndpointExt;
|
||||
|
||||
fn temp_dir() -> TempDir {
|
||||
Builder::new().prefix("/tmp/vhost_test").tempdir().unwrap()
|
||||
|
@ -290,7 +286,7 @@ mod tests {
|
|||
path.push("sock");
|
||||
let mut listener = Listener::new(&path, true).unwrap();
|
||||
listener.set_nonblocking(true).unwrap();
|
||||
let mut master = SocketEndpoint::<MasterReq>::connect(&path).unwrap();
|
||||
let mut master = Endpoint::<MasterReq>::connect(&path).unwrap();
|
||||
let mut slave = listener.accept().unwrap().unwrap();
|
||||
|
||||
let buf1 = [0x1, 0x2, 0x3, 0x4];
|
||||
|
@ -317,7 +313,7 @@ mod tests {
|
|||
path.push("sock");
|
||||
let mut listener = Listener::new(&path, true).unwrap();
|
||||
listener.set_nonblocking(true).unwrap();
|
||||
let mut master = SocketEndpoint::<MasterReq>::connect(&path).unwrap();
|
||||
let mut master = Endpoint::<MasterReq>::connect(&path).unwrap();
|
||||
let mut slave = listener.accept().unwrap().unwrap();
|
||||
|
||||
let mut fd = tempfile().unwrap();
|
||||
|
@ -489,7 +485,7 @@ mod tests {
|
|||
path.push("sock");
|
||||
let mut listener = Listener::new(&path, true).unwrap();
|
||||
listener.set_nonblocking(true).unwrap();
|
||||
let mut master = SocketEndpoint::<MasterReq>::connect(&path).unwrap();
|
||||
let mut master = Endpoint::<MasterReq>::connect(&path).unwrap();
|
||||
let mut slave = listener.accept().unwrap().unwrap();
|
||||
|
||||
let mut hdr1 =
|
||||
|
|
25
third_party/vmm_vhost/src/connection/tube.rs
vendored
25
third_party/vmm_vhost/src/connection/tube.rs
vendored
|
@ -20,10 +20,10 @@ use serde::Deserialize;
|
|||
use serde::Serialize;
|
||||
use tube_transporter::packed_tube;
|
||||
|
||||
use crate::connection::Endpoint;
|
||||
use crate::connection::Req;
|
||||
use crate::message::SlaveReq;
|
||||
use crate::take_single_file;
|
||||
use crate::Endpoint;
|
||||
use crate::Error;
|
||||
use crate::Result;
|
||||
|
||||
|
@ -60,8 +60,8 @@ impl<R: Req> From<Tube> for TubeEndpoint<R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<R: Req> Endpoint<R> for TubeEndpoint<R> {
|
||||
fn connect<P: AsRef<Path>>(_path: P) -> Result<Self> {
|
||||
impl<R: Req> TubeEndpoint<R> {
|
||||
pub fn connect<P: AsRef<Path>>(_path: P) -> Result<Self> {
|
||||
unimplemented!("connections not supported on Tubes")
|
||||
}
|
||||
|
||||
|
@ -70,7 +70,7 @@ impl<R: Req> Endpoint<R> for TubeEndpoint<R> {
|
|||
/// # Return:
|
||||
/// * - number of bytes sent on success
|
||||
/// * - TubeError: tube related errors.
|
||||
fn send_iovec(&mut self, iovs: &[IoSlice], rds: Option<&[RawDescriptor]>) -> Result<usize> {
|
||||
pub fn send_iovec(&mut self, iovs: &[IoSlice], rds: Option<&[RawDescriptor]>) -> Result<usize> {
|
||||
// Gather the iovecs
|
||||
let total_bytes = iovs.iter().map(|iov| iov.len()).sum();
|
||||
let mut data = Vec::with_capacity(total_bytes);
|
||||
|
@ -102,7 +102,7 @@ impl<R: Req> Endpoint<R> for TubeEndpoint<R> {
|
|||
/// * - (number of bytes received, [received files]) on success
|
||||
/// * - RecvBufferTooSmall: Input bufs is too small for the received buffer.
|
||||
/// * - TubeError: tube related errors.
|
||||
fn recv_into_bufs(
|
||||
pub fn recv_into_bufs(
|
||||
&mut self,
|
||||
bufs: &mut [IoSliceMut],
|
||||
_allow_rds: bool,
|
||||
|
@ -156,14 +156,14 @@ impl<R: Req> Endpoint<R> for TubeEndpoint<R> {
|
|||
Ok((bytes_read, files))
|
||||
}
|
||||
|
||||
fn create_slave_request_endpoint(
|
||||
pub fn create_slave_request_endpoint(
|
||||
&mut self,
|
||||
files: Option<Vec<File>>,
|
||||
) -> Result<Box<dyn Endpoint<SlaveReq>>> {
|
||||
) -> Result<Endpoint<SlaveReq>> {
|
||||
let file = take_single_file(files).ok_or(Error::InvalidMessage)?;
|
||||
// Safe because the file represents a packed tube.
|
||||
let tube = unsafe { packed_tube::unpack(file.into()).expect("unpacked Tube") };
|
||||
Ok(Box::new(TubeEndpoint::from(tube)))
|
||||
Ok(Endpoint::from(tube))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -188,16 +188,15 @@ mod tests {
|
|||
use base::Tube;
|
||||
use tempfile::tempfile;
|
||||
|
||||
use super::*;
|
||||
use crate::connection::EndpointExt;
|
||||
use crate::message::MasterReq;
|
||||
use crate::message::VhostUserMsgHeader;
|
||||
use crate::Endpoint;
|
||||
|
||||
fn create_pair() -> (TubeEndpoint<MasterReq>, TubeEndpoint<MasterReq>) {
|
||||
fn create_pair() -> (Endpoint<MasterReq>, Endpoint<MasterReq>) {
|
||||
let (master_tube, slave_tube) = Tube::pair().unwrap();
|
||||
(
|
||||
TubeEndpoint::<MasterReq>::from(master_tube),
|
||||
TubeEndpoint::<MasterReq>::from(slave_tube),
|
||||
Endpoint::<MasterReq>::from(master_tube),
|
||||
Endpoint::<MasterReq>::from(slave_tube),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
14
third_party/vmm_vhost/src/connection/windows.rs
vendored
14
third_party/vmm_vhost/src/connection/windows.rs
vendored
|
@ -5,25 +5,21 @@
|
|||
|
||||
#[cfg(all(test, feature = "vmm"))]
|
||||
pub(crate) mod tests {
|
||||
use crate::connection::TubeEndpoint;
|
||||
use crate::master::Master;
|
||||
use crate::message::MasterReq;
|
||||
use crate::slave_req_handler::SlaveReqHandler;
|
||||
use crate::slave_req_handler::VhostUserSlaveReqHandler;
|
||||
use crate::Endpoint;
|
||||
use crate::SystemStream;
|
||||
pub(crate) type TestEndpoint = TubeEndpoint<MasterReq>;
|
||||
pub(crate) type TestMaster = Master<TestEndpoint>;
|
||||
|
||||
pub(crate) fn create_pair() -> (TestMaster, TestEndpoint) {
|
||||
pub(crate) fn create_pair() -> (Master, Endpoint<MasterReq>) {
|
||||
let (master_tube, slave_tube) = SystemStream::pair().unwrap();
|
||||
let master = Master::from_stream(master_tube);
|
||||
(master, TubeEndpoint::from(slave_tube))
|
||||
(master, Endpoint::from(slave_tube))
|
||||
}
|
||||
|
||||
#[cfg(feature = "device")]
|
||||
pub(crate) fn create_master_slave_pair<S>(
|
||||
backend: S,
|
||||
) -> (TestMaster, SlaveReqHandler<S, TestEndpoint>)
|
||||
pub(crate) fn create_master_slave_pair<S>(backend: S) -> (Master, SlaveReqHandler<S>)
|
||||
where
|
||||
S: VhostUserSlaveReqHandler,
|
||||
{
|
||||
|
@ -31,7 +27,7 @@ pub(crate) mod tests {
|
|||
let master = Master::from_stream(master_tube);
|
||||
(
|
||||
master,
|
||||
SlaveReqHandler::<S, TubeEndpoint<MasterReq>>::from_stream(slave_tube, backend),
|
||||
SlaveReqHandler::<S>::from_stream(slave_tube, backend),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
7
third_party/vmm_vhost/src/lib.rs
vendored
7
third_party/vmm_vhost/src/lib.rs
vendored
|
@ -46,6 +46,9 @@ pub use message::VHOST_USER_F_PROTOCOL_FEATURES;
|
|||
pub mod connection;
|
||||
|
||||
mod sys;
|
||||
pub use connection::Endpoint;
|
||||
pub use message::MasterReq;
|
||||
pub use message::SlaveReq;
|
||||
pub use sys::SystemStream;
|
||||
pub use sys::*;
|
||||
|
||||
|
@ -260,9 +263,7 @@ mod tests {
|
|||
use crate::VringConfigData;
|
||||
|
||||
/// Utility function to process a header and a message together.
|
||||
fn handle_request(
|
||||
h: &mut SlaveReqHandler<Mutex<DummySlaveReqHandler>, MasterReqEndpoint>,
|
||||
) -> Result<()> {
|
||||
fn handle_request(h: &mut SlaveReqHandler<Mutex<DummySlaveReqHandler>>) -> Result<()> {
|
||||
// We assume that a header comes together with message body in tests so we don't wait before
|
||||
// calling `process_message()`.
|
||||
let (hdr, files) = h.recv_header()?;
|
||||
|
|
32
third_party/vmm_vhost/src/master.rs
vendored
32
third_party/vmm_vhost/src/master.rs
vendored
|
@ -21,31 +21,29 @@ use zerocopy::FromBytes;
|
|||
|
||||
use crate::backend::VhostUserMemoryRegionInfo;
|
||||
use crate::backend::VringConfigData;
|
||||
use crate::connection::Endpoint;
|
||||
use crate::connection::EndpointExt;
|
||||
use crate::message::*;
|
||||
use crate::take_single_file;
|
||||
use crate::Endpoint;
|
||||
use crate::Error as VhostUserError;
|
||||
use crate::MasterReq;
|
||||
use crate::Result as VhostUserResult;
|
||||
use crate::Result;
|
||||
use crate::SystemStream;
|
||||
|
||||
/// Client for a vhost-user device. The API is a thin abstraction over the vhost-user protocol.
|
||||
#[derive(Clone)]
|
||||
pub struct Master<E: Endpoint<MasterReq>> {
|
||||
node: Arc<Mutex<MasterInternal<E>>>,
|
||||
pub struct Master {
|
||||
node: Arc<Mutex<MasterInternal>>,
|
||||
}
|
||||
|
||||
impl<E: Endpoint<MasterReq> + From<SystemStream>> Master<E> {
|
||||
impl Master {
|
||||
/// Create a new instance from a Unix stream socket.
|
||||
pub fn from_stream(sock: SystemStream) -> Self {
|
||||
Self::new(E::from(sock))
|
||||
Self::new(Endpoint::from(sock))
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Endpoint<MasterReq>> Master<E> {
|
||||
/// Create a new instance.
|
||||
fn new(ep: E) -> Self {
|
||||
fn new(ep: Endpoint<MasterReq>) -> Self {
|
||||
Master {
|
||||
node: Arc::new(Mutex::new(MasterInternal {
|
||||
main_sock: ep,
|
||||
|
@ -59,7 +57,7 @@ impl<E: Endpoint<MasterReq>> Master<E> {
|
|||
}
|
||||
}
|
||||
|
||||
fn node(&self) -> MutexGuard<MasterInternal<E>> {
|
||||
fn node(&self) -> MutexGuard<MasterInternal> {
|
||||
self.node.lock().unwrap()
|
||||
}
|
||||
|
||||
|
@ -72,7 +70,7 @@ impl<E: Endpoint<MasterReq>> Master<E> {
|
|||
pub fn connect<P: AsRef<Path>>(path: P) -> Result<Self> {
|
||||
let mut retry_count = 5;
|
||||
let endpoint = loop {
|
||||
match E::connect(&path) {
|
||||
match Endpoint::connect(&path) {
|
||||
Ok(endpoint) => break Ok(endpoint),
|
||||
Err(e) => match &e {
|
||||
VhostUserError::SocketConnect(why) => {
|
||||
|
@ -607,7 +605,7 @@ impl<E: Endpoint<MasterReq>> Master<E> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<E: Endpoint<MasterReq> + AsRawDescriptor> AsRawDescriptor for Master<E> {
|
||||
impl AsRawDescriptor for Master {
|
||||
fn as_raw_descriptor(&self) -> RawDescriptor {
|
||||
let node = self.node();
|
||||
// TODO(b/221882601): why is this here? The underlying Tube needs to use a read notifier
|
||||
|
@ -639,9 +637,9 @@ impl VhostUserMemoryContext {
|
|||
}
|
||||
}
|
||||
|
||||
struct MasterInternal<E: Endpoint<MasterReq>> {
|
||||
struct MasterInternal {
|
||||
// Used to send requests to the slave.
|
||||
main_sock: E,
|
||||
main_sock: Endpoint<MasterReq>,
|
||||
// Cached virtio features from the slave.
|
||||
virtio_features: u64,
|
||||
// Cached acked virtio features from the driver.
|
||||
|
@ -656,7 +654,7 @@ struct MasterInternal<E: Endpoint<MasterReq>> {
|
|||
hdr_flags: VhostUserHeaderFlag,
|
||||
}
|
||||
|
||||
impl<E: Endpoint<MasterReq>> MasterInternal<E> {
|
||||
impl MasterInternal {
|
||||
fn send_request_header(
|
||||
&mut self,
|
||||
code: MasterReq,
|
||||
|
@ -795,8 +793,6 @@ mod tests {
|
|||
|
||||
use super::*;
|
||||
use crate::connection::tests::create_pair;
|
||||
use crate::connection::tests::TestEndpoint;
|
||||
use crate::connection::tests::TestMaster;
|
||||
|
||||
const BUFFER_SIZE: usize = 0x1001;
|
||||
|
||||
|
@ -951,7 +947,7 @@ mod tests {
|
|||
.unwrap_err();
|
||||
}
|
||||
|
||||
fn create_pair2() -> (TestMaster, TestEndpoint) {
|
||||
fn create_pair2() -> (Master, Endpoint<MasterReq>) {
|
||||
let (master, peer) = create_pair();
|
||||
{
|
||||
let mut node = master.node();
|
||||
|
|
|
@ -17,12 +17,12 @@ use std::sync::Mutex;
|
|||
use base::AsRawDescriptor;
|
||||
use base::SafeDescriptor;
|
||||
|
||||
use crate::connection::EndpointExt;
|
||||
use crate::message::*;
|
||||
use crate::Endpoint;
|
||||
use crate::Error;
|
||||
use crate::HandlerResult;
|
||||
use crate::Result;
|
||||
use crate::SlaveReqEndpoint;
|
||||
use crate::SlaveReq;
|
||||
use crate::SystemStream;
|
||||
|
||||
/// Define services provided by masters for the slave communication channel.
|
||||
|
@ -226,7 +226,7 @@ impl<S: VhostUserMasterReqHandlerMut> VhostUserMasterReqHandler for Mutex<S> {
|
|||
/// Server to handle service requests from slaves from the slave communication channel.
|
||||
pub struct MasterReqHandler<S: VhostUserMasterReqHandler> {
|
||||
// underlying Unix domain socket for communication
|
||||
sub_sock: SlaveReqEndpoint,
|
||||
sub_sock: Endpoint<SlaveReq>,
|
||||
tx_sock: Option<SystemStream>,
|
||||
// Serializes tx_sock for passing to the backend.
|
||||
serialize_tx: Box<dyn Fn(SystemStream) -> SafeDescriptor + Send>,
|
||||
|
@ -253,7 +253,7 @@ impl<S: VhostUserMasterReqHandler> MasterReqHandler<S> {
|
|||
let (tx, rx) = SystemStream::pair()?;
|
||||
|
||||
Ok(MasterReqHandler {
|
||||
sub_sock: SlaveReqEndpoint::from(rx),
|
||||
sub_sock: Endpoint::from(rx),
|
||||
tx_sock: Some(tx),
|
||||
serialize_tx,
|
||||
reply_ack_negotiated: false,
|
||||
|
|
|
@ -31,14 +31,14 @@ impl<S: VhostUserMasterReqHandler> MasterReqHandler<S> {
|
|||
impl<S: VhostUserMasterReqHandler> ReadNotifier for MasterReqHandler<S> {
|
||||
/// Used for polling.
|
||||
fn get_read_notifier(&self) -> &dyn AsRawDescriptor {
|
||||
self.sub_sock.get_tube().get_read_notifier()
|
||||
self.sub_sock.0.get_tube().get_read_notifier()
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: VhostUserMasterReqHandler> CloseNotifier for MasterReqHandler<S> {
|
||||
/// Used for closing.
|
||||
fn get_close_notifier(&self) -> &dyn AsRawDescriptor {
|
||||
self.sub_sock.get_tube().get_close_notifier()
|
||||
self.sub_sock.0.get_tube().get_close_notifier()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
13
third_party/vmm_vhost/src/slave_proxy.rs
vendored
13
third_party/vmm_vhost/src/slave_proxy.rs
vendored
|
@ -11,18 +11,17 @@ use base::AsRawDescriptor;
|
|||
use base::RawDescriptor;
|
||||
use zerocopy::AsBytes;
|
||||
|
||||
use crate::connection::Endpoint;
|
||||
use crate::connection::EndpointExt;
|
||||
use crate::message::*;
|
||||
use crate::Endpoint;
|
||||
use crate::Error;
|
||||
use crate::HandlerResult;
|
||||
use crate::Result;
|
||||
use crate::SlaveReqEndpoint;
|
||||
use crate::SlaveReq;
|
||||
use crate::SystemStream;
|
||||
use crate::VhostUserMasterReqHandler;
|
||||
|
||||
struct SlaveInternal {
|
||||
sock: Box<dyn Endpoint<SlaveReq>>,
|
||||
sock: Endpoint<SlaveReq>,
|
||||
|
||||
// Protocol feature VHOST_USER_PROTOCOL_F_REPLY_ACK has been negotiated.
|
||||
reply_ack_negotiated: bool,
|
||||
|
@ -89,7 +88,7 @@ pub struct Slave {
|
|||
|
||||
impl Slave {
|
||||
/// Constructs a new slave proxy from the given endpoint.
|
||||
pub fn new(ep: Box<dyn Endpoint<SlaveReq>>) -> Self {
|
||||
pub fn new(ep: Endpoint<SlaveReq>) -> Self {
|
||||
Slave {
|
||||
node: Arc::new(Mutex::new(SlaveInternal {
|
||||
sock: ep,
|
||||
|
@ -119,7 +118,7 @@ impl Slave {
|
|||
|
||||
/// Create a new instance from a `SystemStream` object.
|
||||
pub fn from_stream(sock: SystemStream) -> Self {
|
||||
Self::new(Box::new(SlaveReqEndpoint::from(sock)))
|
||||
Self::new(Endpoint::from(sock))
|
||||
}
|
||||
|
||||
/// Set the negotiation state of the `VHOST_USER_PROTOCOL_F_REPLY_ACK` protocol feature.
|
||||
|
@ -205,7 +204,7 @@ mod tests {
|
|||
fn test_slave_recv_negative() {
|
||||
let (p1, p2) = SystemStream::pair().unwrap();
|
||||
let fs_cache = Slave::from_stream(p1);
|
||||
let mut master = SlaveReqEndpoint::from(p2);
|
||||
let mut master = Endpoint::from(p2);
|
||||
|
||||
let len = mem::size_of::<VhostUserFSSlaveMsg>();
|
||||
let mut hdr = VhostUserMsgHeader::new(
|
||||
|
|
54
third_party/vmm_vhost/src/slave_req_handler.rs
vendored
54
third_party/vmm_vhost/src/slave_req_handler.rs
vendored
|
@ -13,13 +13,13 @@ use zerocopy::FromBytes;
|
|||
|
||||
use zerocopy::Ref;
|
||||
|
||||
use crate::connection::Endpoint;
|
||||
use crate::connection::EndpointExt;
|
||||
use crate::message::*;
|
||||
use crate::take_single_file;
|
||||
use crate::Endpoint;
|
||||
use crate::Error;
|
||||
use crate::MasterReqEndpoint;
|
||||
use crate::MasterReq;
|
||||
use crate::Result;
|
||||
use crate::SlaveReq;
|
||||
use crate::SystemStream;
|
||||
|
||||
/// Services provided to the master by the slave with interior mutability.
|
||||
|
@ -71,7 +71,7 @@ pub trait VhostUserSlaveReqHandler {
|
|||
fn set_vring_enable(&self, index: u32, enable: bool) -> Result<()>;
|
||||
fn get_config(&self, offset: u32, size: u32, flags: VhostUserConfigFlags) -> Result<Vec<u8>>;
|
||||
fn set_config(&self, offset: u32, buf: &[u8], flags: VhostUserConfigFlags) -> Result<()>;
|
||||
fn set_slave_req_fd(&self, _vu_req: Box<dyn Endpoint<SlaveReq>>) {}
|
||||
fn set_slave_req_fd(&self, _vu_req: Endpoint<SlaveReq>) {}
|
||||
fn get_inflight_fd(&self, inflight: &VhostUserInflight) -> Result<(VhostUserInflight, File)>;
|
||||
fn set_inflight_fd(&self, inflight: &VhostUserInflight, file: File) -> Result<()>;
|
||||
fn get_max_mem_slots(&self) -> Result<u64>;
|
||||
|
@ -121,7 +121,7 @@ pub trait VhostUserSlaveReqHandlerMut {
|
|||
flags: VhostUserConfigFlags,
|
||||
) -> Result<Vec<u8>>;
|
||||
fn set_config(&mut self, offset: u32, buf: &[u8], flags: VhostUserConfigFlags) -> Result<()>;
|
||||
fn set_slave_req_fd(&mut self, _vu_req: Box<dyn Endpoint<SlaveReq>>) {}
|
||||
fn set_slave_req_fd(&mut self, _vu_req: Endpoint<SlaveReq>) {}
|
||||
fn get_inflight_fd(
|
||||
&mut self,
|
||||
inflight: &VhostUserInflight,
|
||||
|
@ -224,7 +224,7 @@ impl<T: VhostUserSlaveReqHandlerMut> VhostUserSlaveReqHandler for Mutex<T> {
|
|||
self.lock().unwrap().set_config(offset, buf, flags)
|
||||
}
|
||||
|
||||
fn set_slave_req_fd(&self, vu_req: Box<dyn Endpoint<SlaveReq>>) {
|
||||
fn set_slave_req_fd(&self, vu_req: Endpoint<SlaveReq>) {
|
||||
self.lock().unwrap().set_slave_req_fd(vu_req)
|
||||
}
|
||||
|
||||
|
@ -354,7 +354,7 @@ where
|
|||
self.as_ref().set_config(offset, buf, flags)
|
||||
}
|
||||
|
||||
fn set_slave_req_fd(&self, vu_req: Box<dyn Endpoint<SlaveReq>>) {
|
||||
fn set_slave_req_fd(&self, vu_req: Endpoint<SlaveReq>) {
|
||||
self.as_ref().set_slave_req_fd(vu_req)
|
||||
}
|
||||
|
||||
|
@ -400,17 +400,17 @@ where
|
|||
}
|
||||
|
||||
/// Abstracts |Endpoint| related operations for vhost-user slave implementations.
|
||||
pub struct SlaveReqHelper<E: Endpoint<MasterReq>> {
|
||||
pub struct SlaveReqHelper {
|
||||
/// Underlying endpoint for communication.
|
||||
endpoint: E,
|
||||
endpoint: Endpoint<MasterReq>,
|
||||
|
||||
/// Sending ack for messages without payload.
|
||||
reply_ack_enabled: bool,
|
||||
}
|
||||
|
||||
impl<E: Endpoint<MasterReq>> SlaveReqHelper<E> {
|
||||
impl SlaveReqHelper {
|
||||
/// Creates a new |SlaveReqHelper| instance with an |Endpoint| underneath it.
|
||||
pub fn new(endpoint: E) -> Self {
|
||||
pub fn new(endpoint: Endpoint<MasterReq>) -> Self {
|
||||
SlaveReqHelper {
|
||||
endpoint,
|
||||
reply_ack_enabled: false,
|
||||
|
@ -501,19 +501,19 @@ impl<E: Endpoint<MasterReq>> SlaveReqHelper<E> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<E: Endpoint<MasterReq>> AsRef<E> for SlaveReqHelper<E> {
|
||||
fn as_ref(&self) -> &E {
|
||||
impl AsRef<Endpoint<MasterReq>> for SlaveReqHelper {
|
||||
fn as_ref(&self) -> &Endpoint<MasterReq> {
|
||||
&self.endpoint
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Endpoint<MasterReq>> AsMut<E> for SlaveReqHelper<E> {
|
||||
fn as_mut(&mut self) -> &mut E {
|
||||
impl AsMut<Endpoint<MasterReq>> for SlaveReqHelper {
|
||||
fn as_mut(&mut self) -> &mut Endpoint<MasterReq> {
|
||||
&mut self.endpoint
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: Endpoint<MasterReq> + AsRawDescriptor> AsRawDescriptor for SlaveReqHelper<E> {
|
||||
impl AsRawDescriptor for SlaveReqHelper {
|
||||
fn as_raw_descriptor(&self) -> RawDescriptor {
|
||||
self.endpoint.as_raw_descriptor()
|
||||
}
|
||||
|
@ -530,8 +530,8 @@ impl<E: Endpoint<MasterReq> + AsRawDescriptor> AsRawDescriptor for SlaveReqHelpe
|
|||
///
|
||||
/// [VhostUserSlaveReqHandler]: trait.VhostUserSlaveReqHandler.html
|
||||
/// [SlaveReqHandler]: struct.SlaveReqHandler.html
|
||||
pub struct SlaveReqHandler<S: VhostUserSlaveReqHandler, E: Endpoint<MasterReq>> {
|
||||
slave_req_helper: SlaveReqHelper<E>,
|
||||
pub struct SlaveReqHandler<S: VhostUserSlaveReqHandler> {
|
||||
slave_req_helper: SlaveReqHelper,
|
||||
// the vhost-user backend device object
|
||||
backend: S,
|
||||
|
||||
|
@ -541,22 +541,22 @@ pub struct SlaveReqHandler<S: VhostUserSlaveReqHandler, E: Endpoint<MasterReq>>
|
|||
acked_protocol_features: u64,
|
||||
}
|
||||
|
||||
impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S, MasterReqEndpoint> {
|
||||
impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> {
|
||||
/// Create a vhost-user slave endpoint from a connected socket.
|
||||
pub fn from_stream(socket: SystemStream, backend: S) -> Self {
|
||||
Self::new(MasterReqEndpoint::from(socket), backend)
|
||||
Self::new(Endpoint::from(socket), backend)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: VhostUserSlaveReqHandler, E: Endpoint<MasterReq>> AsRef<S> for SlaveReqHandler<S, E> {
|
||||
impl<S: VhostUserSlaveReqHandler> AsRef<S> for SlaveReqHandler<S> {
|
||||
fn as_ref(&self) -> &S {
|
||||
&self.backend
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: VhostUserSlaveReqHandler, E: Endpoint<MasterReq>> SlaveReqHandler<S, E> {
|
||||
impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> {
|
||||
/// Create a vhost-user slave endpoint.
|
||||
pub fn new(endpoint: E, backend: S) -> Self {
|
||||
pub fn new(endpoint: Endpoint<MasterReq>, backend: S) -> Self {
|
||||
SlaveReqHandler {
|
||||
slave_req_helper: SlaveReqHelper::new(endpoint),
|
||||
backend,
|
||||
|
@ -1119,9 +1119,7 @@ impl<S: VhostUserSlaveReqHandler, E: Endpoint<MasterReq>> SlaveReqHandler<S, E>
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: VhostUserSlaveReqHandler, E: AsRawDescriptor + Endpoint<MasterReq>> AsRawDescriptor
|
||||
for SlaveReqHandler<S, E>
|
||||
{
|
||||
impl<S: VhostUserSlaveReqHandler> AsRawDescriptor for SlaveReqHandler<S> {
|
||||
fn as_raw_descriptor(&self) -> RawDescriptor {
|
||||
// TODO(b/221882601): figure out if this used for polling.
|
||||
self.slave_req_helper.endpoint.as_raw_descriptor()
|
||||
|
@ -1134,13 +1132,13 @@ mod tests {
|
|||
|
||||
use super::*;
|
||||
use crate::dummy_slave::DummySlaveReqHandler;
|
||||
use crate::MasterReqEndpoint;
|
||||
use crate::Endpoint;
|
||||
use crate::SystemStream;
|
||||
|
||||
#[test]
|
||||
fn test_slave_req_handler_new() {
|
||||
let (p1, _p2) = SystemStream::pair().unwrap();
|
||||
let endpoint = MasterReqEndpoint::from(p1);
|
||||
let endpoint = Endpoint::from(p1);
|
||||
let backend = Mutex::new(DummySlaveReqHandler::new());
|
||||
let handler = SlaveReqHandler::new(endpoint, backend);
|
||||
|
||||
|
|
10
third_party/vmm_vhost/src/sys.rs
vendored
10
third_party/vmm_vhost/src/sys.rs
vendored
|
@ -15,8 +15,10 @@ cfg_if::cfg_if! {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "device")]
|
||||
pub(crate) use platform::MasterReqEndpoint;
|
||||
#[cfg(feature = "device")]
|
||||
pub(crate) use platform::SlaveReqEndpoint;
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "device")] {
|
||||
pub(crate) use platform::PlatformEndpoint;
|
||||
}
|
||||
}
|
||||
|
||||
pub use platform::SystemStream;
|
||||
|
|
6
third_party/vmm_vhost/src/sys/linux.rs
vendored
6
third_party/vmm_vhost/src/sys/linux.rs
vendored
|
@ -15,11 +15,7 @@ pub type SystemStream = UnixStream;
|
|||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "device")] {
|
||||
use crate::connection::socket::SocketEndpoint;
|
||||
use crate::message::{MasterReq, SlaveReq};
|
||||
|
||||
pub(crate) type SlaveReqEndpoint = SocketEndpoint<SlaveReq>;
|
||||
pub(crate) type MasterReqEndpoint = SocketEndpoint<MasterReq>;
|
||||
pub(crate) use crate::connection::socket::SocketEndpoint as PlatformEndpoint;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
4
third_party/vmm_vhost/src/sys/windows.rs
vendored
4
third_party/vmm_vhost/src/sys/windows.rs
vendored
|
@ -11,9 +11,7 @@ pub type SystemStream = Tube;
|
|||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "device")] {
|
||||
use crate::connection::TubeEndpoint;
|
||||
use crate::message::{MasterReq, SlaveReq};
|
||||
|
||||
pub(crate) type SlaveReqEndpoint = TubeEndpoint<SlaveReq>;
|
||||
pub(crate) type MasterReqEndpoint = TubeEndpoint<MasterReq>;
|
||||
pub(crate) type PlatformEndpoint<R> = TubeEndpoint<R>;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue