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:
Liu Bo
2020-02-12 15:15:04 -08:00
committed by Rob Bradford
parent 3f09eff6c5
commit 59958f0a61
3 changed files with 52 additions and 3 deletions

View File

@@ -4,12 +4,14 @@
//! Traits and Structs to handle vhost-user requests from the master to the slave.
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::sync::{Arc, Mutex};
use super::connection::Endpoint;
use super::message::*;
use super::slave_fs_cache::SlaveFsCacheReq;
use super::{Error, Result};
/// Trait to handle vhost-user requests from the master to the slave.
@@ -47,6 +49,7 @@ pub trait VhostUserSlaveReqHandler {
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: SlaveFsCacheReq) {}
}
/// 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.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);
}
@@ -405,6 +416,25 @@ impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> {
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(
&mut self,
buf: &[u8],