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:
Frederick Mayle 2023-09-01 16:40:18 -07:00 committed by crosvm LUCI
parent 0419cd9401
commit 4fa985cf0a
22 changed files with 199 additions and 218 deletions

View file

@ -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)

View file

@ -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)
}

View file

@ -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)
}
}

View file

@ -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)?;

View file

@ -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");
}

View file

@ -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)?;

View file

@ -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)?;

View file

@ -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>,

View file

@ -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 {

View file

@ -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();
}
}

View file

@ -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 =

View file

@ -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),
)
}

View file

@ -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),
)
}
}

View file

@ -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()?;

View file

@ -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();

View file

@ -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,

View file

@ -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()
}
}

View file

@ -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(

View file

@ -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);

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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>;
}
}