summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEryu Guan <eguan@linux.alibaba.com>2020-03-23 16:24:33 +0800
committerAndreea Florescu <andreea.florescu15@gmail.com>2020-09-04 17:59:53 +0300
commit4d9fd4b584e309e3d859fca5ee0be9e0d52be84d (patch)
treef1ebe5f1113bd315832125f74a7b88f9df58c442
parent6a33fb176aaf691faaa75d9fa47a0ef6c9a697f0 (diff)
downloadvmm_vhost-4d9fd4b584e309e3d859fca5ee0be9e0d52be84d.tar.gz
vhost-user: preserve master req handler's result
HandlerResult is mapped to either 0 or 1 in send_ack_message() and the actual result (e.g. fs_slave_io()'s I/O count or error number) is lost when sending result back to slave. And slave doesn't know how much data has been read/written nor the real error. Fix it by perserving the real result and send it back to slave in send_ack_message(). Fixes: #15 Signed-off-by: Eryu Guan <eguan@linux.alibaba.com>
-rw-r--r--src/vhost_user/master_req_handler.rs25
-rw-r--r--src/vhost_user/slave_fs_cache.rs14
2 files changed, 23 insertions, 16 deletions
diff --git a/src/vhost_user/master_req_handler.rs b/src/vhost_user/master_req_handler.rs
index ca54ff4..aadfeee 100644
--- a/src/vhost_user/master_req_handler.rs
+++ b/src/vhost_user/master_req_handler.rs
@@ -19,29 +19,29 @@ pub trait VhostUserMasterReqHandler {
// fn handle_vring_host_notifier(&mut self, area: VhostUserVringArea, fd: RawFd);
/// Handle device configuration change notifications from the slave.
- fn handle_config_change(&mut self) -> HandlerResult<()> {
+ fn handle_config_change(&mut self) -> HandlerResult<u64> {
Err(std::io::Error::from_raw_os_error(libc::ENOSYS))
}
/// Handle virtio-fs map file requests from the slave.
- fn fs_slave_map(&mut self, _fs: &VhostUserFSSlaveMsg, fd: RawFd) -> HandlerResult<()> {
+ fn fs_slave_map(&mut self, _fs: &VhostUserFSSlaveMsg, fd: RawFd) -> HandlerResult<u64> {
// Safe because we have just received the rawfd from kernel.
unsafe { libc::close(fd) };
Err(std::io::Error::from_raw_os_error(libc::ENOSYS))
}
/// Handle virtio-fs unmap file requests from the slave.
- fn fs_slave_unmap(&mut self, _fs: &VhostUserFSSlaveMsg) -> HandlerResult<()> {
+ fn fs_slave_unmap(&mut self, _fs: &VhostUserFSSlaveMsg) -> HandlerResult<u64> {
Err(std::io::Error::from_raw_os_error(libc::ENOSYS))
}
/// Handle virtio-fs sync file requests from the slave.
- fn fs_slave_sync(&mut self, _fs: &VhostUserFSSlaveMsg) -> HandlerResult<()> {
+ fn fs_slave_sync(&mut self, _fs: &VhostUserFSSlaveMsg) -> HandlerResult<u64> {
Err(std::io::Error::from_raw_os_error(libc::ENOSYS))
}
/// Handle virtio-fs file IO requests from the slave.
- fn fs_slave_io(&mut self, _fs: &VhostUserFSSlaveMsg, fd: RawFd) -> HandlerResult<()> {
+ fn fs_slave_io(&mut self, _fs: &VhostUserFSSlaveMsg, fd: RawFd) -> HandlerResult<u64> {
// Safe because we have just received the rawfd from kernel.
unsafe { libc::close(fd) };
Err(std::io::Error::from_raw_os_error(libc::ENOSYS))
@@ -90,7 +90,7 @@ impl<S: VhostUserMasterReqHandler> MasterReqHandler<S> {
/// . serialize calls to this function
/// . decide what to do when errer happens
/// . optional recover from failure
- pub fn handle_request(&mut self) -> Result<()> {
+ pub fn handle_request(&mut self) -> Result<u64> {
// Return error if the endpoint is already in failed state.
self.check_state()?;
@@ -251,13 +251,20 @@ impl<S: VhostUserMasterReqHandler> MasterReqHandler<S> {
fn send_ack_message(
&mut self,
req: &VhostUserMsgHeader<SlaveReq>,
- res: &Result<()>,
+ res: &Result<u64>,
) -> Result<()> {
if req.is_need_reply() {
let hdr = self.new_reply_header::<VhostUserU64>(req)?;
+ let def_err = libc::EINVAL;
let val = match res {
- Ok(_) => 0,
- Err(_) => 1,
+ Ok(n) => *n,
+ Err(e) => match &*e {
+ Error::ReqHandlerError(ioerr) => match ioerr.raw_os_error() {
+ Some(rawerr) => -rawerr as u64,
+ None => -def_err as u64,
+ },
+ _ => -def_err as u64,
+ },
};
let msg = VhostUserU64::new(val);
self.sub_sock.send_message(&hdr, &msg, None)?;
diff --git a/src/vhost_user/slave_fs_cache.rs b/src/vhost_user/slave_fs_cache.rs
index a4a1e5e..1804c7a 100644
--- a/src/vhost_user/slave_fs_cache.rs
+++ b/src/vhost_user/slave_fs_cache.rs
@@ -42,7 +42,7 @@ impl SlaveFsCacheReq {
flags: SlaveReq,
fs: &VhostUserFSSlaveMsg,
fds: Option<&[RawFd]>,
- ) -> Result<()> {
+ ) -> Result<u64> {
self.check_state()?;
let len = mem::size_of::<VhostUserFSSlaveMsg>();
@@ -53,7 +53,7 @@ impl SlaveFsCacheReq {
self.wait_for_ack(&hdr)
}
- fn wait_for_ack(&mut self, hdr: &VhostUserMsgHeader<SlaveReq>) -> Result<()> {
+ fn wait_for_ack(&mut self, hdr: &VhostUserMsgHeader<SlaveReq>) -> Result<u64> {
self.check_state()?;
let (reply, body, rfds) = self.node.lock().unwrap().sock.recv_body::<VhostUserU64>()?;
if !reply.is_reply_for(&hdr) || rfds.is_some() || !body.is_valid() {
@@ -63,13 +63,13 @@ impl SlaveFsCacheReq {
if body.value != 0 {
return Err(Error::MasterInternalError);
}
- Ok(())
+ Ok(0)
}
- fn check_state(&self) -> Result<()> {
+ fn check_state(&self) -> Result<u64> {
match self.error {
Some(e) => Err(Error::SocketBroken(std::io::Error::from_raw_os_error(e))),
- None => Ok(()),
+ None => Ok(0),
}
}
@@ -81,13 +81,13 @@ impl SlaveFsCacheReq {
impl VhostUserMasterReqHandler for SlaveFsCacheReq {
/// Handle virtio-fs map file requests from the slave.
- fn fs_slave_map(&mut self, fs: &VhostUserFSSlaveMsg, fd: RawFd) -> HandlerResult<()> {
+ fn fs_slave_map(&mut self, fs: &VhostUserFSSlaveMsg, fd: RawFd) -> HandlerResult<u64> {
self.send_message(SlaveReq::FS_MAP, fs, Some(&[fd]))
.or_else(|e| Err(io::Error::new(io::ErrorKind::Other, format!("{}", e))))
}
/// Handle virtio-fs unmap file requests from the slave.
- fn fs_slave_unmap(&mut self, fs: &VhostUserFSSlaveMsg) -> HandlerResult<()> {
+ fn fs_slave_unmap(&mut self, fs: &VhostUserFSSlaveMsg) -> HandlerResult<u64> {
self.send_message(SlaveReq::FS_UNMAP, fs, None)
.or_else(|e| Err(io::Error::new(io::ErrorKind::Other, format!("{}", e))))
}