diff options
author | Eryu Guan <eguan@linux.alibaba.com> | 2020-03-23 16:24:33 +0800 |
---|---|---|
committer | Andreea Florescu <andreea.florescu15@gmail.com> | 2020-09-04 17:59:53 +0300 |
commit | 4d9fd4b584e309e3d859fca5ee0be9e0d52be84d (patch) | |
tree | f1ebe5f1113bd315832125f74a7b88f9df58c442 | |
parent | 6a33fb176aaf691faaa75d9fa47a0ef6c9a697f0 (diff) | |
download | vmm_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.rs | 25 | ||||
-rw-r--r-- | src/vhost_user/slave_fs_cache.rs | 14 |
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)))) } |