From c44049602c22c09b82ae5ca67afc2fa202d4fbf1 Mon Sep 17 00:00:00 2001 From: Wei Gao Date: Thu, 26 Aug 2021 11:59:02 +0800 Subject: [PATCH 05/10] migration: move function "transport_reset" to save state stage for vhost_vsock device. Because of vsock control protocol is not resilient to vsock packed loss, vsock device will break the connection during restoring. As a solution to this, send a "VIRTIO_VSOCK_EVENT_TRANSPORT_RESET" event when VM doing snapshot. Then vsock pack will not loss. More details about this event can be found in virtio Spec section 5.10.6.6. Signed-off-by: Wei Gao --- virtio/src/vhost/kernel/vsock.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/virtio/src/vhost/kernel/vsock.rs b/virtio/src/vhost/kernel/vsock.rs index 5c3d198..29e59af 100644 --- a/virtio/src/vhost/kernel/vsock.rs +++ b/virtio/src/vhost/kernel/vsock.rs @@ -113,7 +113,7 @@ impl Vsock { /// The `VIRTIO_VSOCK_EVENT_TRANSPORT_RESET` event indicates that communication has /// been interrupted. The driver shuts down established connections and the guest_cid /// configuration field is fetched again. - fn transport_reset(&mut self) -> Result<()> { + fn transport_reset(&self) -> Result<()> { let mut event_queue_locked = self.event_queue.as_ref().unwrap().lock().unwrap(); let element = event_queue_locked .vring @@ -136,7 +136,7 @@ impl Vsock { .chain_err(|| format!("Failed to add used ring {}", element.index))?; if let Some(interrupt_cb) = &self.interrupt_cb { - interrupt_cb(&VirtioInterruptType::Vring, None) + interrupt_cb(&VirtioInterruptType::Vring, Some(&*event_queue_locked)) .chain_err(|| ErrorKind::EventFdWrite)?; } @@ -337,6 +337,9 @@ impl StateTransfer for Vsock { self.backend.as_ref().unwrap().set_running(true), || "Failed to set vsock backend running", )?; + migration::errors::ResultExt::chain_err(self.transport_reset(), || { + "Failed to send vsock transport reset event" + })?; Ok(state.as_bytes().to_vec()) } @@ -358,10 +361,11 @@ impl StateTransfer for Vsock { } impl MigrationHook for Vsock { + #[cfg(target_arch = "aarch64")] fn resume(&mut self) -> migration::errors::Result<()> { - if let Err(e) = self.transport_reset() { - error!("Failed to resume virtio vsock device: {}", e); - } + migration::errors::ResultExt::chain_err(self.transport_reset(), || { + "Failed to resume virtio vsock device" + })?; Ok(()) } -- 2.25.1