Handles a `Memory` request by writing its payload to the VM memory.
(
mut socket: &mut SocketStream,
terminate_fd: &EventFd,
guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
)
| 363 | |
| 364 | // Handles a `Memory` request by writing its payload to the VM memory. |
| 365 | fn worker_receive_memory( |
| 366 | mut socket: &mut SocketStream, |
| 367 | terminate_fd: &EventFd, |
| 368 | guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>, |
| 369 | ) -> Result<(), MigratableError> { |
| 370 | loop { |
| 371 | // We only check whether we should abort when waiting for a new request. If the |
| 372 | // sender stops sending data mid-request, we will hang forever. |
| 373 | if !wait_for_readable(socket, terminate_fd) |
| 374 | .context("Failed to poll fds") |
| 375 | .map_err(MigratableError::MigrateReceive)? |
| 376 | { |
| 377 | info!("Got signal to tear down connection."); |
| 378 | return Ok(()); |
| 379 | } |
| 380 | |
| 381 | let req = match Request::read_from(&mut socket) { |
| 382 | Ok(req) => req, |
| 383 | Err(MigratableError::MigrateSocket(io_error)) |
| 384 | if io_error.kind() == ErrorKind::UnexpectedEof => |
| 385 | { |
| 386 | // EOF is only handled here while reading the next request |
| 387 | // header. Each memory chunk is fully received and acked |
| 388 | // before the worker loops back to Request::read_from(), so |
| 389 | // EOF at this point means the sender finished sending |
| 390 | // memory rather than dropping a chunk mid-transfer. |
| 391 | debug!( |
| 392 | "Connection closed by peer as expected (sender finished sending memory)" |
| 393 | ); |
| 394 | return Ok(()); |
| 395 | } |
| 396 | Err(e) => return Err(e), |
| 397 | }; |
| 398 | |
| 399 | if req.command() != Command::Memory { |
| 400 | error!( |
| 401 | "Dropping connection. Only Memory commands are allowed on additional connections." |
| 402 | ); |
| 403 | return Err(MigratableError::MigrateReceive(anyhow!( |
| 404 | "Received non memory command on migration receive worker: {:?}", |
| 405 | req.command() |
| 406 | ))); |
| 407 | } |
| 408 | |
| 409 | receive_memory_ranges(guest_memory, &req, socket)?; |
| 410 | Response::ok().write_to(socket)?; |
| 411 | } |
| 412 | } |
| 413 | |
| 414 | /// Signals to the worker threads that the migration is finished and joins them. |
| 415 | /// If any thread encountered an error, this error is returned by this function. |
nothing calls this directly
no test coverage detected