diff --git a/virtio-devices/src/vsock/device.rs b/virtio-devices/src/vsock/device.rs index 6d38ecf39..25412503a 100644 --- a/virtio-devices/src/vsock/device.rs +++ b/virtio-devices/src/vsock/device.rs @@ -323,6 +323,8 @@ pub struct Vsock { pub struct VsockState { pub avail_features: u64, pub acked_features: u64, + #[serde(default)] + pub connections: Vec<(u32, u32)>, } impl Vsock @@ -336,7 +338,7 @@ where id: String, cid: u32, path: PathBuf, - backend: B, + mut backend: B, iommu: bool, seccomp_action: SeccompAction, exit_evt: EventFd, @@ -344,6 +346,9 @@ where ) -> io::Result> { let (avail_features, acked_features, paused) = if let Some(state) = state { info!("Restoring virtio-vsock {id}"); + // Instead of letting the guest connection hang/timeout, proactively let + // the guest know the connection is gone. + backend.queue_rst_for_connections(state.connections.clone()); (state.avail_features, state.acked_features, true) } else { let mut avail_features = (1u64 << VIRTIO_F_VERSION_1) | (1u64 << VIRTIO_F_IN_ORDER); @@ -378,6 +383,7 @@ where VsockState { avail_features: self.common.avail_features, acked_features: self.common.acked_features, + connections: self.backend.read().unwrap().connections(), } } diff --git a/virtio-devices/src/vsock/mod.rs b/virtio-devices/src/vsock/mod.rs index 34561f5d4..cc1ef1ad2 100644 --- a/virtio-devices/src/vsock/mod.rs +++ b/virtio-devices/src/vsock/mod.rs @@ -158,7 +158,12 @@ pub trait VsockChannel { /// It that needs to be sendable through a mpsc channel (the latter due to how `vmm::EpollContext` works). /// Currently, the only implementation we have is `crate::virtio::unix::muxer::VsockMuxer`, which /// translates guest-side vsock connections to host-side Unix domain socket connections. -pub trait VsockBackend: VsockChannel + VsockEpollListener + Send {} +pub trait VsockBackend: VsockChannel + VsockEpollListener + Send { + fn connections(&self) -> Vec<(u32, u32)> { + Vec::new() + } + fn queue_rst_for_connections(&mut self, _conns: Vec<(u32, u32)>) {} +} #[cfg(any(test, fuzzing))] pub mod unit_tests { diff --git a/virtio-devices/src/vsock/unix/muxer.rs b/virtio-devices/src/vsock/unix/muxer.rs index 1a8570b75..499c68eac 100644 --- a/virtio-devices/src/vsock/unix/muxer.rs +++ b/virtio-devices/src/vsock/unix/muxer.rs @@ -345,7 +345,23 @@ impl VsockEpollListener for VsockMuxer { } } -impl VsockBackend for VsockMuxer {} +impl VsockBackend for VsockMuxer { + fn connections(&self) -> Vec<(u32, u32)> { + self.conn_map + .keys() + .map(|k| (k.local_port, k.peer_port)) + .collect() + } + + fn queue_rst_for_connections(&mut self, conns: Vec<(u32, u32)>) { + for (local_port, peer_port) in conns { + self.rxq.push(MuxerRx::RstPkt { + local_port, + peer_port, + }); + } + } +} impl VsockMuxer { /// Muxer constructor.