vmm: make migration errors more helpful

Keep the original error sources while adding operation context to the
straightforward migration send and receive paths. This keeps up a
chain of errors that can be printed nicely and in a helpful way.

This commit does that for all MigratableError-occurences where this
change is easily applicable.

Co-authored-by: Sebastian Eydam <sebastian.eydam@cyberus-technology.de>

On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
This commit is contained in:
Philipp Schuster
2026-06-25 14:34:50 +02:00
committed by Bo Chen
parent 05f026440a
commit 8c71a0d821
5 changed files with 130 additions and 117 deletions
+20 -17
View File
@@ -24,7 +24,7 @@ use std::sync::{Arc, Mutex};
use std::time::Instant;
use std::{any, cmp, result, str, thread};
use anyhow::anyhow;
use anyhow::{Context, anyhow};
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
use arch::PciSpaceInfo;
#[cfg(not(target_arch = "x86_64"))]
@@ -3019,14 +3019,12 @@ impl Vm {
{
Request::memory_fd(size_of_val(&slot) as u64)
.write_to(socket)
.map_err(|e| {
MigratableError::MigrateSend(anyhow!("Error sending memory fd request: {e}"))
})?;
.context("Error sending memory fd request")
.map_err(MigratableError::MigrateSend)?;
socket
.send_with_fd(&slot.to_le_bytes()[..], fd)
.map_err(|e| {
MigratableError::MigrateSend(anyhow!("Error sending memory fd: {e}"))
})?;
.context("Error sending memory fd")
.map_err(MigratableError::MigrateSend)?;
Response::read_from(socket)?.ok_or_abandon(
socket,
@@ -3358,9 +3356,8 @@ impl Snapshottable for Vm {
profile,
},
)
.map_err(|e| {
MigratableError::MigrateReceive(anyhow!("Error generating common cpuid: {e:?}"))
})?
.context("Error generating common cpuid")
.map_err(MigratableError::MigrateReceive)?
};
let vm_snapshot_state = VmSnapshot {
@@ -3407,15 +3404,18 @@ impl Transportable for Vm {
.write(true)
.create_new(true)
.open(snapshot_config_path)
.map_err(|e| MigratableError::MigrateSend(e.into()))?;
.context("Error creating VM config snapshot file")
.map_err(MigratableError::MigrateSend)?;
// Serialize and write the snapshot config
let vm_config = serde_json::to_string(self.config.lock().unwrap().deref())
.map_err(|e| MigratableError::MigrateSend(e.into()))?;
.context("Error serializing VM config snapshot")
.map_err(MigratableError::MigrateSend)?;
snapshot_config_file
.write(vm_config.as_bytes())
.map_err(|e| MigratableError::MigrateSend(e.into()))?;
.context("Error writing VM config snapshot")
.map_err(MigratableError::MigrateSend)?;
let mut snapshot_state_path = url_to_path(destination_url)?;
snapshot_state_path.push(SNAPSHOT_STATE_FILE);
@@ -3426,15 +3426,18 @@ impl Transportable for Vm {
.write(true)
.create_new(true)
.open(snapshot_state_path)
.map_err(|e| MigratableError::MigrateSend(e.into()))?;
.context("Error creating VM state snapshot file")
.map_err(MigratableError::MigrateSend)?;
// Serialize and write the snapshot state
let vm_state =
serde_json::to_vec(snapshot).map_err(|e| MigratableError::MigrateSend(e.into()))?;
let vm_state = serde_json::to_vec(snapshot)
.context("Error serializing VM state snapshot")
.map_err(MigratableError::MigrateSend)?;
snapshot_state_file
.write(&vm_state)
.map_err(|e| MigratableError::MigrateSend(e.into()))?;
.context("Error writing VM state snapshot")
.map_err(MigratableError::MigrateSend)?;
// Tell the memory manager to also send/write its own snapshot.
if let Some(memory_manager_snapshot) = snapshot.snapshots.get(MEMORY_MANAGER_SNAPSHOT_ID) {