mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: allow keeping the socket listener around
This allows accepting multiple connections in the migration receive path. On-behalf-of: SAP sebastian.eydam@sap.com Signed-off-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>
This commit is contained in:
+3
-2
@@ -2298,9 +2298,10 @@ impl RequestHandler for Vmm {
|
|||||||
receive_data_migration.receiver_url
|
receive_data_migration.receiver_url
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let mut listener =
|
||||||
|
migration_transport::receive_migration_listener(&receive_data_migration.receiver_url)?;
|
||||||
// Accept the connection and get the socket
|
// Accept the connection and get the socket
|
||||||
let mut socket =
|
let mut socket = listener.accept()?;
|
||||||
migration_transport::receive_migration_socket(&receive_data_migration.receiver_url)?;
|
|
||||||
|
|
||||||
event!("vm", "migration-receive-started");
|
event!("vm", "migration-receive-started");
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,31 @@ use vm_migration::{MigratableError, Snapshot};
|
|||||||
|
|
||||||
use crate::{GuestMemoryMmap, VmMigrationConfig};
|
use crate::{GuestMemoryMmap, VmMigrationConfig};
|
||||||
|
|
||||||
|
/// Transport-agnostic listener used to receive connections.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(crate) enum ReceiveListener {
|
||||||
|
Tcp(TcpListener),
|
||||||
|
Unix(UnixListener),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ReceiveListener {
|
||||||
|
/// Block until a connection is accepted.
|
||||||
|
pub(crate) fn accept(&mut self) -> Result<SocketStream, MigratableError> {
|
||||||
|
match self {
|
||||||
|
ReceiveListener::Tcp(listener) => listener
|
||||||
|
.accept()
|
||||||
|
.map(|(socket, _)| SocketStream::Tcp(socket))
|
||||||
|
.context("Failed to accept TCP migration connection")
|
||||||
|
.map_err(MigratableError::MigrateReceive),
|
||||||
|
ReceiveListener::Unix(listener) => listener
|
||||||
|
.accept()
|
||||||
|
.map(|(socket, _)| SocketStream::Unix(socket))
|
||||||
|
.context("Failed to accept Unix migration connection")
|
||||||
|
.map_err(MigratableError::MigrateReceive),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Transport-agnostic stream used by the migration protocol.
|
/// Transport-agnostic stream used by the migration protocol.
|
||||||
pub(crate) enum SocketStream {
|
pub(crate) enum SocketStream {
|
||||||
Unix(UnixStream),
|
Unix(UnixStream),
|
||||||
@@ -138,35 +163,21 @@ pub(crate) fn send_migration_socket(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Bind and accept a migration connection for the receiver side.
|
/// Bind a migration listener for the receiver side.
|
||||||
pub(crate) fn receive_migration_socket(
|
pub(crate) fn receive_migration_listener(
|
||||||
receiver_url: &str,
|
receiver_url: &str,
|
||||||
) -> Result<SocketStream, MigratableError> {
|
) -> Result<ReceiveListener, MigratableError> {
|
||||||
if let Some(address) = receiver_url.strip_prefix("tcp:") {
|
if let Some(address) = receiver_url.strip_prefix("tcp:") {
|
||||||
let listener = TcpListener::bind(address).map_err(|e| {
|
TcpListener::bind(address)
|
||||||
MigratableError::MigrateReceive(anyhow!("Error binding to TCP socket: {e}"))
|
.map(ReceiveListener::Tcp)
|
||||||
})?;
|
.context("Error binding to TCP socket")
|
||||||
|
.map_err(MigratableError::MigrateReceive)
|
||||||
let (socket, _addr) = listener.accept().map_err(|e| {
|
|
||||||
MigratableError::MigrateReceive(anyhow!(
|
|
||||||
"Error accepting connection on TCP socket: {e}"
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(SocketStream::Tcp(socket))
|
|
||||||
} else {
|
} else {
|
||||||
let path = socket_url_to_path(receiver_url).map_err(MigratableError::MigrateSend)?;
|
let path = socket_url_to_path(receiver_url).map_err(MigratableError::MigrateReceive)?;
|
||||||
let listener = UnixListener::bind(&path).map_err(|e| {
|
UnixListener::bind(&path)
|
||||||
MigratableError::MigrateReceive(anyhow!("Error binding to UNIX socket: {e}"))
|
.map(ReceiveListener::Unix)
|
||||||
})?;
|
.context("Error binding to UNIX socket")
|
||||||
|
.map_err(MigratableError::MigrateReceive)
|
||||||
let (socket, _addr) = listener.accept().map_err(|e| {
|
|
||||||
MigratableError::MigrateReceive(anyhow!(
|
|
||||||
"Error accepting connection on UNIX socket: {e}"
|
|
||||||
))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(SocketStream::Unix(socket))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user