mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 21:55:20 +00:00
vhost_user_fs: add the ability to set slave req fd
This adds the missing part of supporting virtiofs dax on the slave end, that is, receiving a socket pair fd from the master end to set up a communication channel for sending setupmapping & removemapping messages. Signed-off-by: Liu Bo <bo.liu@linux.alibaba.com>
This commit is contained in:
parent
3f09eff6c5
commit
59958f0a61
@ -17,6 +17,7 @@ use std::sync::{Arc, RwLock};
|
|||||||
use std::{convert, error, fmt, io, process};
|
use std::{convert, error, fmt, io, process};
|
||||||
|
|
||||||
use vhost_rs::vhost_user::message::*;
|
use vhost_rs::vhost_user::message::*;
|
||||||
|
use vhost_rs::vhost_user::SlaveFsCacheReq;
|
||||||
use vhost_user_backend::{VhostUserBackend, VhostUserDaemon, Vring};
|
use vhost_user_backend::{VhostUserBackend, VhostUserDaemon, Vring};
|
||||||
use vhost_user_fs::descriptor_utils::{Reader, Writer};
|
use vhost_user_fs::descriptor_utils::{Reader, Writer};
|
||||||
use vhost_user_fs::filesystem::FileSystem;
|
use vhost_user_fs::filesystem::FileSystem;
|
||||||
@ -72,6 +73,8 @@ struct VhostUserFsBackend<F: FileSystem + Send + Sync + 'static> {
|
|||||||
mem: Option<GuestMemoryMmap>,
|
mem: Option<GuestMemoryMmap>,
|
||||||
kill_evt: EventFd,
|
kill_evt: EventFd,
|
||||||
server: Arc<Server<F>>,
|
server: Arc<Server<F>>,
|
||||||
|
// handle request from slave to master
|
||||||
|
vu_req: Option<SlaveFsCacheReq>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: FileSystem + Send + Sync + 'static> Clone for VhostUserFsBackend<F> {
|
impl<F: FileSystem + Send + Sync + 'static> Clone for VhostUserFsBackend<F> {
|
||||||
@ -80,6 +83,7 @@ impl<F: FileSystem + Send + Sync + 'static> Clone for VhostUserFsBackend<F> {
|
|||||||
mem: self.mem.clone(),
|
mem: self.mem.clone(),
|
||||||
kill_evt: self.kill_evt.try_clone().unwrap(),
|
kill_evt: self.kill_evt.try_clone().unwrap(),
|
||||||
server: self.server.clone(),
|
server: self.server.clone(),
|
||||||
|
vu_req: self.vu_req.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,6 +94,7 @@ impl<F: FileSystem + Send + Sync + 'static> VhostUserFsBackend<F> {
|
|||||||
mem: None,
|
mem: None,
|
||||||
kill_evt: EventFd::new(EFD_NONBLOCK).map_err(Error::CreateKillEventFd)?,
|
kill_evt: EventFd::new(EFD_NONBLOCK).map_err(Error::CreateKillEventFd)?,
|
||||||
server: Arc::new(Server::new(fs)),
|
server: Arc::new(Server::new(fs)),
|
||||||
|
vu_req: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +110,7 @@ impl<F: FileSystem + Send + Sync + 'static> VhostUserFsBackend<F> {
|
|||||||
|
|
||||||
let total = self
|
let total = self
|
||||||
.server
|
.server
|
||||||
.handle_message(reader, writer)
|
.handle_message(reader, writer, self.vu_req.as_mut())
|
||||||
.map_err(Error::ProcessQueue)?;
|
.map_err(Error::ProcessQueue)?;
|
||||||
|
|
||||||
used_desc_heads[used_count] = (head_index, total);
|
used_desc_heads[used_count] = (head_index, total);
|
||||||
@ -173,6 +178,10 @@ impl<F: FileSystem + Send + Sync + 'static> VhostUserBackend for VhostUserFsBack
|
|||||||
fn exit_event(&self) -> Option<(EventFd, Option<u16>)> {
|
fn exit_event(&self) -> Option<(EventFd, Option<u16>)> {
|
||||||
Some((self.kill_evt.try_clone().unwrap(), Some(KILL_EVENT)))
|
Some((self.kill_evt.try_clone().unwrap(), Some(KILL_EVENT)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_slave_req_fd(&mut self, vu_req: SlaveFsCacheReq) {
|
||||||
|
self.vu_req = Some(vu_req);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -4,12 +4,14 @@
|
|||||||
//! Traits and Structs to handle vhost-user requests from the master to the slave.
|
//! Traits and Structs to handle vhost-user requests from the master to the slave.
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
|
||||||
|
use std::os::unix::net::UnixStream;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use super::connection::Endpoint;
|
use super::connection::Endpoint;
|
||||||
use super::message::*;
|
use super::message::*;
|
||||||
|
use super::slave_fs_cache::SlaveFsCacheReq;
|
||||||
use super::{Error, Result};
|
use super::{Error, Result};
|
||||||
|
|
||||||
/// Trait to handle vhost-user requests from the master to the slave.
|
/// Trait to handle vhost-user requests from the master to the slave.
|
||||||
@ -47,6 +49,7 @@ pub trait VhostUserSlaveReqHandler {
|
|||||||
flags: VhostUserConfigFlags,
|
flags: VhostUserConfigFlags,
|
||||||
) -> Result<Vec<u8>>;
|
) -> Result<Vec<u8>>;
|
||||||
fn set_config(&mut self, offset: u32, buf: &[u8], flags: VhostUserConfigFlags) -> Result<()>;
|
fn set_config(&mut self, offset: u32, buf: &[u8], flags: VhostUserConfigFlags) -> Result<()>;
|
||||||
|
fn set_slave_req_fd(&mut self, _vu_req: SlaveFsCacheReq) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A vhost-user slave endpoint which relays all received requests from the
|
/// A vhost-user slave endpoint which relays all received requests from the
|
||||||
@ -274,6 +277,14 @@ impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> {
|
|||||||
self.check_request_size(&hdr, size, hdr.get_size() as usize)?;
|
self.check_request_size(&hdr, size, hdr.get_size() as usize)?;
|
||||||
self.set_config(&hdr, size, &buf)?;
|
self.set_config(&hdr, size, &buf)?;
|
||||||
}
|
}
|
||||||
|
MasterReq::SET_SLAVE_REQ_FD => {
|
||||||
|
if self.acked_protocol_features & VhostUserProtocolFeatures::SLAVE_SEND_FD.bits()
|
||||||
|
== 0
|
||||||
|
{
|
||||||
|
return Err(Error::InvalidOperation);
|
||||||
|
}
|
||||||
|
self.set_slave_req_fd(&hdr, rfds)?;
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::InvalidMessage);
|
return Err(Error::InvalidMessage);
|
||||||
}
|
}
|
||||||
@ -405,6 +416,25 @@ impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_slave_req_fd(
|
||||||
|
&mut self,
|
||||||
|
hdr: &VhostUserMsgHeader<MasterReq>,
|
||||||
|
rfds: Option<Vec<RawFd>>,
|
||||||
|
) -> Result<()> {
|
||||||
|
if let Some(fds) = rfds {
|
||||||
|
if fds.len() == 1 {
|
||||||
|
let sock = unsafe { UnixStream::from_raw_fd(fds[0]) };
|
||||||
|
let vu_req = SlaveFsCacheReq::from_stream(sock);
|
||||||
|
self.backend.lock().unwrap().set_slave_req_fd(vu_req);
|
||||||
|
self.send_ack_message(&hdr, Ok(()))
|
||||||
|
} else {
|
||||||
|
Err(Error::InvalidMessage)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(Error::InvalidMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_vring_fd_request(
|
fn handle_vring_fd_request(
|
||||||
&mut self,
|
&mut self,
|
||||||
buf: &[u8],
|
buf: &[u8],
|
||||||
|
@ -20,7 +20,8 @@ use vhost_rs::vhost_user::message::{
|
|||||||
VhostUserVirtioFeatures, VhostUserVringAddrFlags, VhostUserVringState,
|
VhostUserVirtioFeatures, VhostUserVringAddrFlags, VhostUserVringState,
|
||||||
};
|
};
|
||||||
use vhost_rs::vhost_user::{
|
use vhost_rs::vhost_user::{
|
||||||
Error as VhostUserError, Result as VhostUserResult, SlaveListener, VhostUserSlaveReqHandler,
|
Error as VhostUserError, Result as VhostUserResult, SlaveFsCacheReq, SlaveListener,
|
||||||
|
VhostUserSlaveReqHandler,
|
||||||
};
|
};
|
||||||
use vm_memory::guest_memory::FileOffset;
|
use vm_memory::guest_memory::FileOffset;
|
||||||
use vm_memory::{GuestAddress, GuestMemoryMmap};
|
use vm_memory::{GuestAddress, GuestMemoryMmap};
|
||||||
@ -103,6 +104,11 @@ pub trait VhostUserBackend: Send + Sync + 'static {
|
|||||||
fn exit_event(&self) -> Option<(EventFd, Option<u16>)> {
|
fn exit_event(&self) -> Option<(EventFd, Option<u16>)> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set slave fd.
|
||||||
|
/// A default implementation is provided as we cannot expect all backends
|
||||||
|
/// to implement this function.
|
||||||
|
fn set_slave_req_fd(&mut self, _vu_req: SlaveFsCacheReq) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This structure is the public API the backend is allowed to interact with
|
/// This structure is the public API the backend is allowed to interact with
|
||||||
@ -779,6 +785,10 @@ impl<S: VhostUserBackend> VhostUserSlaveReqHandler for VhostUserHandler<S> {
|
|||||||
.set_config(offset, buf)
|
.set_config(offset, buf)
|
||||||
.map_err(VhostUserError::ReqHandlerError)
|
.map_err(VhostUserError::ReqHandlerError)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_slave_req_fd(&mut self, vu_req: SlaveFsCacheReq) {
|
||||||
|
self.backend.write().unwrap().set_slave_req_fd(vu_req);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: VhostUserBackend> Drop for VhostUserHandler<S> {
|
impl<S: VhostUserBackend> Drop for VhostUserHandler<S> {
|
||||||
|
Loading…
Reference in New Issue
Block a user