Skip to content

Commit f56c839

Browse files
posk-iolikebreath
authored andcommitted
virtio-devices: vsock: RST vsocks on snapshot restore
Otherwise guest connections just hang. Signed-off-by: Peter Oskolkov <posk@google.com>
1 parent f7f9895 commit f56c839

3 files changed

Lines changed: 30 additions & 3 deletions

File tree

virtio-devices/src/vsock/device.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,8 @@ pub struct Vsock<B: VsockBackend> {
323323
pub struct VsockState {
324324
pub avail_features: u64,
325325
pub acked_features: u64,
326+
#[serde(default)]
327+
pub connections: Vec<(u32, u32)>,
326328
}
327329

328330
impl<B> Vsock<B>
@@ -336,14 +338,17 @@ where
336338
id: String,
337339
cid: u32,
338340
path: PathBuf,
339-
backend: B,
341+
mut backend: B,
340342
iommu: bool,
341343
seccomp_action: SeccompAction,
342344
exit_evt: EventFd,
343345
state: Option<VsockState>,
344346
) -> io::Result<Vsock<B>> {
345347
let (avail_features, acked_features, paused) = if let Some(state) = state {
346348
info!("Restoring virtio-vsock {id}");
349+
// Instead of letting the guest connection hang/timeout, proactively let
350+
// the guest know the connection is gone.
351+
backend.queue_rst_for_connections(state.connections.clone());
347352
(state.avail_features, state.acked_features, true)
348353
} else {
349354
let mut avail_features = (1u64 << VIRTIO_F_VERSION_1) | (1u64 << VIRTIO_F_IN_ORDER);
@@ -378,6 +383,7 @@ where
378383
VsockState {
379384
avail_features: self.common.avail_features,
380385
acked_features: self.common.acked_features,
386+
connections: self.backend.read().unwrap().connections(),
381387
}
382388
}
383389

virtio-devices/src/vsock/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,12 @@ pub trait VsockChannel {
158158
/// It that needs to be sendable through a mpsc channel (the latter due to how `vmm::EpollContext` works).
159159
/// Currently, the only implementation we have is `crate::virtio::unix::muxer::VsockMuxer`, which
160160
/// translates guest-side vsock connections to host-side Unix domain socket connections.
161-
pub trait VsockBackend: VsockChannel + VsockEpollListener + Send {}
161+
pub trait VsockBackend: VsockChannel + VsockEpollListener + Send {
162+
fn connections(&self) -> Vec<(u32, u32)> {
163+
Vec::new()
164+
}
165+
fn queue_rst_for_connections(&mut self, _conns: Vec<(u32, u32)>) {}
166+
}
162167

163168
#[cfg(any(test, fuzzing))]
164169
pub mod unit_tests {

virtio-devices/src/vsock/unix/muxer.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,23 @@ impl VsockEpollListener for VsockMuxer {
345345
}
346346
}
347347

348-
impl VsockBackend for VsockMuxer {}
348+
impl VsockBackend for VsockMuxer {
349+
fn connections(&self) -> Vec<(u32, u32)> {
350+
self.conn_map
351+
.keys()
352+
.map(|k| (k.local_port, k.peer_port))
353+
.collect()
354+
}
355+
356+
fn queue_rst_for_connections(&mut self, conns: Vec<(u32, u32)>) {
357+
for (local_port, peer_port) in conns {
358+
self.rxq.push(MuxerRx::RstPkt {
359+
local_port,
360+
peer_port,
361+
});
362+
}
363+
}
364+
}
349365

350366
impl VsockMuxer {
351367
/// Muxer constructor.

0 commit comments

Comments
 (0)