mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm: migration: print whole error chain on error
In [0] we agreed on the current format. When ch-remote or
cloud-hypervisor exit with an error, they nicely print the whole chain.
This, however, doesn't work when simply doing `error!("error: {e}")`
- which is what we currently do for migration-related errors.
This commit walks the chain of errors and prints all components in a
single line. This massively improves the quality of error messages and
helps tracing down where an error is originating from. Using ` => ` as
separator is better than `\n` which doesn't work well in our current
log format.
# Example (Before - Bad)
```
cloud-hypervisor: 2.859287s: <vmm> ERROR:vmm/src/lib.rs:2021 -- Migration failed: Failed to send migratable component snapshot
```
# Example (New - Better)
```
cloud-hypervisor: 2.296160s: <vmm> ERROR:vmm/src/lib.rs:2038 -- Migration failed: Failed to send migratable component snapshot => Error connecting to TCP socket => Connection refused (os error 111)
```
[0] https://github.com/cloud-hypervisor/cloud-hypervisor/pull/7066
On-behalf-of: SAP philipp.schuster@sap.com
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
This commit is contained in:
committed by
Bo Chen
parent
8c71a0d821
commit
252702049e
@@ -4,6 +4,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::error::Error as StdError;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{Read, Write, stdout};
|
use std::io::{Read, Write, stdout};
|
||||||
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, FromRawFd, RawFd};
|
||||||
@@ -15,7 +16,7 @@ use std::sync::mpsc;
|
|||||||
use std::sync::mpsc::{Receiver, RecvError, SendError, Sender, channel};
|
use std::sync::mpsc::{Receiver, RecvError, SendError, Sender, channel};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use std::{any, io, mem, panic, path, process, result, thread};
|
use std::{any, io, iter, mem, panic, path, process, result, thread};
|
||||||
|
|
||||||
use anyhow::{Context, anyhow};
|
use anyhow::{Context, anyhow};
|
||||||
#[cfg(feature = "dbus_api")]
|
#[cfg(feature = "dbus_api")]
|
||||||
@@ -2018,7 +2019,22 @@ impl Vmm {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Migration failed: {e}");
|
// Mimic the error chain that CH prints on error in the log.
|
||||||
|
// Required to get useful error messages in the log.
|
||||||
|
let top_error: &dyn StdError = &e;
|
||||||
|
let error_chain_str = {
|
||||||
|
iter::successors(Some(top_error), |sub_error| {
|
||||||
|
// Dereference necessary to mitigate rustc compiler bug.
|
||||||
|
// See <https://github.com/rust-lang/rust/issues/141673>
|
||||||
|
(*sub_error).source()
|
||||||
|
})
|
||||||
|
// Important to use the plain Display impl to not interfere
|
||||||
|
// with anyhow's "smart" printing
|
||||||
|
.map(|e| format!("{e}"))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(" => ")
|
||||||
|
};
|
||||||
|
error!("Migration failed: {error_chain_str}");
|
||||||
try_resume_vm_after_failed_migration(vm);
|
try_resume_vm_after_failed_migration(vm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user