#[macro_use]
extern crate log;
#[macro_use]
extern crate alloc;
use ax_std as _;
mod banner;
mod config;
#[cfg(any(
feature = "test-console-atomic-output",
feature = "test-console-interleave"
))]
mod console_regression;
mod guest_console;
#[cfg(feature = "http-axum")]
mod http;
mod manager;
mod shell;
mod virtio_blk;
mod virtio_net;
#[cfg(any(feature = "backtrace", feature = "test-panic-no-backtrace"))]
fn init_panic_hook() {
std::panic::set_hook(Box::new(|info| {
let backtrace = axbacktrace::Backtrace::capture().kind("panic");
let _ = ax_std::os::arceos::modules::ax_runtime::emergency_console::write_fmt(
format_args!("{info}\n{backtrace}\n"),
);
}));
}
#[cfg(feature = "test-console-atomic-output")]
fn init_atomic_output_panic_hook() {
std::panic::set_hook(Box::new(|info| {
let _ = ax_std::os::arceos::modules::ax_runtime::emergency_console::write_fmt(
format_args!("{info}\n"),
);
}));
}
fn main() {
#[cfg(feature = "test-console-atomic-output")]
init_atomic_output_panic_hook();
#[cfg(any(feature = "backtrace", feature = "test-panic-no-backtrace"))]
init_panic_hook();
#[cfg(feature = "test-backtrace-panic")]
panic!("axvisor backtrace smoke test: deliberate panic to verify backtrace output");
#[cfg(feature = "test-panic-no-backtrace")]
panic!("axvisor no-backtrace smoke test: panic without backtrace");
guest_console::configure_host_console()
.unwrap_or_else(|error| panic!("failed to configure host console: {error:#}"));
guest_console::submit_host_bytes(banner::STARTUP);
info!("Starting virtualization...");
let manager = manager::AxvmManager::new()
.unwrap_or_else(|error| panic!("failed to initialize AxVM manager: {error:#}"));
manager.init_default_vms();
#[cfg(feature = "http-axum")]
std::thread::Builder::new()
.name("axvisor-http".into())
.spawn(http::serve)
.unwrap_or_else(|error| panic!("failed to start management HTTP server: {error}"));
#[cfg(feature = "test-console-atomic-output")]
console_regression::emit_atomic_output();
#[cfg(feature = "test-console-interleave")]
console_regression::emit_interleave();
#[cfg(not(feature = "no-auto-start"))]
let started_vms = manager.launch_default_vms();
#[cfg(not(feature = "no-auto-start"))]
guest_console::attach_default(started_vms);
#[cfg(not(feature = "no-auto-start"))]
std::thread::Builder::new()
.name("axvisor-vm-wait".into())
.spawn(manager::AxvmManager::wait_for_default_vms)
.unwrap_or_else(|error| panic!("failed to start VM completion waiter: {error}"));
#[cfg(not(feature = "no-auto-start"))]
info!("[OK] Default guest initialized");
info!("shell task on CPU{}", axvm::host::cpu::current_id());
shell::console_init();
}