virtio-devices: vsock: RST vsocks on snapshot restore

Otherwise guest connections just hang.

Signed-off-by: Peter Oskolkov <posk@google.com>
This commit is contained in:
Peter Oskolkov
2026-04-02 20:52:21 +00:00
committed by Bo Chen
parent f7f9895d57
commit f56c8392ea
3 changed files with 30 additions and 3 deletions

View File

@@ -323,6 +323,8 @@ pub struct Vsock<B: VsockBackend> {
pub struct VsockState {
pub avail_features: u64,
pub acked_features: u64,
#[serde(default)]
pub connections: Vec<(u32, u32)>,
}
impl<B> Vsock<B>
@@ -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<Vsock<B>> {
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(),
}
}

View File

@@ -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 {

View File

@@ -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.