@@ -32,6 +32,10 @@ use vmm_sys_util::eventfd::EventFd;
3232use crate :: sync_utils:: Gate ;
3333use crate :: { GuestMemoryMmap , VmMigrationConfig } ;
3434
35+ /// Hard upper bound for migration worker connections on both the sender and
36+ /// receiver side.
37+ pub ( crate ) const MAX_MIGRATION_CONNECTIONS : u32 = 128 ;
38+
3539/// Transport-agnostic listener used to receive connections.
3640#[ derive( Debug ) ]
3741pub ( crate ) enum ReceiveListener {
@@ -288,12 +292,30 @@ impl ReceiveAdditionalConnections {
288292 guest_memory : & GuestMemoryAtomic < GuestMemoryMmap > ,
289293 ) -> Result < ( ) , MigratableError > {
290294 let mut threads: Vec < thread:: JoinHandle < Result < ( ) , MigratableError > > > = Vec :: new ( ) ;
291- while let Some ( mut socket) = listener. abortable_accept ( terminate_fd) ? {
295+ let mut first_err = loop {
296+ let socket = match listener. abortable_accept ( terminate_fd) {
297+ Ok ( socket) => socket,
298+ Err ( e) => break Err ( e) ,
299+ } ;
300+ let Some ( mut socket) = socket else {
301+ break Ok ( ( ) ) ;
302+ } ;
303+
304+ if threads. len ( ) >= MAX_MIGRATION_CONNECTIONS as usize {
305+ break Err ( MigratableError :: MigrateReceive ( anyhow ! (
306+ "Received more than {MAX_MIGRATION_CONNECTIONS} additional migration connections."
307+ ) ) ) ;
308+ }
309+
292310 let guest_memory = guest_memory. clone ( ) ;
293- let terminate_fd = terminate_fd
311+ let terminate_fd = match terminate_fd
294312 . try_clone ( )
295313 . context ( "Error cloning terminate fd" )
296- . map_err ( MigratableError :: MigrateReceive ) ?;
314+ . map_err ( MigratableError :: MigrateReceive )
315+ {
316+ Ok ( terminate_fd) => terminate_fd,
317+ Err ( e) => break Err ( e) ,
318+ } ;
297319
298320 match thread:: Builder :: new ( )
299321 . name ( format ! ( "migrate-receive-memory-{}" , threads. len( ) ) . to_owned ( ) )
@@ -303,15 +325,21 @@ impl ReceiveAdditionalConnections {
303325 Ok ( t) => threads. push ( t) ,
304326 Err ( e) => {
305327 error ! ( "Error spawning receive-memory thread: {e}" ) ;
306- break ;
328+ break Err ( MigratableError :: MigrateReceive (
329+ anyhow ! ( e) . context ( "Error spawning receive-memory thread" ) ,
330+ ) ) ;
307331 }
308332 }
333+ } ;
334+
335+ if first_err. is_err ( ) {
336+ warn ! ( "Signaling termination due to an error while accepting connections." ) ;
337+ let _ = terminate_fd. write ( 1 ) ;
309338 }
310339
311340 info ! ( "Stopped accepting additional connections. Cleaning up threads." ) ;
312341
313342 // We only return the first error we encounter here.
314- let mut first_err = Ok ( ( ) ) ;
315343 for thread in threads {
316344 let err = match thread. join ( ) {
317345 Ok ( Ok ( ( ) ) ) => None ,
0 commit comments