mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 05:35:20 +00:00
virtio-devices: vhost_user: Reconnection for slave request handler
Add the support for reconnecting the backend request handler after a disconnection/crash happened. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
acec7e34fc
commit
1a5c6631a5
@ -23,7 +23,7 @@ use std::vec::Vec;
|
||||
use vhost::vhost_user::message::VhostUserConfigFlags;
|
||||
use vhost::vhost_user::message::VHOST_USER_CONFIG_OFFSET;
|
||||
use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures};
|
||||
use vhost::vhost_user::{Master, VhostUserMaster, VhostUserMasterReqHandler};
|
||||
use vhost::vhost_user::{Master, MasterReqHandler, VhostUserMaster, VhostUserMasterReqHandler};
|
||||
use vhost::VhostBackend;
|
||||
use virtio_bindings::bindings::virtio_blk::{
|
||||
VIRTIO_BLK_F_BLK_SIZE, VIRTIO_BLK_F_CONFIG_WCE, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_FLUSH,
|
||||
@ -215,6 +215,8 @@ impl VirtioDevice for Blk {
|
||||
|
||||
self.guest_memory = Some(mem.clone());
|
||||
|
||||
let slave_req_handler: Option<MasterReqHandler<SlaveReqHandler>> = None;
|
||||
|
||||
// The backend acknowledged features must contain the protocol feature
|
||||
// bit in case it was initially set but lost through the features
|
||||
// negotiation with the guest.
|
||||
@ -228,6 +230,7 @@ impl VirtioDevice for Blk {
|
||||
queue_evts.iter().map(|q| q.try_clone().unwrap()).collect(),
|
||||
&interrupt_cb,
|
||||
backend_acked_features,
|
||||
&slave_req_handler,
|
||||
)
|
||||
.map_err(ActivateError::VhostUserBlkSetup)?;
|
||||
|
||||
|
@ -415,22 +415,6 @@ impl VirtioDevice for Fs {
|
||||
self.common.activate(&queues, &queue_evts, &interrupt_cb)?;
|
||||
self.guest_memory = Some(mem.clone());
|
||||
|
||||
// The backend acknowledged features must contain the protocol feature
|
||||
// bit in case it was initially set but lost through the features
|
||||
// negotiation with the guest.
|
||||
let backend_acked_features = self.common.acked_features
|
||||
| (self.common.avail_features & VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits());
|
||||
|
||||
setup_vhost_user(
|
||||
&mut self.vu.lock().unwrap(),
|
||||
&mem.memory(),
|
||||
queues.clone(),
|
||||
queue_evts.iter().map(|q| q.try_clone().unwrap()).collect(),
|
||||
&interrupt_cb,
|
||||
backend_acked_features,
|
||||
)
|
||||
.map_err(ActivateError::VhostUserFsSetup)?;
|
||||
|
||||
// Initialize slave communication.
|
||||
let slave_req_handler = if self.slave_req_support {
|
||||
if let Some(cache) = self.cache.as_ref() {
|
||||
@ -446,13 +430,6 @@ impl VirtioDevice for Fs {
|
||||
ActivateError::VhostUserFsSetup(Error::MasterReqHandlerCreation(e))
|
||||
})?;
|
||||
req_handler.set_reply_ack_flag(true);
|
||||
self.vu
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_slave_request_fd(req_handler.get_tx_raw_fd())
|
||||
.map_err(|e| {
|
||||
ActivateError::VhostUserFsSetup(Error::VhostUserSetSlaveRequestFd(e))
|
||||
})?;
|
||||
Some(req_handler)
|
||||
} else {
|
||||
None
|
||||
@ -461,6 +438,23 @@ impl VirtioDevice for Fs {
|
||||
None
|
||||
};
|
||||
|
||||
// The backend acknowledged features must contain the protocol feature
|
||||
// bit in case it was initially set but lost through the features
|
||||
// negotiation with the guest.
|
||||
let backend_acked_features = self.common.acked_features
|
||||
| (self.common.avail_features & VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits());
|
||||
|
||||
setup_vhost_user(
|
||||
&mut self.vu.lock().unwrap(),
|
||||
&mem.memory(),
|
||||
queues.clone(),
|
||||
queue_evts.iter().map(|q| q.try_clone().unwrap()).collect(),
|
||||
&interrupt_cb,
|
||||
backend_acked_features,
|
||||
&slave_req_handler,
|
||||
)
|
||||
.map_err(ActivateError::VhostUserFsSetup)?;
|
||||
|
||||
// Run a dedicated thread for handling potential reconnections with
|
||||
// the backend as well as requests initiated by the backend.
|
||||
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
||||
|
@ -197,6 +197,7 @@ impl<S: VhostUserMasterReqHandler> VhostUserEpollHandler<S> {
|
||||
&self.virtio_interrupt,
|
||||
self.acked_features,
|
||||
self.acked_protocol_features,
|
||||
&self.slave_req_handler,
|
||||
)
|
||||
.map_err(|e| {
|
||||
EpollHelperError::IoError(std::io::Error::new(
|
||||
|
@ -23,7 +23,7 @@ use std::sync::{Arc, Barrier, Mutex};
|
||||
use std::thread;
|
||||
use std::vec::Vec;
|
||||
use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures};
|
||||
use vhost::vhost_user::{Master, VhostUserMaster, VhostUserMasterReqHandler};
|
||||
use vhost::vhost_user::{Master, MasterReqHandler, VhostUserMaster, VhostUserMasterReqHandler};
|
||||
use virtio_bindings::bindings::virtio_net::{
|
||||
VIRTIO_NET_F_CSUM, VIRTIO_NET_F_CTRL_VQ, VIRTIO_NET_F_GUEST_CSUM, VIRTIO_NET_F_GUEST_ECN,
|
||||
VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, VIRTIO_NET_F_GUEST_UFO,
|
||||
@ -283,6 +283,8 @@ impl VirtioDevice for Net {
|
||||
})?;
|
||||
}
|
||||
|
||||
let slave_req_handler: Option<MasterReqHandler<SlaveReqHandler>> = None;
|
||||
|
||||
// The backend acknowledged features must contain the protocol feature
|
||||
// bit in case it was initially set but lost through the features
|
||||
// negotiation with the guest. Additionally, it must not contain
|
||||
@ -297,6 +299,7 @@ impl VirtioDevice for Net {
|
||||
queue_evts.iter().map(|q| q.try_clone().unwrap()).collect(),
|
||||
&interrupt_cb,
|
||||
backend_acked_features,
|
||||
&slave_req_handler,
|
||||
)
|
||||
.map_err(ActivateError::VhostUserNetSetup)?;
|
||||
|
||||
|
@ -13,7 +13,7 @@ use std::thread::sleep;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::vec::Vec;
|
||||
use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures};
|
||||
use vhost::vhost_user::{Master, VhostUserMaster};
|
||||
use vhost::vhost_user::{Master, MasterReqHandler, VhostUserMaster, VhostUserMasterReqHandler};
|
||||
use vhost::{VhostBackend, VhostUserMemoryRegionInfo, VringConfigData};
|
||||
use vm_memory::{Address, Error as MmapError, GuestMemory, GuestMemoryRegion};
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
@ -100,13 +100,14 @@ pub fn negotiate_features_vhost_user(
|
||||
Ok((acked_features, acked_protocol_features))
|
||||
}
|
||||
|
||||
pub fn setup_vhost_user(
|
||||
pub fn setup_vhost_user<S: VhostUserMasterReqHandler>(
|
||||
vu: &mut Master,
|
||||
mem: &GuestMemoryMmap,
|
||||
queues: Vec<Queue>,
|
||||
queue_evts: Vec<EventFd>,
|
||||
virtio_interrupt: &Arc<dyn VirtioInterrupt>,
|
||||
acked_features: u64,
|
||||
slave_req_handler: &Option<MasterReqHandler<S>>,
|
||||
) -> Result<()> {
|
||||
vu.set_features(acked_features)
|
||||
.map_err(Error::VhostUserSetFeatures)?;
|
||||
@ -164,7 +165,12 @@ pub fn setup_vhost_user(
|
||||
.map_err(Error::VhostUserSetVringEnable)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
if let Some(slave_req_handler) = slave_req_handler {
|
||||
vu.set_slave_request_fd(slave_req_handler.get_tx_raw_fd())
|
||||
.map_err(Error::VhostUserSetSlaveRequestFd)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reset_vhost_user(vu: &mut Master, num_queues: usize) -> Result<()> {
|
||||
@ -178,7 +184,8 @@ pub fn reset_vhost_user(vu: &mut Master, num_queues: usize) -> Result<()> {
|
||||
vu.reset_owner().map_err(Error::VhostUserResetOwner)
|
||||
}
|
||||
|
||||
pub fn reinitialize_vhost_user(
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn reinitialize_vhost_user<S: VhostUserMasterReqHandler>(
|
||||
vu: &mut Master,
|
||||
mem: &GuestMemoryMmap,
|
||||
queues: Vec<Queue>,
|
||||
@ -186,6 +193,7 @@ pub fn reinitialize_vhost_user(
|
||||
virtio_interrupt: &Arc<dyn VirtioInterrupt>,
|
||||
acked_features: u64,
|
||||
acked_protocol_features: u64,
|
||||
slave_req_handler: &Option<MasterReqHandler<S>>,
|
||||
) -> Result<()> {
|
||||
vu.set_owner().map_err(Error::VhostUserSetOwner)?;
|
||||
vu.get_features().map_err(Error::VhostUserGetFeatures)?;
|
||||
@ -206,6 +214,7 @@ pub fn reinitialize_vhost_user(
|
||||
queue_evts,
|
||||
virtio_interrupt,
|
||||
acked_features,
|
||||
slave_req_handler,
|
||||
)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user