diff --git a/virtio-devices/src/vhost_user/mod.rs b/virtio-devices/src/vhost_user/mod.rs index 1eee637d4..a8b3be672 100644 --- a/virtio-devices/src/vhost_user/mod.rs +++ b/virtio-devices/src/vhost_user/mod.rs @@ -657,13 +657,28 @@ impl VhostUserCommon { } pub fn pause(&mut self) -> std::result::Result<(), MigratableError> { - if let Some(vu) = &self.vu { - vu.lock().unwrap().pause_vhost_user().map_err(|e| { - MigratableError::Pause(anyhow!("Error pausing vhost-user backend: {e:?}")) - }) - } else { - Ok(()) + if self.disconnected.load(Ordering::Relaxed) { + return Err(MigratableError::DeviceDisconnected( + self.socket_path.clone(), + )); } + + if let Some(vu) = &self.vu + && let Err(e) = vu.lock().unwrap().pause_vhost_user() + { + if e.is_transport_lost() { + self.disconnected.store(true, Ordering::Relaxed); + return Err(MigratableError::DeviceDisconnected( + self.socket_path.clone(), + )); + } + + return Err(MigratableError::Pause(anyhow!( + "Error pausing vhost-user backend for socket {}: {e:?}", + self.socket_path + ))); + } + Ok(()) } pub fn resume(&mut self) -> std::result::Result<(), MigratableError> { diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index 9b9cda598..69ac8ad99 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -5526,7 +5526,13 @@ impl Pausable for DeviceManager { fn pause(&mut self) -> result::Result<(), MigratableError> { for (_, device_node) in self.device_tree.lock().unwrap().iter() { if let Some(migratable) = &device_node.migratable { - migratable.lock().unwrap().pause()?; + match migratable.lock().unwrap().pause() { + Ok(()) => {} + Err(MigratableError::DeviceDisconnected(id)) => { + warn!("Skipping pause for disconnected device {id}"); + } + Err(e) => return Err(e), + } } } // On AArch64, the pause of device manager needs to trigger