vmm, virtio-devices: Restore vhost-user devices in a dedicated way

We cannot let vhost-user devices connect to the backend when the Block,
Fs or Net object is being created during a restore/migration. The reason
is we can't have two VMs (source and destination) connected to the same
backend at the same time. That's why we must delay the connection with
the vhost-user backend until the restoration is performed.

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf
2021-08-09 14:02:30 +02:00
committed by Bo Chen
parent a636411522
commit 4735cb8563
4 changed files with 176 additions and 2 deletions
+54 -1
View File
@@ -43,6 +43,8 @@ pub struct State {
pub avail_features: u64,
pub acked_features: u64,
pub config: VirtioBlockConfig,
pub acked_protocol_features: u64,
pub vu_num_queues: usize,
}
impl VersionMapped for State {}
@@ -65,9 +67,33 @@ pub struct Blk {
impl Blk {
/// Create a new vhost-user-blk device
pub fn new(id: String, vu_cfg: VhostUserConfig) -> Result<Blk> {
pub fn new(id: String, vu_cfg: VhostUserConfig, restoring: bool) -> Result<Blk> {
let num_queues = vu_cfg.num_queues;
if restoring {
// We need 'queue_sizes' to report a number of queues that will be
// enough to handle all the potential queues. VirtioPciDevice::new()
// will create the actual queues based on this information.
return Ok(Blk {
id,
common: VirtioCommon {
device_type: VirtioDeviceType::Block as u32,
queue_sizes: vec![vu_cfg.queue_size; num_queues],
paused_sync: Some(Arc::new(Barrier::new(2))),
min_queues: DEFAULT_QUEUE_NUMBER as u16,
..Default::default()
},
vu: None,
config: VirtioBlockConfig::default(),
guest_memory: None,
acked_protocol_features: 0,
socket_path: vu_cfg.socket,
epoll_thread: None,
vu_num_queues: num_queues,
migration_started: false,
});
}
let mut vu =
VhostUserHandle::connect_vhost_user(false, &vu_cfg.socket, num_queues as u64, false)?;
@@ -157,6 +183,8 @@ impl Blk {
avail_features: self.common.avail_features,
acked_features: self.common.acked_features,
config: self.config,
acked_protocol_features: self.acked_protocol_features,
vu_num_queues: self.vu_num_queues,
}
}
@@ -164,6 +192,31 @@ impl Blk {
self.common.avail_features = state.avail_features;
self.common.acked_features = state.acked_features;
self.config = state.config;
self.acked_protocol_features = state.acked_protocol_features;
self.vu_num_queues = state.vu_num_queues;
let mut vu = match VhostUserHandle::connect_vhost_user(
false,
&self.socket_path,
self.vu_num_queues as u64,
false,
) {
Ok(r) => r,
Err(e) => {
error!("Failed connecting vhost-user backend: {:?}", e);
return;
}
};
if let Err(e) = vu.set_protocol_features_vhost_user(
self.common.acked_features,
self.acked_protocol_features,
) {
error!("Failed setting up vhost-user backend: {:?}", e);
return;
}
self.vu = Some(Arc::new(Mutex::new(vu)));
}
}