diff options
author | Sebastien Boeuf <sebastien.boeuf@intel.com> | 2019-09-10 15:29:53 -0700 |
---|---|---|
committer | Andreea Florescu <andreea.florescu15@gmail.com> | 2020-09-04 17:59:53 +0300 |
commit | d0850abc14163a5b85f39cbcc447bf3c821bc90a (patch) | |
tree | 4de2148f92b017927588ab0443558bcb88809740 /src/vhost_user | |
parent | 897bc18f573a6d52184f9781282257d114281cef (diff) | |
download | vmm_vhost-d0850abc14163a5b85f39cbcc447bf3c821bc90a.tar.gz |
vhost-user: Fix GET_CONFIG command
Following the vhost-user specification that can be found at
https://github.com/qemu/qemu/blob/master/docs/interop/
vhost-user.rst#virtio-device-config-space
this patch fixes the GET_CONFIG command.
This command is very specific as it needs to provide a body and a
payload corresponding to the content of the configuration structure as
an array of bytes. As a reply, it receives the body and payload provided
by the slave.
Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
Diffstat (limited to 'src/vhost_user')
-rw-r--r-- | src/vhost_user/master.rs | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/src/vhost_user/master.rs b/src/vhost_user/master.rs index 1a098cd..4df85d4 100644 --- a/src/vhost_user/master.rs +++ b/src/vhost_user/master.rs @@ -40,11 +40,12 @@ pub trait VhostUserMaster: VhostBackend { offset: u32, size: u32, flags: VhostUserConfigFlags, - ) -> Result<Vec<u8>>; + buf: &[u8], + ) -> Result<(VhostUserConfig, VhostUserConfigPayload)>; /// Change the virtio device configuration space. It also can be used for live migration on the /// destination host to set readonly configuration space fields. - fn set_config(&mut self, offset: u32, buf: &[u8], flags: VhostUserConfigFlags) -> Result<()>; + fn set_config(&mut self, offset: u32, flags: VhostUserConfigFlags, buf: &[u8]) -> Result<()>; /// Setup slave communication channel. fn set_slave_request_fd(&mut self, fd: RawFd) -> Result<()>; @@ -344,7 +345,8 @@ impl VhostUserMaster for Master { offset: u32, size: u32, flags: VhostUserConfigFlags, - ) -> Result<Vec<u8>> { + buf: &[u8], + ) -> Result<(VhostUserConfig, VhostUserConfigPayload)> { let body = VhostUserConfig::new(offset, size, flags); if !body.is_valid() { return error_code(VhostUserError::InvalidParam); @@ -356,24 +358,24 @@ impl VhostUserMaster for Master { return error_code(VhostUserError::InvalidOperation); } - // TODO: vhost-user spec states that: + // vhost-user spec states that: // "Master payload: virtio device config space" - // But what content should the payload contains for a get_config() request? - // So current implementation doesn't conform to the spec. - let hdr = node.send_request_with_body(MasterReq::GET_CONFIG, &body, None)?; - let (reply, buf, rfds) = node.recv_reply_with_payload::<VhostUserConfig>(&hdr)?; + // "Slave payload: virtio device config space" + let hdr = node.send_request_with_payload(MasterReq::GET_CONFIG, &body, buf, None)?; + let (body_reply, buf_reply, rfds) = + node.recv_reply_with_payload::<VhostUserConfig>(&hdr)?; if rfds.is_some() { Endpoint::<MasterReq>::close_rfds(rfds); return error_code(VhostUserError::InvalidMessage); - } else if reply.size == 0 { + } else if body_reply.size == 0 { return error_code(VhostUserError::SlaveInternalError); - } else if reply.size != body.size || reply.size as usize != buf.len() { + } else if body_reply.size != body.size || body_reply.size as usize != buf.len() { return error_code(VhostUserError::InvalidMessage); } - Ok(buf) + Ok((body_reply, buf_reply)) } - fn set_config(&mut self, offset: u32, buf: &[u8], flags: VhostUserConfigFlags) -> Result<()> { + fn set_config(&mut self, offset: u32, flags: VhostUserConfigFlags, buf: &[u8]) -> Result<()> { if buf.len() > MAX_MSG_SIZE { return error_code(VhostUserError::InvalidParam); } @@ -550,12 +552,12 @@ impl MasterInternal { } self.check_state()?; - let mut buf = vec![0; MAX_MSG_SIZE - mem::size_of::<T>()]; + let mut buf: Vec<u8> = vec![0; hdr.get_size() as usize - mem::size_of::<T>()]; let (reply, body, bytes, rfds) = self.main_sock.recv_payload_into_buf::<T>(&mut buf)?; if !reply.is_reply_for(hdr) || reply.get_size() as usize != mem::size_of::<T>() + bytes || rfds.is_some() - || body.is_valid() + || !body.is_valid() { Endpoint::<MasterReq>::close_rfds(rfds); return Err(VhostUserError::InvalidMessage); |