From c6feb03dc08dfc6f4faea211811361228e8f86f8 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Wed, 7 Aug 2019 10:50:17 -0700 Subject: [PATCH] vhost_rs: Allow MasterReqHandler to reply when needed No matter if the communication is coming from the master or the slave, it should always reply with an ack if the message header specifies that it expects a reply. Signed-off-by: Sebastien Boeuf --- vhost_rs/src/vhost_user/master_req_handler.rs | 52 +++++++++++++++---- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/vhost_rs/src/vhost_user/master_req_handler.rs b/vhost_rs/src/vhost_user/master_req_handler.rs index f79cf79e0..cc8270820 100644 --- a/vhost_rs/src/vhost_user/master_req_handler.rs +++ b/vhost_rs/src/vhost_user/master_req_handler.rs @@ -109,14 +109,14 @@ impl MasterReqHandler { } }; - match hdr.get_code() { + let res = match hdr.get_code() { SlaveReq::CONFIG_CHANGE_MSG => { self.check_msg_size(&hdr, size, 0)?; self.backend .lock() .unwrap() .handle_config_change() - .map_err(Error::ReqHandlerError)?; + .map_err(Error::ReqHandlerError) } SlaveReq::FS_MAP => { let msg = self.extract_msg_body::(&hdr, size, &buf)?; @@ -124,7 +124,7 @@ impl MasterReqHandler { .lock() .unwrap() .fs_slave_map(msg, rfds.unwrap()[0]) - .map_err(Error::ReqHandlerError)?; + .map_err(Error::ReqHandlerError) } SlaveReq::FS_UNMAP => { let msg = self.extract_msg_body::(&hdr, size, &buf)?; @@ -132,7 +132,7 @@ impl MasterReqHandler { .lock() .unwrap() .fs_slave_unmap(msg) - .map_err(Error::ReqHandlerError)?; + .map_err(Error::ReqHandlerError) } SlaveReq::FS_SYNC => { let msg = self.extract_msg_body::(&hdr, size, &buf)?; @@ -140,14 +140,14 @@ impl MasterReqHandler { .lock() .unwrap() .fs_slave_sync(msg) - .map_err(Error::ReqHandlerError)?; + .map_err(Error::ReqHandlerError) } - _ => { - return Err(Error::InvalidMessage); - } - } + _ => Err(Error::InvalidMessage), + }; - Ok(()) + self.send_ack_message(&hdr, &res)?; + + res } fn check_state(&self) -> Result<()> { @@ -217,6 +217,38 @@ impl MasterReqHandler { } Ok(msg) } + + fn new_reply_header( + &self, + req: &VhostUserMsgHeader, + ) -> Result> { + if mem::size_of::() > MAX_MSG_SIZE { + return Err(Error::InvalidParam); + } + self.check_state()?; + Ok(VhostUserMsgHeader::new( + req.get_code(), + VhostUserHeaderFlag::REPLY.bits(), + mem::size_of::() as u32, + )) + } + + fn send_ack_message( + &mut self, + req: &VhostUserMsgHeader, + res: &Result<()>, + ) -> Result<()> { + if req.is_need_reply() { + let hdr = self.new_reply_header::(req)?; + let val = match res { + Ok(_) => 0, + Err(_) => 1, + }; + let msg = VhostUserU64::new(val); + self.sub_sock.send_message(&hdr, &msg, None)?; + } + Ok(()) + } } impl AsRawFd for MasterReqHandler {