mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
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:
@@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user