1 // Copyright © 2019 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 6 #![allow(clippy::significant_drop_in_scrutinee)] 7 8 #[macro_use] 9 extern crate event_monitor; 10 #[macro_use] 11 extern crate log; 12 13 use crate::api::{ 14 ApiError, ApiRequest, ApiResponse, ApiResponsePayload, VmInfo, VmReceiveMigrationData, 15 VmSendMigrationData, VmmPingResponse, 16 }; 17 use crate::config::{ 18 add_to_config, DeviceConfig, DiskConfig, FsConfig, NetConfig, PmemConfig, RestoreConfig, 19 UserDeviceConfig, VdpaConfig, VmConfig, VsockConfig, 20 }; 21 #[cfg(feature = "guest_debug")] 22 use crate::coredump::GuestDebuggable; 23 use crate::memory_manager::MemoryManager; 24 #[cfg(all(feature = "kvm", target_arch = "x86_64"))] 25 use crate::migration::get_vm_snapshot; 26 use crate::migration::{recv_vm_config, recv_vm_state}; 27 use crate::seccomp_filters::{get_seccomp_filter, Thread}; 28 use crate::vm::{Error as VmError, Vm, VmState}; 29 use anyhow::anyhow; 30 use libc::{EFD_NONBLOCK, SIGINT, SIGTERM}; 31 use memory_manager::MemoryManagerSnapshotData; 32 use pci::PciBdf; 33 use seccompiler::{apply_filter, SeccompAction}; 34 use serde::ser::{SerializeStruct, Serializer}; 35 use serde::{Deserialize, Serialize}; 36 use signal_hook::iterator::{Handle, Signals}; 37 use std::collections::HashMap; 38 use std::fs::File; 39 use std::io; 40 use std::io::{Read, Write}; 41 use std::os::unix::io::{AsRawFd, FromRawFd, RawFd}; 42 use std::os::unix::net::UnixListener; 43 use std::os::unix::net::UnixStream; 44 use std::panic::AssertUnwindSafe; 45 use std::path::PathBuf; 46 use std::sync::mpsc::{Receiver, RecvError, SendError, Sender}; 47 use std::sync::{Arc, Mutex}; 48 use std::time::Instant; 49 use std::{result, thread}; 50 use thiserror::Error; 51 use tracer::trace_scoped; 52 use vm_memory::bitmap::AtomicBitmap; 53 use vm_migration::{protocol::*, Migratable}; 54 use vm_migration::{MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; 55 use vmm_sys_util::eventfd::EventFd; 56 use vmm_sys_util::signal::unblock_signal; 57 use vmm_sys_util::sock_ctrl_msg::ScmSocket; 58 use vmm_sys_util::terminal::Terminal; 59 60 mod acpi; 61 pub mod api; 62 mod clone3; 63 pub mod config; 64 #[cfg(feature = "guest_debug")] 65 mod coredump; 66 pub mod cpu; 67 pub mod device_manager; 68 pub mod device_tree; 69 #[cfg(feature = "guest_debug")] 70 mod gdb; 71 pub mod interrupt; 72 pub mod memory_manager; 73 pub mod migration; 74 mod pci_segment; 75 pub mod seccomp_filters; 76 mod serial_manager; 77 mod sigwinch_listener; 78 pub mod vm; 79 pub mod vm_config; 80 81 type GuestMemoryMmap = vm_memory::GuestMemoryMmap<AtomicBitmap>; 82 type GuestRegionMmap = vm_memory::GuestRegionMmap<AtomicBitmap>; 83 84 /// Errors associated with VMM management 85 #[derive(Debug, Error)] 86 #[allow(clippy::large_enum_variant)] 87 pub enum Error { 88 /// API request receive error 89 #[error("Error receiving API request: {0}")] 90 ApiRequestRecv(#[source] RecvError), 91 92 /// API response send error 93 #[error("Error sending API request: {0}")] 94 ApiResponseSend(#[source] SendError<ApiResponse>), 95 96 /// Cannot bind to the UNIX domain socket path 97 #[error("Error binding to UNIX domain socket: {0}")] 98 Bind(#[source] io::Error), 99 100 /// Cannot clone EventFd. 101 #[error("Error cloning EventFd: {0}")] 102 EventFdClone(#[source] io::Error), 103 104 /// Cannot create EventFd. 105 #[error("Error creating EventFd: {0}")] 106 EventFdCreate(#[source] io::Error), 107 108 /// Cannot read from EventFd. 109 #[error("Error reading from EventFd: {0}")] 110 EventFdRead(#[source] io::Error), 111 112 /// Cannot create epoll context. 113 #[error("Error creating epoll context: {0}")] 114 Epoll(#[source] io::Error), 115 116 /// Cannot create HTTP thread 117 #[error("Error spawning HTTP thread: {0}")] 118 HttpThreadSpawn(#[source] io::Error), 119 120 /// Cannot handle the VM STDIN stream 121 #[error("Error handling VM stdin: {0:?}")] 122 Stdin(VmError), 123 124 /// Cannot handle the VM pty stream 125 #[error("Error handling VM pty: {0:?}")] 126 Pty(VmError), 127 128 /// Cannot reboot the VM 129 #[error("Error rebooting VM: {0:?}")] 130 VmReboot(VmError), 131 132 /// Cannot create VMM thread 133 #[error("Error spawning VMM thread {0:?}")] 134 VmmThreadSpawn(#[source] io::Error), 135 136 /// Cannot shut the VMM down 137 #[error("Error shutting down VMM: {0:?}")] 138 VmmShutdown(VmError), 139 140 /// Cannot create seccomp filter 141 #[error("Error creating seccomp filter: {0}")] 142 CreateSeccompFilter(seccompiler::Error), 143 144 /// Cannot apply seccomp filter 145 #[error("Error applying seccomp filter: {0}")] 146 ApplySeccompFilter(seccompiler::Error), 147 148 /// Error activating virtio devices 149 #[error("Error activating virtio devices: {0:?}")] 150 ActivateVirtioDevices(VmError), 151 152 /// Error creating API server 153 #[error("Error creating API server {0:?}")] 154 CreateApiServer(micro_http::ServerError), 155 156 /// Error binding API server socket 157 #[error("Error creation API server's socket {0:?}")] 158 CreateApiServerSocket(#[source] io::Error), 159 160 #[cfg(feature = "guest_debug")] 161 #[error("Failed to start the GDB thread: {0}")] 162 GdbThreadSpawn(io::Error), 163 164 /// GDB request receive error 165 #[cfg(feature = "guest_debug")] 166 #[error("Error receiving GDB request: {0}")] 167 GdbRequestRecv(#[source] RecvError), 168 169 /// GDB response send error 170 #[cfg(feature = "guest_debug")] 171 #[error("Error sending GDB request: {0}")] 172 GdbResponseSend(#[source] SendError<gdb::GdbResponse>), 173 174 #[error("Cannot spawn a signal handler thread: {0}")] 175 SignalHandlerSpawn(#[source] io::Error), 176 177 #[error("Failed to join on threads: {0:?}")] 178 ThreadCleanup(std::boxed::Box<dyn std::any::Any + std::marker::Send>), 179 } 180 pub type Result<T> = result::Result<T, Error>; 181 182 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 183 #[repr(u64)] 184 pub enum EpollDispatch { 185 Exit = 0, 186 Reset = 1, 187 Api = 2, 188 ActivateVirtioDevices = 3, 189 Debug = 4, 190 Unknown, 191 } 192 193 impl From<u64> for EpollDispatch { 194 fn from(v: u64) -> Self { 195 use EpollDispatch::*; 196 match v { 197 0 => Exit, 198 1 => Reset, 199 2 => Api, 200 3 => ActivateVirtioDevices, 201 4 => Debug, 202 _ => Unknown, 203 } 204 } 205 } 206 207 pub struct EpollContext { 208 epoll_file: File, 209 } 210 211 impl EpollContext { 212 pub fn new() -> result::Result<EpollContext, io::Error> { 213 let epoll_fd = epoll::create(true)?; 214 // Use 'File' to enforce closing on 'epoll_fd' 215 // SAFETY: the epoll_fd returned by epoll::create is valid and owned by us. 216 let epoll_file = unsafe { File::from_raw_fd(epoll_fd) }; 217 218 Ok(EpollContext { epoll_file }) 219 } 220 221 pub fn add_event<T>(&mut self, fd: &T, token: EpollDispatch) -> result::Result<(), io::Error> 222 where 223 T: AsRawFd, 224 { 225 let dispatch_index = token as u64; 226 epoll::ctl( 227 self.epoll_file.as_raw_fd(), 228 epoll::ControlOptions::EPOLL_CTL_ADD, 229 fd.as_raw_fd(), 230 epoll::Event::new(epoll::Events::EPOLLIN, dispatch_index), 231 )?; 232 233 Ok(()) 234 } 235 } 236 237 impl AsRawFd for EpollContext { 238 fn as_raw_fd(&self) -> RawFd { 239 self.epoll_file.as_raw_fd() 240 } 241 } 242 243 pub struct PciDeviceInfo { 244 pub id: String, 245 pub bdf: PciBdf, 246 } 247 248 impl Serialize for PciDeviceInfo { 249 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error> 250 where 251 S: Serializer, 252 { 253 let bdf_str = self.bdf.to_string(); 254 255 // Serialize the structure. 256 let mut state = serializer.serialize_struct("PciDeviceInfo", 2)?; 257 state.serialize_field("id", &self.id)?; 258 state.serialize_field("bdf", &bdf_str)?; 259 state.end() 260 } 261 } 262 263 #[allow(unused_variables)] 264 #[allow(clippy::too_many_arguments)] 265 pub fn start_vmm_thread( 266 vmm_version: String, 267 http_path: &Option<String>, 268 http_fd: Option<RawFd>, 269 api_event: EventFd, 270 api_sender: Sender<ApiRequest>, 271 api_receiver: Receiver<ApiRequest>, 272 #[cfg(feature = "guest_debug")] debug_path: Option<PathBuf>, 273 #[cfg(feature = "guest_debug")] debug_event: EventFd, 274 #[cfg(feature = "guest_debug")] vm_debug_event: EventFd, 275 seccomp_action: &SeccompAction, 276 hypervisor: Arc<dyn hypervisor::Hypervisor>, 277 ) -> Result<thread::JoinHandle<Result<()>>> { 278 #[cfg(feature = "guest_debug")] 279 let gdb_hw_breakpoints = hypervisor.get_guest_debug_hw_bps(); 280 #[cfg(feature = "guest_debug")] 281 let (gdb_sender, gdb_receiver) = std::sync::mpsc::channel(); 282 #[cfg(feature = "guest_debug")] 283 let gdb_debug_event = debug_event.try_clone().map_err(Error::EventFdClone)?; 284 #[cfg(feature = "guest_debug")] 285 let gdb_vm_debug_event = vm_debug_event.try_clone().map_err(Error::EventFdClone)?; 286 287 let http_api_event = api_event.try_clone().map_err(Error::EventFdClone)?; 288 let hypervisor_type = hypervisor.hypervisor_type(); 289 290 // Retrieve seccomp filter 291 let vmm_seccomp_filter = get_seccomp_filter(seccomp_action, Thread::Vmm, hypervisor_type) 292 .map_err(Error::CreateSeccompFilter)?; 293 294 let vmm_seccomp_action = seccomp_action.clone(); 295 let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdCreate)?; 296 let thread = { 297 let exit_evt = exit_evt.try_clone().map_err(Error::EventFdClone)?; 298 thread::Builder::new() 299 .name("vmm".to_string()) 300 .spawn(move || { 301 // Apply seccomp filter for VMM thread. 302 if !vmm_seccomp_filter.is_empty() { 303 apply_filter(&vmm_seccomp_filter).map_err(Error::ApplySeccompFilter)?; 304 } 305 306 let mut vmm = Vmm::new( 307 vmm_version.to_string(), 308 api_event, 309 #[cfg(feature = "guest_debug")] 310 debug_event, 311 #[cfg(feature = "guest_debug")] 312 vm_debug_event, 313 vmm_seccomp_action, 314 hypervisor, 315 exit_evt, 316 )?; 317 318 vmm.setup_signal_handler()?; 319 320 vmm.control_loop( 321 Arc::new(api_receiver), 322 #[cfg(feature = "guest_debug")] 323 Arc::new(gdb_receiver), 324 ) 325 }) 326 .map_err(Error::VmmThreadSpawn)? 327 }; 328 329 // The VMM thread is started, we can start serving HTTP requests 330 if let Some(http_path) = http_path { 331 api::start_http_path_thread( 332 http_path, 333 http_api_event, 334 api_sender, 335 seccomp_action, 336 exit_evt, 337 hypervisor_type, 338 )?; 339 } else if let Some(http_fd) = http_fd { 340 api::start_http_fd_thread( 341 http_fd, 342 http_api_event, 343 api_sender, 344 seccomp_action, 345 exit_evt, 346 hypervisor_type, 347 )?; 348 } 349 350 #[cfg(feature = "guest_debug")] 351 if let Some(debug_path) = debug_path { 352 let target = gdb::GdbStub::new( 353 gdb_sender, 354 gdb_debug_event, 355 gdb_vm_debug_event, 356 gdb_hw_breakpoints, 357 ); 358 thread::Builder::new() 359 .name("gdb".to_owned()) 360 .spawn(move || gdb::gdb_thread(target, &debug_path)) 361 .map_err(Error::GdbThreadSpawn)?; 362 } 363 364 Ok(thread) 365 } 366 367 #[derive(Clone, Deserialize, Serialize)] 368 struct VmMigrationConfig { 369 vm_config: Arc<Mutex<VmConfig>>, 370 #[cfg(all(feature = "kvm", target_arch = "x86_64"))] 371 common_cpuid: Vec<hypervisor::arch::x86::CpuIdEntry>, 372 memory_manager_data: MemoryManagerSnapshotData, 373 } 374 375 pub struct Vmm { 376 epoll: EpollContext, 377 exit_evt: EventFd, 378 reset_evt: EventFd, 379 api_evt: EventFd, 380 #[cfg(feature = "guest_debug")] 381 debug_evt: EventFd, 382 #[cfg(feature = "guest_debug")] 383 vm_debug_evt: EventFd, 384 version: String, 385 vm: Option<Vm>, 386 vm_config: Option<Arc<Mutex<VmConfig>>>, 387 seccomp_action: SeccompAction, 388 hypervisor: Arc<dyn hypervisor::Hypervisor>, 389 activate_evt: EventFd, 390 signals: Option<Handle>, 391 threads: Vec<thread::JoinHandle<()>>, 392 } 393 394 impl Vmm { 395 pub const HANDLED_SIGNALS: [i32; 2] = [SIGTERM, SIGINT]; 396 397 fn signal_handler(mut signals: Signals, on_tty: bool, exit_evt: &EventFd) { 398 for sig in &Self::HANDLED_SIGNALS { 399 unblock_signal(*sig).unwrap(); 400 } 401 402 for signal in signals.forever() { 403 match signal { 404 SIGTERM | SIGINT => { 405 if exit_evt.write(1).is_err() { 406 // Resetting the terminal is usually done as the VMM exits 407 if on_tty { 408 io::stdin() 409 .lock() 410 .set_canon_mode() 411 .expect("failed to restore terminal mode"); 412 } 413 std::process::exit(1); 414 } 415 } 416 _ => (), 417 } 418 } 419 } 420 421 fn setup_signal_handler(&mut self) -> Result<()> { 422 let signals = Signals::new(Self::HANDLED_SIGNALS); 423 match signals { 424 Ok(signals) => { 425 self.signals = Some(signals.handle()); 426 let exit_evt = self.exit_evt.try_clone().map_err(Error::EventFdClone)?; 427 // SAFETY: trivially safe 428 let on_tty = unsafe { libc::isatty(libc::STDIN_FILENO) } != 0; 429 430 let signal_handler_seccomp_filter = get_seccomp_filter( 431 &self.seccomp_action, 432 Thread::SignalHandler, 433 self.hypervisor.hypervisor_type(), 434 ) 435 .map_err(Error::CreateSeccompFilter)?; 436 self.threads.push( 437 thread::Builder::new() 438 .name("vmm_signal_handler".to_string()) 439 .spawn(move || { 440 if !signal_handler_seccomp_filter.is_empty() { 441 if let Err(e) = apply_filter(&signal_handler_seccomp_filter) 442 .map_err(Error::ApplySeccompFilter) 443 { 444 error!("Error applying seccomp filter: {:?}", e); 445 exit_evt.write(1).ok(); 446 return; 447 } 448 } 449 std::panic::catch_unwind(AssertUnwindSafe(|| { 450 Vmm::signal_handler(signals, on_tty, &exit_evt); 451 })) 452 .map_err(|_| { 453 error!("signal_handler thead panicked"); 454 exit_evt.write(1).ok() 455 }) 456 .ok(); 457 }) 458 .map_err(Error::SignalHandlerSpawn)?, 459 ); 460 } 461 Err(e) => error!("Signal not found {}", e), 462 } 463 Ok(()) 464 } 465 466 fn new( 467 vmm_version: String, 468 api_evt: EventFd, 469 #[cfg(feature = "guest_debug")] debug_evt: EventFd, 470 #[cfg(feature = "guest_debug")] vm_debug_evt: EventFd, 471 seccomp_action: SeccompAction, 472 hypervisor: Arc<dyn hypervisor::Hypervisor>, 473 exit_evt: EventFd, 474 ) -> Result<Self> { 475 let mut epoll = EpollContext::new().map_err(Error::Epoll)?; 476 let reset_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdCreate)?; 477 let activate_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdCreate)?; 478 479 epoll 480 .add_event(&exit_evt, EpollDispatch::Exit) 481 .map_err(Error::Epoll)?; 482 483 epoll 484 .add_event(&reset_evt, EpollDispatch::Reset) 485 .map_err(Error::Epoll)?; 486 487 epoll 488 .add_event(&activate_evt, EpollDispatch::ActivateVirtioDevices) 489 .map_err(Error::Epoll)?; 490 491 epoll 492 .add_event(&api_evt, EpollDispatch::Api) 493 .map_err(Error::Epoll)?; 494 495 #[cfg(feature = "guest_debug")] 496 epoll 497 .add_event(&debug_evt, EpollDispatch::Debug) 498 .map_err(Error::Epoll)?; 499 500 Ok(Vmm { 501 epoll, 502 exit_evt, 503 reset_evt, 504 api_evt, 505 #[cfg(feature = "guest_debug")] 506 debug_evt, 507 #[cfg(feature = "guest_debug")] 508 vm_debug_evt, 509 version: vmm_version, 510 vm: None, 511 vm_config: None, 512 seccomp_action, 513 hypervisor, 514 activate_evt, 515 signals: None, 516 threads: vec![], 517 }) 518 } 519 520 fn vm_create(&mut self, config: Arc<Mutex<VmConfig>>) -> result::Result<(), VmError> { 521 // We only store the passed VM config. 522 // The VM will be created when being asked to boot it. 523 if self.vm_config.is_none() { 524 self.vm_config = Some(config); 525 Ok(()) 526 } else { 527 Err(VmError::VmAlreadyCreated) 528 } 529 } 530 531 fn vm_boot(&mut self) -> result::Result<(), VmError> { 532 tracer::start(); 533 let r = { 534 trace_scoped!("vm_boot"); 535 // If we don't have a config, we can not boot a VM. 536 if self.vm_config.is_none() { 537 return Err(VmError::VmMissingConfig); 538 }; 539 540 // Create a new VM if we don't have one yet. 541 if self.vm.is_none() { 542 let exit_evt = self.exit_evt.try_clone().map_err(VmError::EventFdClone)?; 543 let reset_evt = self.reset_evt.try_clone().map_err(VmError::EventFdClone)?; 544 #[cfg(feature = "guest_debug")] 545 let vm_debug_evt = self 546 .vm_debug_evt 547 .try_clone() 548 .map_err(VmError::EventFdClone)?; 549 let activate_evt = self 550 .activate_evt 551 .try_clone() 552 .map_err(VmError::EventFdClone)?; 553 554 if let Some(ref vm_config) = self.vm_config { 555 let vm = Vm::new( 556 Arc::clone(vm_config), 557 exit_evt, 558 reset_evt, 559 #[cfg(feature = "guest_debug")] 560 vm_debug_evt, 561 &self.seccomp_action, 562 self.hypervisor.clone(), 563 activate_evt, 564 None, 565 None, 566 None, 567 )?; 568 569 self.vm = Some(vm); 570 } 571 } 572 573 // Now we can boot the VM. 574 if let Some(ref mut vm) = self.vm { 575 vm.boot() 576 } else { 577 Err(VmError::VmNotCreated) 578 } 579 }; 580 tracer::end(); 581 r 582 } 583 584 fn vm_pause(&mut self) -> result::Result<(), VmError> { 585 if let Some(ref mut vm) = self.vm { 586 vm.pause().map_err(VmError::Pause) 587 } else { 588 Err(VmError::VmNotRunning) 589 } 590 } 591 592 fn vm_resume(&mut self) -> result::Result<(), VmError> { 593 if let Some(ref mut vm) = self.vm { 594 vm.resume().map_err(VmError::Resume) 595 } else { 596 Err(VmError::VmNotRunning) 597 } 598 } 599 600 fn vm_snapshot(&mut self, destination_url: &str) -> result::Result<(), VmError> { 601 if let Some(ref mut vm) = self.vm { 602 vm.snapshot() 603 .map_err(VmError::Snapshot) 604 .and_then(|snapshot| { 605 vm.send(&snapshot, destination_url) 606 .map_err(VmError::SnapshotSend) 607 }) 608 } else { 609 Err(VmError::VmNotRunning) 610 } 611 } 612 613 fn vm_restore(&mut self, restore_cfg: RestoreConfig) -> result::Result<(), VmError> { 614 if self.vm.is_some() || self.vm_config.is_some() { 615 return Err(VmError::VmAlreadyCreated); 616 } 617 618 let source_url = restore_cfg.source_url.as_path().to_str(); 619 if source_url.is_none() { 620 return Err(VmError::InvalidRestoreSourceUrl); 621 } 622 // Safe to unwrap as we checked it was Some(&str). 623 let source_url = source_url.unwrap(); 624 625 let vm_config = Arc::new(Mutex::new( 626 recv_vm_config(source_url).map_err(VmError::Restore)?, 627 )); 628 let snapshot = recv_vm_state(source_url).map_err(VmError::Restore)?; 629 #[cfg(all(feature = "kvm", target_arch = "x86_64"))] 630 let vm_snapshot = get_vm_snapshot(&snapshot).map_err(VmError::Restore)?; 631 632 #[cfg(all(feature = "kvm", target_arch = "x86_64"))] 633 self.vm_check_cpuid_compatibility(&vm_config, &vm_snapshot.common_cpuid) 634 .map_err(VmError::Restore)?; 635 636 self.vm_config = Some(Arc::clone(&vm_config)); 637 638 let exit_evt = self.exit_evt.try_clone().map_err(VmError::EventFdClone)?; 639 let reset_evt = self.reset_evt.try_clone().map_err(VmError::EventFdClone)?; 640 #[cfg(feature = "guest_debug")] 641 let debug_evt = self 642 .vm_debug_evt 643 .try_clone() 644 .map_err(VmError::EventFdClone)?; 645 let activate_evt = self 646 .activate_evt 647 .try_clone() 648 .map_err(VmError::EventFdClone)?; 649 650 let vm = Vm::new_from_snapshot( 651 &snapshot, 652 vm_config, 653 exit_evt, 654 reset_evt, 655 #[cfg(feature = "guest_debug")] 656 debug_evt, 657 Some(source_url), 658 restore_cfg.prefault, 659 &self.seccomp_action, 660 self.hypervisor.clone(), 661 activate_evt, 662 )?; 663 self.vm = Some(vm); 664 665 // Now we can restore the rest of the VM. 666 if let Some(ref mut vm) = self.vm { 667 vm.restore(snapshot).map_err(VmError::Restore) 668 } else { 669 Err(VmError::VmNotCreated) 670 } 671 } 672 673 #[cfg(feature = "guest_debug")] 674 fn vm_coredump(&mut self, destination_url: &str) -> result::Result<(), VmError> { 675 if let Some(ref mut vm) = self.vm { 676 vm.coredump(destination_url).map_err(VmError::Coredump) 677 } else { 678 Err(VmError::VmNotRunning) 679 } 680 } 681 682 fn vm_shutdown(&mut self) -> result::Result<(), VmError> { 683 if let Some(ref mut vm) = self.vm.take() { 684 vm.shutdown() 685 } else { 686 Err(VmError::VmNotRunning) 687 } 688 } 689 690 fn vm_reboot(&mut self) -> result::Result<(), VmError> { 691 // First we stop the current VM 692 let (config, serial_pty, console_pty, console_resize_pipe) = 693 if let Some(mut vm) = self.vm.take() { 694 let config = vm.get_config(); 695 let serial_pty = vm.serial_pty(); 696 let console_pty = vm.console_pty(); 697 let console_resize_pipe = vm 698 .console_resize_pipe() 699 .as_ref() 700 .map(|pipe| pipe.try_clone().unwrap()); 701 vm.shutdown()?; 702 (config, serial_pty, console_pty, console_resize_pipe) 703 } else { 704 return Err(VmError::VmNotCreated); 705 }; 706 707 let exit_evt = self.exit_evt.try_clone().map_err(VmError::EventFdClone)?; 708 let reset_evt = self.reset_evt.try_clone().map_err(VmError::EventFdClone)?; 709 #[cfg(feature = "guest_debug")] 710 let debug_evt = self 711 .vm_debug_evt 712 .try_clone() 713 .map_err(VmError::EventFdClone)?; 714 let activate_evt = self 715 .activate_evt 716 .try_clone() 717 .map_err(VmError::EventFdClone)?; 718 719 // The Linux kernel fires off an i8042 reset after doing the ACPI reset so there may be 720 // an event sitting in the shared reset_evt. Without doing this we get very early reboots 721 // during the boot process. 722 if self.reset_evt.read().is_ok() { 723 warn!("Spurious second reset event received. Ignoring."); 724 } 725 726 // Then we create the new VM 727 let mut vm = Vm::new( 728 config, 729 exit_evt, 730 reset_evt, 731 #[cfg(feature = "guest_debug")] 732 debug_evt, 733 &self.seccomp_action, 734 self.hypervisor.clone(), 735 activate_evt, 736 serial_pty, 737 console_pty, 738 console_resize_pipe, 739 )?; 740 741 // And we boot it 742 vm.boot()?; 743 744 self.vm = Some(vm); 745 746 Ok(()) 747 } 748 749 fn vm_info(&self) -> result::Result<VmInfo, VmError> { 750 match &self.vm_config { 751 Some(config) => { 752 let state = match &self.vm { 753 Some(vm) => vm.get_state()?, 754 None => VmState::Created, 755 }; 756 757 let config = Arc::clone(config); 758 759 let mut memory_actual_size = config.lock().unwrap().memory.total_size(); 760 if let Some(vm) = &self.vm { 761 memory_actual_size -= vm.balloon_size(); 762 } 763 764 let device_tree = self.vm.as_ref().map(|vm| vm.device_tree()); 765 766 Ok(VmInfo { 767 config, 768 state, 769 memory_actual_size, 770 device_tree, 771 }) 772 } 773 None => Err(VmError::VmNotCreated), 774 } 775 } 776 777 fn vmm_ping(&self) -> VmmPingResponse { 778 VmmPingResponse { 779 version: self.version.clone(), 780 } 781 } 782 783 fn vm_delete(&mut self) -> result::Result<(), VmError> { 784 if self.vm_config.is_none() { 785 return Ok(()); 786 } 787 788 // If a VM is booted, we first try to shut it down. 789 if self.vm.is_some() { 790 self.vm_shutdown()?; 791 } 792 793 self.vm_config = None; 794 795 event!("vm", "deleted"); 796 797 Ok(()) 798 } 799 800 fn vmm_shutdown(&mut self) -> result::Result<(), VmError> { 801 self.vm_delete()?; 802 event!("vmm", "shutdown"); 803 Ok(()) 804 } 805 806 fn vm_resize( 807 &mut self, 808 desired_vcpus: Option<u8>, 809 desired_ram: Option<u64>, 810 desired_balloon: Option<u64>, 811 ) -> result::Result<(), VmError> { 812 self.vm_config.as_ref().ok_or(VmError::VmNotCreated)?; 813 814 if let Some(ref mut vm) = self.vm { 815 if let Err(e) = vm.resize(desired_vcpus, desired_ram, desired_balloon) { 816 error!("Error when resizing VM: {:?}", e); 817 Err(e) 818 } else { 819 Ok(()) 820 } 821 } else { 822 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap(); 823 if let Some(desired_vcpus) = desired_vcpus { 824 config.cpus.boot_vcpus = desired_vcpus; 825 } 826 if let Some(desired_ram) = desired_ram { 827 config.memory.size = desired_ram; 828 } 829 if let Some(desired_balloon) = desired_balloon { 830 if let Some(balloon_config) = &mut config.balloon { 831 balloon_config.size = desired_balloon; 832 } 833 } 834 Ok(()) 835 } 836 } 837 838 fn vm_resize_zone(&mut self, id: String, desired_ram: u64) -> result::Result<(), VmError> { 839 self.vm_config.as_ref().ok_or(VmError::VmNotCreated)?; 840 841 if let Some(ref mut vm) = self.vm { 842 if let Err(e) = vm.resize_zone(id, desired_ram) { 843 error!("Error when resizing VM: {:?}", e); 844 Err(e) 845 } else { 846 Ok(()) 847 } 848 } else { 849 // Update VmConfig by setting the new desired ram. 850 let memory_config = &mut self.vm_config.as_ref().unwrap().lock().unwrap().memory; 851 852 if let Some(zones) = &mut memory_config.zones { 853 for zone in zones.iter_mut() { 854 if zone.id == id { 855 zone.size = desired_ram; 856 return Ok(()); 857 } 858 } 859 } 860 861 error!("Could not find the memory zone {} for the resize", id); 862 Err(VmError::ResizeZone) 863 } 864 } 865 866 fn vm_add_device( 867 &mut self, 868 device_cfg: DeviceConfig, 869 ) -> result::Result<Option<Vec<u8>>, VmError> { 870 self.vm_config.as_ref().ok_or(VmError::VmNotCreated)?; 871 872 { 873 // Validate the configuration change in a cloned configuration 874 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap().clone(); 875 add_to_config(&mut config.devices, device_cfg.clone()); 876 config.validate().map_err(VmError::ConfigValidation)?; 877 } 878 879 if let Some(ref mut vm) = self.vm { 880 let info = vm.add_device(device_cfg).map_err(|e| { 881 error!("Error when adding new device to the VM: {:?}", e); 882 e 883 })?; 884 serde_json::to_vec(&info) 885 .map(Some) 886 .map_err(VmError::SerializeJson) 887 } else { 888 // Update VmConfig by adding the new device. 889 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap(); 890 add_to_config(&mut config.devices, device_cfg); 891 Ok(None) 892 } 893 } 894 895 fn vm_add_user_device( 896 &mut self, 897 device_cfg: UserDeviceConfig, 898 ) -> result::Result<Option<Vec<u8>>, VmError> { 899 self.vm_config.as_ref().ok_or(VmError::VmNotCreated)?; 900 901 { 902 // Validate the configuration change in a cloned configuration 903 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap().clone(); 904 add_to_config(&mut config.user_devices, device_cfg.clone()); 905 config.validate().map_err(VmError::ConfigValidation)?; 906 } 907 908 if let Some(ref mut vm) = self.vm { 909 let info = vm.add_user_device(device_cfg).map_err(|e| { 910 error!("Error when adding new user device to the VM: {:?}", e); 911 e 912 })?; 913 serde_json::to_vec(&info) 914 .map(Some) 915 .map_err(VmError::SerializeJson) 916 } else { 917 // Update VmConfig by adding the new device. 918 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap(); 919 add_to_config(&mut config.user_devices, device_cfg); 920 Ok(None) 921 } 922 } 923 924 fn vm_remove_device(&mut self, id: String) -> result::Result<(), VmError> { 925 if let Some(ref mut vm) = self.vm { 926 if let Err(e) = vm.remove_device(id) { 927 error!("Error when removing new device to the VM: {:?}", e); 928 Err(e) 929 } else { 930 Ok(()) 931 } 932 } else { 933 Err(VmError::VmNotRunning) 934 } 935 } 936 937 fn vm_add_disk(&mut self, disk_cfg: DiskConfig) -> result::Result<Option<Vec<u8>>, VmError> { 938 self.vm_config.as_ref().ok_or(VmError::VmNotCreated)?; 939 940 { 941 // Validate the configuration change in a cloned configuration 942 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap().clone(); 943 add_to_config(&mut config.disks, disk_cfg.clone()); 944 config.validate().map_err(VmError::ConfigValidation)?; 945 } 946 947 if let Some(ref mut vm) = self.vm { 948 let info = vm.add_disk(disk_cfg).map_err(|e| { 949 error!("Error when adding new disk to the VM: {:?}", e); 950 e 951 })?; 952 serde_json::to_vec(&info) 953 .map(Some) 954 .map_err(VmError::SerializeJson) 955 } else { 956 // Update VmConfig by adding the new device. 957 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap(); 958 add_to_config(&mut config.disks, disk_cfg); 959 Ok(None) 960 } 961 } 962 963 fn vm_add_fs(&mut self, fs_cfg: FsConfig) -> result::Result<Option<Vec<u8>>, VmError> { 964 self.vm_config.as_ref().ok_or(VmError::VmNotCreated)?; 965 966 { 967 // Validate the configuration change in a cloned configuration 968 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap().clone(); 969 add_to_config(&mut config.fs, fs_cfg.clone()); 970 config.validate().map_err(VmError::ConfigValidation)?; 971 } 972 973 if let Some(ref mut vm) = self.vm { 974 let info = vm.add_fs(fs_cfg).map_err(|e| { 975 error!("Error when adding new fs to the VM: {:?}", e); 976 e 977 })?; 978 serde_json::to_vec(&info) 979 .map(Some) 980 .map_err(VmError::SerializeJson) 981 } else { 982 // Update VmConfig by adding the new device. 983 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap(); 984 add_to_config(&mut config.fs, fs_cfg); 985 Ok(None) 986 } 987 } 988 989 fn vm_add_pmem(&mut self, pmem_cfg: PmemConfig) -> result::Result<Option<Vec<u8>>, VmError> { 990 self.vm_config.as_ref().ok_or(VmError::VmNotCreated)?; 991 992 { 993 // Validate the configuration change in a cloned configuration 994 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap().clone(); 995 add_to_config(&mut config.pmem, pmem_cfg.clone()); 996 config.validate().map_err(VmError::ConfigValidation)?; 997 } 998 999 if let Some(ref mut vm) = self.vm { 1000 let info = vm.add_pmem(pmem_cfg).map_err(|e| { 1001 error!("Error when adding new pmem device to the VM: {:?}", e); 1002 e 1003 })?; 1004 serde_json::to_vec(&info) 1005 .map(Some) 1006 .map_err(VmError::SerializeJson) 1007 } else { 1008 // Update VmConfig by adding the new device. 1009 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap(); 1010 add_to_config(&mut config.pmem, pmem_cfg); 1011 Ok(None) 1012 } 1013 } 1014 1015 fn vm_add_net(&mut self, net_cfg: NetConfig) -> result::Result<Option<Vec<u8>>, VmError> { 1016 self.vm_config.as_ref().ok_or(VmError::VmNotCreated)?; 1017 1018 { 1019 // Validate the configuration change in a cloned configuration 1020 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap().clone(); 1021 add_to_config(&mut config.net, net_cfg.clone()); 1022 config.validate().map_err(VmError::ConfigValidation)?; 1023 } 1024 1025 if let Some(ref mut vm) = self.vm { 1026 let info = vm.add_net(net_cfg).map_err(|e| { 1027 error!("Error when adding new network device to the VM: {:?}", e); 1028 e 1029 })?; 1030 serde_json::to_vec(&info) 1031 .map(Some) 1032 .map_err(VmError::SerializeJson) 1033 } else { 1034 // Update VmConfig by adding the new device. 1035 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap(); 1036 add_to_config(&mut config.net, net_cfg); 1037 Ok(None) 1038 } 1039 } 1040 1041 fn vm_add_vdpa(&mut self, vdpa_cfg: VdpaConfig) -> result::Result<Option<Vec<u8>>, VmError> { 1042 self.vm_config.as_ref().ok_or(VmError::VmNotCreated)?; 1043 1044 { 1045 // Validate the configuration change in a cloned configuration 1046 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap().clone(); 1047 add_to_config(&mut config.vdpa, vdpa_cfg.clone()); 1048 config.validate().map_err(VmError::ConfigValidation)?; 1049 } 1050 1051 if let Some(ref mut vm) = self.vm { 1052 let info = vm.add_vdpa(vdpa_cfg).map_err(|e| { 1053 error!("Error when adding new vDPA device to the VM: {:?}", e); 1054 e 1055 })?; 1056 serde_json::to_vec(&info) 1057 .map(Some) 1058 .map_err(VmError::SerializeJson) 1059 } else { 1060 // Update VmConfig by adding the new device. 1061 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap(); 1062 add_to_config(&mut config.vdpa, vdpa_cfg); 1063 Ok(None) 1064 } 1065 } 1066 1067 fn vm_add_vsock(&mut self, vsock_cfg: VsockConfig) -> result::Result<Option<Vec<u8>>, VmError> { 1068 self.vm_config.as_ref().ok_or(VmError::VmNotCreated)?; 1069 1070 { 1071 // Validate the configuration change in a cloned configuration 1072 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap().clone(); 1073 1074 if config.vsock.is_some() { 1075 return Err(VmError::TooManyVsockDevices); 1076 } 1077 1078 config.vsock = Some(vsock_cfg.clone()); 1079 config.validate().map_err(VmError::ConfigValidation)?; 1080 } 1081 1082 if let Some(ref mut vm) = self.vm { 1083 let info = vm.add_vsock(vsock_cfg).map_err(|e| { 1084 error!("Error when adding new vsock device to the VM: {:?}", e); 1085 e 1086 })?; 1087 serde_json::to_vec(&info) 1088 .map(Some) 1089 .map_err(VmError::SerializeJson) 1090 } else { 1091 // Update VmConfig by adding the new device. 1092 let mut config = self.vm_config.as_ref().unwrap().lock().unwrap(); 1093 config.vsock = Some(vsock_cfg); 1094 Ok(None) 1095 } 1096 } 1097 1098 fn vm_counters(&mut self) -> result::Result<Option<Vec<u8>>, VmError> { 1099 if let Some(ref mut vm) = self.vm { 1100 let info = vm.counters().map_err(|e| { 1101 error!("Error when getting counters from the VM: {:?}", e); 1102 e 1103 })?; 1104 serde_json::to_vec(&info) 1105 .map(Some) 1106 .map_err(VmError::SerializeJson) 1107 } else { 1108 Err(VmError::VmNotRunning) 1109 } 1110 } 1111 1112 fn vm_power_button(&mut self) -> result::Result<(), VmError> { 1113 if let Some(ref mut vm) = self.vm { 1114 vm.power_button() 1115 } else { 1116 Err(VmError::VmNotRunning) 1117 } 1118 } 1119 1120 fn vm_receive_config<T>( 1121 &mut self, 1122 req: &Request, 1123 socket: &mut T, 1124 existing_memory_files: Option<HashMap<u32, File>>, 1125 ) -> std::result::Result<Arc<Mutex<MemoryManager>>, MigratableError> 1126 where 1127 T: Read + Write, 1128 { 1129 // Read in config data along with memory manager data 1130 let mut data: Vec<u8> = Vec::new(); 1131 data.resize_with(req.length() as usize, Default::default); 1132 socket 1133 .read_exact(&mut data) 1134 .map_err(MigratableError::MigrateSocket)?; 1135 1136 let vm_migration_config: VmMigrationConfig = 1137 serde_json::from_slice(&data).map_err(|e| { 1138 MigratableError::MigrateReceive(anyhow!("Error deserialising config: {}", e)) 1139 })?; 1140 1141 #[cfg(all(feature = "kvm", target_arch = "x86_64"))] 1142 self.vm_check_cpuid_compatibility( 1143 &vm_migration_config.vm_config, 1144 &vm_migration_config.common_cpuid, 1145 )?; 1146 1147 let config = vm_migration_config.vm_config.clone(); 1148 self.vm_config = Some(vm_migration_config.vm_config); 1149 1150 let vm = Vm::create_hypervisor_vm( 1151 &self.hypervisor, 1152 #[cfg(feature = "tdx")] 1153 false, 1154 ) 1155 .map_err(|e| { 1156 MigratableError::MigrateReceive(anyhow!( 1157 "Error creating hypervisor VM from snapshot: {:?}", 1158 e 1159 )) 1160 })?; 1161 1162 let phys_bits = vm::physical_bits(config.lock().unwrap().cpus.max_phys_bits); 1163 1164 let memory_manager = MemoryManager::new( 1165 vm, 1166 &config.lock().unwrap().memory.clone(), 1167 None, 1168 phys_bits, 1169 #[cfg(feature = "tdx")] 1170 false, 1171 Some(&vm_migration_config.memory_manager_data), 1172 existing_memory_files, 1173 #[cfg(target_arch = "x86_64")] 1174 None, 1175 ) 1176 .map_err(|e| { 1177 MigratableError::MigrateReceive(anyhow!( 1178 "Error creating MemoryManager from snapshot: {:?}", 1179 e 1180 )) 1181 })?; 1182 1183 Response::ok().write_to(socket)?; 1184 1185 Ok(memory_manager) 1186 } 1187 1188 fn vm_receive_state<T>( 1189 &mut self, 1190 req: &Request, 1191 socket: &mut T, 1192 mm: Arc<Mutex<MemoryManager>>, 1193 ) -> std::result::Result<(), MigratableError> 1194 where 1195 T: Read + Write, 1196 { 1197 // Read in state data 1198 let mut data: Vec<u8> = Vec::new(); 1199 data.resize_with(req.length() as usize, Default::default); 1200 socket 1201 .read_exact(&mut data) 1202 .map_err(MigratableError::MigrateSocket)?; 1203 let snapshot: Snapshot = serde_json::from_slice(&data).map_err(|e| { 1204 MigratableError::MigrateReceive(anyhow!("Error deserialising snapshot: {}", e)) 1205 })?; 1206 1207 let exit_evt = self.exit_evt.try_clone().map_err(|e| { 1208 MigratableError::MigrateReceive(anyhow!("Error cloning exit EventFd: {}", e)) 1209 })?; 1210 let reset_evt = self.reset_evt.try_clone().map_err(|e| { 1211 MigratableError::MigrateReceive(anyhow!("Error cloning reset EventFd: {}", e)) 1212 })?; 1213 #[cfg(feature = "guest_debug")] 1214 let debug_evt = self.vm_debug_evt.try_clone().map_err(|e| { 1215 MigratableError::MigrateReceive(anyhow!("Error cloning debug EventFd: {}", e)) 1216 })?; 1217 let activate_evt = self.activate_evt.try_clone().map_err(|e| { 1218 MigratableError::MigrateReceive(anyhow!("Error cloning activate EventFd: {}", e)) 1219 })?; 1220 1221 let timestamp = Instant::now(); 1222 let hypervisor_vm = mm.lock().unwrap().vm.clone(); 1223 let mut vm = Vm::new_from_memory_manager( 1224 self.vm_config.clone().unwrap(), 1225 mm, 1226 hypervisor_vm, 1227 exit_evt, 1228 reset_evt, 1229 #[cfg(feature = "guest_debug")] 1230 debug_evt, 1231 &self.seccomp_action, 1232 self.hypervisor.clone(), 1233 activate_evt, 1234 true, 1235 timestamp, 1236 Some(&snapshot), 1237 ) 1238 .map_err(|e| { 1239 MigratableError::MigrateReceive(anyhow!("Error creating VM from snapshot: {:?}", e)) 1240 })?; 1241 1242 // Create VM 1243 vm.restore(snapshot).map_err(|e| { 1244 Response::error().write_to(socket).ok(); 1245 e 1246 })?; 1247 self.vm = Some(vm); 1248 1249 Response::ok().write_to(socket)?; 1250 1251 Ok(()) 1252 } 1253 1254 fn vm_receive_memory<T>( 1255 &mut self, 1256 req: &Request, 1257 socket: &mut T, 1258 memory_manager: &mut MemoryManager, 1259 ) -> std::result::Result<(), MigratableError> 1260 where 1261 T: Read + Write, 1262 { 1263 // Read table 1264 let table = MemoryRangeTable::read_from(socket, req.length())?; 1265 1266 // And then read the memory itself 1267 memory_manager 1268 .receive_memory_regions(&table, socket) 1269 .map_err(|e| { 1270 Response::error().write_to(socket).ok(); 1271 e 1272 })?; 1273 Response::ok().write_to(socket)?; 1274 Ok(()) 1275 } 1276 1277 fn socket_url_to_path(url: &str) -> result::Result<PathBuf, MigratableError> { 1278 url.strip_prefix("unix:") 1279 .ok_or_else(|| { 1280 MigratableError::MigrateSend(anyhow!("Could not extract path from URL: {}", url)) 1281 }) 1282 .map(|s| s.into()) 1283 } 1284 1285 fn vm_receive_migration( 1286 &mut self, 1287 receive_data_migration: VmReceiveMigrationData, 1288 ) -> result::Result<(), MigratableError> { 1289 info!( 1290 "Receiving migration: receiver_url = {}", 1291 receive_data_migration.receiver_url 1292 ); 1293 1294 let path = Self::socket_url_to_path(&receive_data_migration.receiver_url)?; 1295 let listener = UnixListener::bind(&path).map_err(|e| { 1296 MigratableError::MigrateReceive(anyhow!("Error binding to UNIX socket: {}", e)) 1297 })?; 1298 let (mut socket, _addr) = listener.accept().map_err(|e| { 1299 MigratableError::MigrateReceive(anyhow!("Error accepting on UNIX socket: {}", e)) 1300 })?; 1301 std::fs::remove_file(&path).map_err(|e| { 1302 MigratableError::MigrateReceive(anyhow!("Error unlinking UNIX socket: {}", e)) 1303 })?; 1304 1305 let mut started = false; 1306 let mut memory_manager: Option<Arc<Mutex<MemoryManager>>> = None; 1307 let mut existing_memory_files = None; 1308 loop { 1309 let req = Request::read_from(&mut socket)?; 1310 match req.command() { 1311 Command::Invalid => info!("Invalid Command Received"), 1312 Command::Start => { 1313 info!("Start Command Received"); 1314 started = true; 1315 1316 Response::ok().write_to(&mut socket)?; 1317 } 1318 Command::Config => { 1319 info!("Config Command Received"); 1320 1321 if !started { 1322 warn!("Migration not started yet"); 1323 Response::error().write_to(&mut socket)?; 1324 continue; 1325 } 1326 memory_manager = Some(self.vm_receive_config( 1327 &req, 1328 &mut socket, 1329 existing_memory_files.take(), 1330 )?); 1331 } 1332 Command::State => { 1333 info!("State Command Received"); 1334 1335 if !started { 1336 warn!("Migration not started yet"); 1337 Response::error().write_to(&mut socket)?; 1338 continue; 1339 } 1340 if let Some(mm) = memory_manager.take() { 1341 self.vm_receive_state(&req, &mut socket, mm)?; 1342 } else { 1343 warn!("Configuration not sent yet"); 1344 Response::error().write_to(&mut socket)?; 1345 } 1346 } 1347 Command::Memory => { 1348 info!("Memory Command Received"); 1349 1350 if !started { 1351 warn!("Migration not started yet"); 1352 Response::error().write_to(&mut socket)?; 1353 continue; 1354 } 1355 if let Some(mm) = memory_manager.as_ref() { 1356 self.vm_receive_memory(&req, &mut socket, &mut mm.lock().unwrap())?; 1357 } else { 1358 warn!("Configuration not sent yet"); 1359 Response::error().write_to(&mut socket)?; 1360 } 1361 } 1362 Command::MemoryFd => { 1363 info!("MemoryFd Command Received"); 1364 1365 if !started { 1366 warn!("Migration not started yet"); 1367 Response::error().write_to(&mut socket)?; 1368 continue; 1369 } 1370 1371 let mut buf = [0u8; 4]; 1372 let (_, file) = socket.recv_with_fd(&mut buf).map_err(|e| { 1373 MigratableError::MigrateReceive(anyhow!( 1374 "Error receiving slot from socket: {}", 1375 e 1376 )) 1377 })?; 1378 1379 if existing_memory_files.is_none() { 1380 existing_memory_files = Some(HashMap::default()) 1381 } 1382 1383 if let Some(ref mut existing_memory_files) = existing_memory_files { 1384 let slot = u32::from_le_bytes(buf); 1385 existing_memory_files.insert(slot, file.unwrap()); 1386 } 1387 1388 Response::ok().write_to(&mut socket)?; 1389 } 1390 Command::Complete => { 1391 info!("Complete Command Received"); 1392 if let Some(ref mut vm) = self.vm.as_mut() { 1393 vm.resume()?; 1394 Response::ok().write_to(&mut socket)?; 1395 } else { 1396 warn!("VM not created yet"); 1397 Response::error().write_to(&mut socket)?; 1398 } 1399 break; 1400 } 1401 Command::Abandon => { 1402 info!("Abandon Command Received"); 1403 self.vm = None; 1404 self.vm_config = None; 1405 Response::ok().write_to(&mut socket).ok(); 1406 break; 1407 } 1408 } 1409 } 1410 1411 Ok(()) 1412 } 1413 1414 // Returns true if there were dirty pages to send 1415 fn vm_maybe_send_dirty_pages<T>( 1416 vm: &mut Vm, 1417 socket: &mut T, 1418 ) -> result::Result<bool, MigratableError> 1419 where 1420 T: Read + Write, 1421 { 1422 // Send (dirty) memory table 1423 let table = vm.dirty_log()?; 1424 1425 // But if there are no regions go straight to pause 1426 if table.regions().is_empty() { 1427 return Ok(false); 1428 } 1429 1430 Request::memory(table.length()).write_to(socket).unwrap(); 1431 table.write_to(socket)?; 1432 // And then the memory itself 1433 vm.send_memory_regions(&table, socket)?; 1434 let res = Response::read_from(socket)?; 1435 if res.status() != Status::Ok { 1436 warn!("Error during dirty memory migration"); 1437 Request::abandon().write_to(socket)?; 1438 Response::read_from(socket).ok(); 1439 return Err(MigratableError::MigrateSend(anyhow!( 1440 "Error during dirty memory migration" 1441 ))); 1442 } 1443 1444 Ok(true) 1445 } 1446 1447 fn send_migration( 1448 vm: &mut Vm, 1449 #[cfg(all(feature = "kvm", target_arch = "x86_64"))] hypervisor: Arc< 1450 dyn hypervisor::Hypervisor, 1451 >, 1452 send_data_migration: VmSendMigrationData, 1453 ) -> result::Result<(), MigratableError> { 1454 let path = Self::socket_url_to_path(&send_data_migration.destination_url)?; 1455 let mut socket = UnixStream::connect(path).map_err(|e| { 1456 MigratableError::MigrateSend(anyhow!("Error connecting to UNIX socket: {}", e)) 1457 })?; 1458 1459 // Start the migration 1460 Request::start().write_to(&mut socket)?; 1461 let res = Response::read_from(&mut socket)?; 1462 if res.status() != Status::Ok { 1463 warn!("Error starting migration"); 1464 Request::abandon().write_to(&mut socket)?; 1465 Response::read_from(&mut socket).ok(); 1466 return Err(MigratableError::MigrateSend(anyhow!( 1467 "Error starting migration" 1468 ))); 1469 } 1470 1471 // Send config 1472 let vm_config = vm.get_config(); 1473 #[cfg(all(feature = "kvm", target_arch = "x86_64"))] 1474 let common_cpuid = { 1475 let phys_bits = vm::physical_bits(vm_config.lock().unwrap().cpus.max_phys_bits); 1476 arch::generate_common_cpuid( 1477 hypervisor, 1478 None, 1479 None, 1480 phys_bits, 1481 vm_config.lock().unwrap().cpus.kvm_hyperv, 1482 #[cfg(feature = "tdx")] 1483 vm_config.lock().unwrap().is_tdx_enabled(), 1484 ) 1485 .map_err(|e| { 1486 MigratableError::MigrateReceive(anyhow!("Error generating common cpuid': {:?}", e)) 1487 })? 1488 }; 1489 1490 if send_data_migration.local { 1491 vm.send_memory_fds(&mut socket)?; 1492 } 1493 1494 let vm_migration_config = VmMigrationConfig { 1495 vm_config, 1496 #[cfg(all(feature = "kvm", target_arch = "x86_64"))] 1497 common_cpuid, 1498 memory_manager_data: vm.memory_manager_data(), 1499 }; 1500 let config_data = serde_json::to_vec(&vm_migration_config).unwrap(); 1501 Request::config(config_data.len() as u64).write_to(&mut socket)?; 1502 socket 1503 .write_all(&config_data) 1504 .map_err(MigratableError::MigrateSocket)?; 1505 let res = Response::read_from(&mut socket)?; 1506 if res.status() != Status::Ok { 1507 warn!("Error during config migration"); 1508 Request::abandon().write_to(&mut socket)?; 1509 Response::read_from(&mut socket).ok(); 1510 return Err(MigratableError::MigrateSend(anyhow!( 1511 "Error during config migration" 1512 ))); 1513 } 1514 1515 // Let every Migratable object know about the migration being started. 1516 vm.start_migration()?; 1517 1518 if send_data_migration.local { 1519 // Now pause VM 1520 vm.pause()?; 1521 } else { 1522 // Start logging dirty pages 1523 vm.start_dirty_log()?; 1524 1525 // Send memory table 1526 let table = vm.memory_range_table()?; 1527 Request::memory(table.length()) 1528 .write_to(&mut socket) 1529 .unwrap(); 1530 table.write_to(&mut socket)?; 1531 // And then the memory itself 1532 vm.send_memory_regions(&table, &mut socket)?; 1533 let res = Response::read_from(&mut socket)?; 1534 if res.status() != Status::Ok { 1535 warn!("Error during memory migration"); 1536 Request::abandon().write_to(&mut socket)?; 1537 Response::read_from(&mut socket).ok(); 1538 return Err(MigratableError::MigrateSend(anyhow!( 1539 "Error during memory migration" 1540 ))); 1541 } 1542 1543 // Try at most 5 passes of dirty memory sending 1544 const MAX_DIRTY_MIGRATIONS: usize = 5; 1545 for i in 0..MAX_DIRTY_MIGRATIONS { 1546 info!("Dirty memory migration {} of {}", i, MAX_DIRTY_MIGRATIONS); 1547 if !Self::vm_maybe_send_dirty_pages(vm, &mut socket)? { 1548 break; 1549 } 1550 } 1551 1552 // Now pause VM 1553 vm.pause()?; 1554 1555 // Send last batch of dirty pages 1556 Self::vm_maybe_send_dirty_pages(vm, &mut socket)?; 1557 1558 // Stop logging dirty pages 1559 vm.stop_dirty_log()?; 1560 } 1561 // Capture snapshot and send it 1562 let vm_snapshot = vm.snapshot()?; 1563 let snapshot_data = serde_json::to_vec(&vm_snapshot).unwrap(); 1564 Request::state(snapshot_data.len() as u64).write_to(&mut socket)?; 1565 socket 1566 .write_all(&snapshot_data) 1567 .map_err(MigratableError::MigrateSocket)?; 1568 let res = Response::read_from(&mut socket)?; 1569 if res.status() != Status::Ok { 1570 warn!("Error during state migration"); 1571 Request::abandon().write_to(&mut socket)?; 1572 Response::read_from(&mut socket).ok(); 1573 return Err(MigratableError::MigrateSend(anyhow!( 1574 "Error during state migration" 1575 ))); 1576 } 1577 1578 // Complete the migration 1579 Request::complete().write_to(&mut socket)?; 1580 let res = Response::read_from(&mut socket)?; 1581 if res.status() != Status::Ok { 1582 warn!("Error completing migration"); 1583 Request::abandon().write_to(&mut socket)?; 1584 Response::read_from(&mut socket).ok(); 1585 return Err(MigratableError::MigrateSend(anyhow!( 1586 "Error completing migration" 1587 ))); 1588 } 1589 info!("Migration complete"); 1590 1591 // Let every Migratable object know about the migration being complete 1592 vm.complete_migration() 1593 } 1594 1595 fn vm_send_migration( 1596 &mut self, 1597 send_data_migration: VmSendMigrationData, 1598 ) -> result::Result<(), MigratableError> { 1599 info!( 1600 "Sending migration: destination_url = {}, local = {}", 1601 send_data_migration.destination_url, send_data_migration.local 1602 ); 1603 1604 if !self 1605 .vm_config 1606 .as_ref() 1607 .unwrap() 1608 .lock() 1609 .unwrap() 1610 .backed_by_shared_memory() 1611 && send_data_migration.local 1612 { 1613 return Err(MigratableError::MigrateSend(anyhow!( 1614 "Local migration requires shared memory or hugepages enabled" 1615 ))); 1616 } 1617 1618 if let Some(vm) = self.vm.as_mut() { 1619 Self::send_migration( 1620 vm, 1621 #[cfg(all(feature = "kvm", target_arch = "x86_64"))] 1622 self.hypervisor.clone(), 1623 send_data_migration, 1624 ) 1625 .map_err(|migration_err| { 1626 error!("Migration failed: {:?}", migration_err); 1627 1628 // Stop logging dirty pages 1629 if let Err(e) = vm.stop_dirty_log() { 1630 return e; 1631 } 1632 1633 if vm.get_state().unwrap() == VmState::Paused { 1634 if let Err(e) = vm.resume() { 1635 return e; 1636 } 1637 } 1638 1639 migration_err 1640 })?; 1641 1642 // Shutdown the VM after the migration succeeded 1643 self.exit_evt.write(1).map_err(|e| { 1644 MigratableError::MigrateSend(anyhow!( 1645 "Failed shutting down the VM after migration: {:?}", 1646 e 1647 )) 1648 }) 1649 } else { 1650 Err(MigratableError::MigrateSend(anyhow!("VM is not running"))) 1651 } 1652 } 1653 1654 #[cfg(all(feature = "kvm", target_arch = "x86_64"))] 1655 fn vm_check_cpuid_compatibility( 1656 &self, 1657 src_vm_config: &Arc<Mutex<VmConfig>>, 1658 src_vm_cpuid: &[hypervisor::arch::x86::CpuIdEntry], 1659 ) -> result::Result<(), MigratableError> { 1660 // We check the `CPUID` compatibility of between the source vm and destination, which is 1661 // mostly about feature compatibility and "topology/sgx" leaves are not relevant. 1662 let dest_cpuid = &{ 1663 let vm_config = &src_vm_config.lock().unwrap(); 1664 1665 let phys_bits = vm::physical_bits(vm_config.cpus.max_phys_bits); 1666 arch::generate_common_cpuid( 1667 self.hypervisor.clone(), 1668 None, 1669 None, 1670 phys_bits, 1671 vm_config.cpus.kvm_hyperv, 1672 #[cfg(feature = "tdx")] 1673 vm_config.is_tdx_enabled(), 1674 ) 1675 .map_err(|e| { 1676 MigratableError::MigrateReceive(anyhow!("Error generating common cpuid: {:?}", e)) 1677 })? 1678 }; 1679 arch::CpuidFeatureEntry::check_cpuid_compatibility(src_vm_cpuid, dest_cpuid).map_err(|e| { 1680 MigratableError::MigrateReceive(anyhow!( 1681 "Error checking cpu feature compatibility': {:?}", 1682 e 1683 )) 1684 }) 1685 } 1686 1687 fn control_loop( 1688 &mut self, 1689 api_receiver: Arc<Receiver<ApiRequest>>, 1690 #[cfg(feature = "guest_debug")] gdb_receiver: Arc<Receiver<gdb::GdbRequest>>, 1691 ) -> Result<()> { 1692 const EPOLL_EVENTS_LEN: usize = 100; 1693 1694 let mut events = vec![epoll::Event::new(epoll::Events::empty(), 0); EPOLL_EVENTS_LEN]; 1695 let epoll_fd = self.epoll.as_raw_fd(); 1696 1697 'outer: loop { 1698 let num_events = match epoll::wait(epoll_fd, -1, &mut events[..]) { 1699 Ok(res) => res, 1700 Err(e) => { 1701 if e.kind() == io::ErrorKind::Interrupted { 1702 // It's well defined from the epoll_wait() syscall 1703 // documentation that the epoll loop can be interrupted 1704 // before any of the requested events occurred or the 1705 // timeout expired. In both those cases, epoll_wait() 1706 // returns an error of type EINTR, but this should not 1707 // be considered as a regular error. Instead it is more 1708 // appropriate to retry, by calling into epoll_wait(). 1709 continue; 1710 } 1711 return Err(Error::Epoll(e)); 1712 } 1713 }; 1714 1715 for event in events.iter().take(num_events) { 1716 let dispatch_event: EpollDispatch = event.data.into(); 1717 match dispatch_event { 1718 EpollDispatch::Unknown => { 1719 let event = event.data; 1720 warn!("Unknown VMM loop event: {}", event); 1721 } 1722 EpollDispatch::Exit => { 1723 info!("VM exit event"); 1724 // Consume the event. 1725 self.exit_evt.read().map_err(Error::EventFdRead)?; 1726 self.vmm_shutdown().map_err(Error::VmmShutdown)?; 1727 1728 break 'outer; 1729 } 1730 EpollDispatch::Reset => { 1731 info!("VM reset event"); 1732 // Consume the event. 1733 self.reset_evt.read().map_err(Error::EventFdRead)?; 1734 self.vm_reboot().map_err(Error::VmReboot)?; 1735 } 1736 EpollDispatch::ActivateVirtioDevices => { 1737 if let Some(ref vm) = self.vm { 1738 let count = self.activate_evt.read().map_err(Error::EventFdRead)?; 1739 info!( 1740 "Trying to activate pending virtio devices: count = {}", 1741 count 1742 ); 1743 vm.activate_virtio_devices() 1744 .map_err(Error::ActivateVirtioDevices)?; 1745 } 1746 } 1747 EpollDispatch::Api => { 1748 // Consume the events. 1749 for _ in 0..self.api_evt.read().map_err(Error::EventFdRead)? { 1750 // Read from the API receiver channel 1751 let api_request = api_receiver.recv().map_err(Error::ApiRequestRecv)?; 1752 1753 info!("API request event: {:?}", api_request); 1754 match api_request { 1755 ApiRequest::VmCreate(config, sender) => { 1756 let response = self 1757 .vm_create(config) 1758 .map_err(ApiError::VmCreate) 1759 .map(|_| ApiResponsePayload::Empty); 1760 1761 sender.send(response).map_err(Error::ApiResponseSend)?; 1762 } 1763 ApiRequest::VmDelete(sender) => { 1764 let response = self 1765 .vm_delete() 1766 .map_err(ApiError::VmDelete) 1767 .map(|_| ApiResponsePayload::Empty); 1768 1769 sender.send(response).map_err(Error::ApiResponseSend)?; 1770 } 1771 ApiRequest::VmBoot(sender) => { 1772 let response = self 1773 .vm_boot() 1774 .map_err(ApiError::VmBoot) 1775 .map(|_| ApiResponsePayload::Empty); 1776 1777 sender.send(response).map_err(Error::ApiResponseSend)?; 1778 } 1779 ApiRequest::VmShutdown(sender) => { 1780 let response = self 1781 .vm_shutdown() 1782 .map_err(ApiError::VmShutdown) 1783 .map(|_| ApiResponsePayload::Empty); 1784 1785 sender.send(response).map_err(Error::ApiResponseSend)?; 1786 } 1787 ApiRequest::VmReboot(sender) => { 1788 let response = self 1789 .vm_reboot() 1790 .map_err(ApiError::VmReboot) 1791 .map(|_| ApiResponsePayload::Empty); 1792 1793 sender.send(response).map_err(Error::ApiResponseSend)?; 1794 } 1795 ApiRequest::VmInfo(sender) => { 1796 let response = self 1797 .vm_info() 1798 .map_err(ApiError::VmInfo) 1799 .map(ApiResponsePayload::VmInfo); 1800 1801 sender.send(response).map_err(Error::ApiResponseSend)?; 1802 } 1803 ApiRequest::VmmPing(sender) => { 1804 let response = ApiResponsePayload::VmmPing(self.vmm_ping()); 1805 1806 sender.send(Ok(response)).map_err(Error::ApiResponseSend)?; 1807 } 1808 ApiRequest::VmPause(sender) => { 1809 let response = self 1810 .vm_pause() 1811 .map_err(ApiError::VmPause) 1812 .map(|_| ApiResponsePayload::Empty); 1813 1814 sender.send(response).map_err(Error::ApiResponseSend)?; 1815 } 1816 ApiRequest::VmResume(sender) => { 1817 let response = self 1818 .vm_resume() 1819 .map_err(ApiError::VmResume) 1820 .map(|_| ApiResponsePayload::Empty); 1821 1822 sender.send(response).map_err(Error::ApiResponseSend)?; 1823 } 1824 ApiRequest::VmSnapshot(snapshot_data, sender) => { 1825 let response = self 1826 .vm_snapshot(&snapshot_data.destination_url) 1827 .map_err(ApiError::VmSnapshot) 1828 .map(|_| ApiResponsePayload::Empty); 1829 1830 sender.send(response).map_err(Error::ApiResponseSend)?; 1831 } 1832 ApiRequest::VmRestore(restore_data, sender) => { 1833 let response = self 1834 .vm_restore(restore_data.as_ref().clone()) 1835 .map_err(ApiError::VmRestore) 1836 .map(|_| ApiResponsePayload::Empty); 1837 1838 sender.send(response).map_err(Error::ApiResponseSend)?; 1839 } 1840 #[cfg(feature = "guest_debug")] 1841 ApiRequest::VmCoredump(coredump_data, sender) => { 1842 let response = self 1843 .vm_coredump(&coredump_data.destination_url) 1844 .map_err(ApiError::VmCoredump) 1845 .map(|_| ApiResponsePayload::Empty); 1846 1847 sender.send(response).map_err(Error::ApiResponseSend)?; 1848 } 1849 ApiRequest::VmmShutdown(sender) => { 1850 let response = self 1851 .vmm_shutdown() 1852 .map_err(ApiError::VmmShutdown) 1853 .map(|_| ApiResponsePayload::Empty); 1854 1855 sender.send(response).map_err(Error::ApiResponseSend)?; 1856 1857 break 'outer; 1858 } 1859 ApiRequest::VmResize(resize_data, sender) => { 1860 let response = self 1861 .vm_resize( 1862 resize_data.desired_vcpus, 1863 resize_data.desired_ram, 1864 resize_data.desired_balloon, 1865 ) 1866 .map_err(ApiError::VmResize) 1867 .map(|_| ApiResponsePayload::Empty); 1868 sender.send(response).map_err(Error::ApiResponseSend)?; 1869 } 1870 ApiRequest::VmResizeZone(resize_zone_data, sender) => { 1871 let response = self 1872 .vm_resize_zone( 1873 resize_zone_data.id.clone(), 1874 resize_zone_data.desired_ram, 1875 ) 1876 .map_err(ApiError::VmResizeZone) 1877 .map(|_| ApiResponsePayload::Empty); 1878 sender.send(response).map_err(Error::ApiResponseSend)?; 1879 } 1880 ApiRequest::VmAddDevice(add_device_data, sender) => { 1881 let response = self 1882 .vm_add_device(add_device_data.as_ref().clone()) 1883 .map_err(ApiError::VmAddDevice) 1884 .map(ApiResponsePayload::VmAction); 1885 sender.send(response).map_err(Error::ApiResponseSend)?; 1886 } 1887 ApiRequest::VmAddUserDevice(add_device_data, sender) => { 1888 let response = self 1889 .vm_add_user_device(add_device_data.as_ref().clone()) 1890 .map_err(ApiError::VmAddUserDevice) 1891 .map(ApiResponsePayload::VmAction); 1892 sender.send(response).map_err(Error::ApiResponseSend)?; 1893 } 1894 ApiRequest::VmRemoveDevice(remove_device_data, sender) => { 1895 let response = self 1896 .vm_remove_device(remove_device_data.id.clone()) 1897 .map_err(ApiError::VmRemoveDevice) 1898 .map(|_| ApiResponsePayload::Empty); 1899 sender.send(response).map_err(Error::ApiResponseSend)?; 1900 } 1901 ApiRequest::VmAddDisk(add_disk_data, sender) => { 1902 let response = self 1903 .vm_add_disk(add_disk_data.as_ref().clone()) 1904 .map_err(ApiError::VmAddDisk) 1905 .map(ApiResponsePayload::VmAction); 1906 sender.send(response).map_err(Error::ApiResponseSend)?; 1907 } 1908 ApiRequest::VmAddFs(add_fs_data, sender) => { 1909 let response = self 1910 .vm_add_fs(add_fs_data.as_ref().clone()) 1911 .map_err(ApiError::VmAddFs) 1912 .map(ApiResponsePayload::VmAction); 1913 sender.send(response).map_err(Error::ApiResponseSend)?; 1914 } 1915 ApiRequest::VmAddPmem(add_pmem_data, sender) => { 1916 let response = self 1917 .vm_add_pmem(add_pmem_data.as_ref().clone()) 1918 .map_err(ApiError::VmAddPmem) 1919 .map(ApiResponsePayload::VmAction); 1920 sender.send(response).map_err(Error::ApiResponseSend)?; 1921 } 1922 ApiRequest::VmAddNet(add_net_data, sender) => { 1923 let response = self 1924 .vm_add_net(add_net_data.as_ref().clone()) 1925 .map_err(ApiError::VmAddNet) 1926 .map(ApiResponsePayload::VmAction); 1927 sender.send(response).map_err(Error::ApiResponseSend)?; 1928 } 1929 ApiRequest::VmAddVdpa(add_vdpa_data, sender) => { 1930 let response = self 1931 .vm_add_vdpa(add_vdpa_data.as_ref().clone()) 1932 .map_err(ApiError::VmAddVdpa) 1933 .map(ApiResponsePayload::VmAction); 1934 sender.send(response).map_err(Error::ApiResponseSend)?; 1935 } 1936 ApiRequest::VmAddVsock(add_vsock_data, sender) => { 1937 let response = self 1938 .vm_add_vsock(add_vsock_data.as_ref().clone()) 1939 .map_err(ApiError::VmAddVsock) 1940 .map(ApiResponsePayload::VmAction); 1941 sender.send(response).map_err(Error::ApiResponseSend)?; 1942 } 1943 ApiRequest::VmCounters(sender) => { 1944 let response = self 1945 .vm_counters() 1946 .map_err(ApiError::VmInfo) 1947 .map(ApiResponsePayload::VmAction); 1948 sender.send(response).map_err(Error::ApiResponseSend)?; 1949 } 1950 ApiRequest::VmReceiveMigration(receive_migration_data, sender) => { 1951 let response = self 1952 .vm_receive_migration( 1953 receive_migration_data.as_ref().clone(), 1954 ) 1955 .map_err(ApiError::VmReceiveMigration) 1956 .map(|_| ApiResponsePayload::Empty); 1957 sender.send(response).map_err(Error::ApiResponseSend)?; 1958 } 1959 ApiRequest::VmSendMigration(send_migration_data, sender) => { 1960 let response = self 1961 .vm_send_migration(send_migration_data.as_ref().clone()) 1962 .map_err(ApiError::VmSendMigration) 1963 .map(|_| ApiResponsePayload::Empty); 1964 sender.send(response).map_err(Error::ApiResponseSend)?; 1965 } 1966 ApiRequest::VmPowerButton(sender) => { 1967 let response = self 1968 .vm_power_button() 1969 .map_err(ApiError::VmPowerButton) 1970 .map(|_| ApiResponsePayload::Empty); 1971 1972 sender.send(response).map_err(Error::ApiResponseSend)?; 1973 } 1974 } 1975 } 1976 } 1977 #[cfg(feature = "guest_debug")] 1978 EpollDispatch::Debug => { 1979 // Consume the events. 1980 for _ in 0..self.debug_evt.read().map_err(Error::EventFdRead)? { 1981 // Read from the API receiver channel 1982 let gdb_request = gdb_receiver.recv().map_err(Error::GdbRequestRecv)?; 1983 1984 let response = if let Some(ref mut vm) = self.vm { 1985 vm.debug_request(&gdb_request.payload, gdb_request.cpu_id) 1986 } else { 1987 Err(VmError::VmNotRunning) 1988 } 1989 .map_err(gdb::Error::Vm); 1990 1991 gdb_request 1992 .sender 1993 .send(response) 1994 .map_err(Error::GdbResponseSend)?; 1995 } 1996 } 1997 #[cfg(not(feature = "guest_debug"))] 1998 EpollDispatch::Debug => {} 1999 } 2000 } 2001 } 2002 2003 // Trigger the termination of the signal_handler thread 2004 if let Some(signals) = self.signals.take() { 2005 signals.close(); 2006 } 2007 2008 // Wait for all the threads to finish 2009 for thread in self.threads.drain(..) { 2010 thread.join().map_err(Error::ThreadCleanup)? 2011 } 2012 2013 Ok(()) 2014 } 2015 } 2016 2017 const CPU_MANAGER_SNAPSHOT_ID: &str = "cpu-manager"; 2018 const MEMORY_MANAGER_SNAPSHOT_ID: &str = "memory-manager"; 2019 const DEVICE_MANAGER_SNAPSHOT_ID: &str = "device-manager"; 2020 2021 #[cfg(test)] 2022 mod unit_tests { 2023 use super::*; 2024 use config::{ 2025 ConsoleConfig, ConsoleOutputMode, CpusConfig, HotplugMethod, MemoryConfig, PayloadConfig, 2026 RngConfig, VmConfig, 2027 }; 2028 2029 fn create_dummy_vmm() -> Vmm { 2030 Vmm::new( 2031 "dummy".to_string(), 2032 EventFd::new(EFD_NONBLOCK).unwrap(), 2033 #[cfg(feature = "guest_debug")] 2034 EventFd::new(EFD_NONBLOCK).unwrap(), 2035 #[cfg(feature = "guest_debug")] 2036 EventFd::new(EFD_NONBLOCK).unwrap(), 2037 SeccompAction::Allow, 2038 hypervisor::new().unwrap(), 2039 EventFd::new(EFD_NONBLOCK).unwrap(), 2040 ) 2041 .unwrap() 2042 } 2043 2044 fn create_dummy_vm_config() -> Arc<Mutex<VmConfig>> { 2045 Arc::new(Mutex::new(VmConfig { 2046 cpus: CpusConfig { 2047 boot_vcpus: 1, 2048 max_vcpus: 1, 2049 topology: None, 2050 kvm_hyperv: false, 2051 max_phys_bits: 46, 2052 affinity: None, 2053 features: config::CpuFeatures::default(), 2054 }, 2055 memory: MemoryConfig { 2056 size: 536_870_912, 2057 mergeable: false, 2058 hotplug_method: HotplugMethod::Acpi, 2059 hotplug_size: None, 2060 hotplugged_size: None, 2061 shared: true, 2062 hugepages: false, 2063 hugepage_size: None, 2064 prefault: false, 2065 zones: None, 2066 thp: true, 2067 }, 2068 payload: Some(PayloadConfig { 2069 kernel: Some(PathBuf::from("/path/to/kernel")), 2070 ..Default::default() 2071 }), 2072 disks: None, 2073 net: None, 2074 rng: RngConfig { 2075 src: PathBuf::from("/dev/urandom"), 2076 iommu: false, 2077 }, 2078 balloon: None, 2079 fs: None, 2080 pmem: None, 2081 serial: ConsoleConfig { 2082 file: None, 2083 mode: ConsoleOutputMode::Null, 2084 iommu: false, 2085 }, 2086 console: ConsoleConfig { 2087 file: None, 2088 mode: ConsoleOutputMode::Tty, 2089 iommu: false, 2090 }, 2091 devices: None, 2092 user_devices: None, 2093 vdpa: None, 2094 vsock: None, 2095 iommu: false, 2096 #[cfg(target_arch = "x86_64")] 2097 sgx_epc: None, 2098 numa: None, 2099 watchdog: false, 2100 #[cfg(feature = "guest_debug")] 2101 gdb: false, 2102 platform: None, 2103 tpm: None, 2104 })) 2105 } 2106 2107 #[test] 2108 fn test_vmm_vm_create() { 2109 let mut vmm = create_dummy_vmm(); 2110 let config = create_dummy_vm_config(); 2111 2112 assert!(matches!(vmm.vm_create(config.clone()), Ok(()))); 2113 assert!(matches!( 2114 vmm.vm_create(config), 2115 Err(VmError::VmAlreadyCreated) 2116 )); 2117 } 2118 2119 #[test] 2120 fn test_vmm_vm_cold_add_device() { 2121 let mut vmm = create_dummy_vmm(); 2122 let device_config = DeviceConfig::parse("path=/path/to/device").unwrap(); 2123 2124 assert!(matches!( 2125 vmm.vm_add_device(device_config.clone()), 2126 Err(VmError::VmNotCreated) 2127 )); 2128 2129 let _ = vmm.vm_create(create_dummy_vm_config()); 2130 assert!(vmm 2131 .vm_config 2132 .as_ref() 2133 .unwrap() 2134 .lock() 2135 .unwrap() 2136 .devices 2137 .is_none()); 2138 2139 let result = vmm.vm_add_device(device_config.clone()); 2140 assert!(result.is_ok()); 2141 assert!(result.unwrap().is_none()); 2142 assert_eq!( 2143 vmm.vm_config 2144 .as_ref() 2145 .unwrap() 2146 .lock() 2147 .unwrap() 2148 .devices 2149 .clone() 2150 .unwrap() 2151 .len(), 2152 1 2153 ); 2154 assert_eq!( 2155 vmm.vm_config 2156 .as_ref() 2157 .unwrap() 2158 .lock() 2159 .unwrap() 2160 .devices 2161 .clone() 2162 .unwrap()[0], 2163 device_config 2164 ); 2165 } 2166 2167 #[test] 2168 fn test_vmm_vm_cold_add_user_device() { 2169 let mut vmm = create_dummy_vmm(); 2170 let user_device_config = 2171 UserDeviceConfig::parse("socket=/path/to/socket,id=8,pci_segment=2").unwrap(); 2172 2173 assert!(matches!( 2174 vmm.vm_add_user_device(user_device_config.clone()), 2175 Err(VmError::VmNotCreated) 2176 )); 2177 2178 let _ = vmm.vm_create(create_dummy_vm_config()); 2179 assert!(vmm 2180 .vm_config 2181 .as_ref() 2182 .unwrap() 2183 .lock() 2184 .unwrap() 2185 .user_devices 2186 .is_none()); 2187 2188 let result = vmm.vm_add_user_device(user_device_config.clone()); 2189 assert!(result.is_ok()); 2190 assert!(result.unwrap().is_none()); 2191 assert_eq!( 2192 vmm.vm_config 2193 .as_ref() 2194 .unwrap() 2195 .lock() 2196 .unwrap() 2197 .user_devices 2198 .clone() 2199 .unwrap() 2200 .len(), 2201 1 2202 ); 2203 assert_eq!( 2204 vmm.vm_config 2205 .as_ref() 2206 .unwrap() 2207 .lock() 2208 .unwrap() 2209 .user_devices 2210 .clone() 2211 .unwrap()[0], 2212 user_device_config 2213 ); 2214 } 2215 2216 #[test] 2217 fn test_vmm_vm_cold_add_disk() { 2218 let mut vmm = create_dummy_vmm(); 2219 let disk_config = DiskConfig::parse("path=/path/to_file").unwrap(); 2220 2221 assert!(matches!( 2222 vmm.vm_add_disk(disk_config.clone()), 2223 Err(VmError::VmNotCreated) 2224 )); 2225 2226 let _ = vmm.vm_create(create_dummy_vm_config()); 2227 assert!(vmm 2228 .vm_config 2229 .as_ref() 2230 .unwrap() 2231 .lock() 2232 .unwrap() 2233 .disks 2234 .is_none()); 2235 2236 let result = vmm.vm_add_disk(disk_config.clone()); 2237 assert!(result.is_ok()); 2238 assert!(result.unwrap().is_none()); 2239 assert_eq!( 2240 vmm.vm_config 2241 .as_ref() 2242 .unwrap() 2243 .lock() 2244 .unwrap() 2245 .disks 2246 .clone() 2247 .unwrap() 2248 .len(), 2249 1 2250 ); 2251 assert_eq!( 2252 vmm.vm_config 2253 .as_ref() 2254 .unwrap() 2255 .lock() 2256 .unwrap() 2257 .disks 2258 .clone() 2259 .unwrap()[0], 2260 disk_config 2261 ); 2262 } 2263 2264 #[test] 2265 fn test_vmm_vm_cold_add_fs() { 2266 let mut vmm = create_dummy_vmm(); 2267 let fs_config = FsConfig::parse("tag=mytag,socket=/tmp/sock").unwrap(); 2268 2269 assert!(matches!( 2270 vmm.vm_add_fs(fs_config.clone()), 2271 Err(VmError::VmNotCreated) 2272 )); 2273 2274 let _ = vmm.vm_create(create_dummy_vm_config()); 2275 assert!(vmm.vm_config.as_ref().unwrap().lock().unwrap().fs.is_none()); 2276 2277 let result = vmm.vm_add_fs(fs_config.clone()); 2278 assert!(result.is_ok()); 2279 assert!(result.unwrap().is_none()); 2280 assert_eq!( 2281 vmm.vm_config 2282 .as_ref() 2283 .unwrap() 2284 .lock() 2285 .unwrap() 2286 .fs 2287 .clone() 2288 .unwrap() 2289 .len(), 2290 1 2291 ); 2292 assert_eq!( 2293 vmm.vm_config 2294 .as_ref() 2295 .unwrap() 2296 .lock() 2297 .unwrap() 2298 .fs 2299 .clone() 2300 .unwrap()[0], 2301 fs_config 2302 ); 2303 } 2304 2305 #[test] 2306 fn test_vmm_vm_cold_add_pmem() { 2307 let mut vmm = create_dummy_vmm(); 2308 let pmem_config = PmemConfig::parse("file=/tmp/pmem,size=128M").unwrap(); 2309 2310 assert!(matches!( 2311 vmm.vm_add_pmem(pmem_config.clone()), 2312 Err(VmError::VmNotCreated) 2313 )); 2314 2315 let _ = vmm.vm_create(create_dummy_vm_config()); 2316 assert!(vmm 2317 .vm_config 2318 .as_ref() 2319 .unwrap() 2320 .lock() 2321 .unwrap() 2322 .pmem 2323 .is_none()); 2324 2325 let result = vmm.vm_add_pmem(pmem_config.clone()); 2326 assert!(result.is_ok()); 2327 assert!(result.unwrap().is_none()); 2328 assert_eq!( 2329 vmm.vm_config 2330 .as_ref() 2331 .unwrap() 2332 .lock() 2333 .unwrap() 2334 .pmem 2335 .clone() 2336 .unwrap() 2337 .len(), 2338 1 2339 ); 2340 assert_eq!( 2341 vmm.vm_config 2342 .as_ref() 2343 .unwrap() 2344 .lock() 2345 .unwrap() 2346 .pmem 2347 .clone() 2348 .unwrap()[0], 2349 pmem_config 2350 ); 2351 } 2352 2353 #[test] 2354 fn test_vmm_vm_cold_add_net() { 2355 let mut vmm = create_dummy_vmm(); 2356 let net_config = NetConfig::parse( 2357 "mac=de:ad:be:ef:12:34,host_mac=12:34:de:ad:be:ef,vhost_user=true,socket=/tmp/sock", 2358 ) 2359 .unwrap(); 2360 2361 assert!(matches!( 2362 vmm.vm_add_net(net_config.clone()), 2363 Err(VmError::VmNotCreated) 2364 )); 2365 2366 let _ = vmm.vm_create(create_dummy_vm_config()); 2367 assert!(vmm 2368 .vm_config 2369 .as_ref() 2370 .unwrap() 2371 .lock() 2372 .unwrap() 2373 .net 2374 .is_none()); 2375 2376 let result = vmm.vm_add_net(net_config.clone()); 2377 assert!(result.is_ok()); 2378 assert!(result.unwrap().is_none()); 2379 assert_eq!( 2380 vmm.vm_config 2381 .as_ref() 2382 .unwrap() 2383 .lock() 2384 .unwrap() 2385 .net 2386 .clone() 2387 .unwrap() 2388 .len(), 2389 1 2390 ); 2391 assert_eq!( 2392 vmm.vm_config 2393 .as_ref() 2394 .unwrap() 2395 .lock() 2396 .unwrap() 2397 .net 2398 .clone() 2399 .unwrap()[0], 2400 net_config 2401 ); 2402 } 2403 2404 #[test] 2405 fn test_vmm_vm_cold_add_vdpa() { 2406 let mut vmm = create_dummy_vmm(); 2407 let vdpa_config = VdpaConfig::parse("path=/dev/vhost-vdpa,num_queues=2").unwrap(); 2408 2409 assert!(matches!( 2410 vmm.vm_add_vdpa(vdpa_config.clone()), 2411 Err(VmError::VmNotCreated) 2412 )); 2413 2414 let _ = vmm.vm_create(create_dummy_vm_config()); 2415 assert!(vmm 2416 .vm_config 2417 .as_ref() 2418 .unwrap() 2419 .lock() 2420 .unwrap() 2421 .vdpa 2422 .is_none()); 2423 2424 let result = vmm.vm_add_vdpa(vdpa_config.clone()); 2425 assert!(result.is_ok()); 2426 assert!(result.unwrap().is_none()); 2427 assert_eq!( 2428 vmm.vm_config 2429 .as_ref() 2430 .unwrap() 2431 .lock() 2432 .unwrap() 2433 .vdpa 2434 .clone() 2435 .unwrap() 2436 .len(), 2437 1 2438 ); 2439 assert_eq!( 2440 vmm.vm_config 2441 .as_ref() 2442 .unwrap() 2443 .lock() 2444 .unwrap() 2445 .vdpa 2446 .clone() 2447 .unwrap()[0], 2448 vdpa_config 2449 ); 2450 } 2451 2452 #[test] 2453 fn test_vmm_vm_cold_add_vsock() { 2454 let mut vmm = create_dummy_vmm(); 2455 let vsock_config = VsockConfig::parse("socket=/tmp/sock,cid=1,iommu=on").unwrap(); 2456 2457 assert!(matches!( 2458 vmm.vm_add_vsock(vsock_config.clone()), 2459 Err(VmError::VmNotCreated) 2460 )); 2461 2462 let _ = vmm.vm_create(create_dummy_vm_config()); 2463 assert!(vmm 2464 .vm_config 2465 .as_ref() 2466 .unwrap() 2467 .lock() 2468 .unwrap() 2469 .vsock 2470 .is_none()); 2471 2472 let result = vmm.vm_add_vsock(vsock_config.clone()); 2473 assert!(result.is_ok()); 2474 assert!(result.unwrap().is_none()); 2475 assert_eq!( 2476 vmm.vm_config 2477 .as_ref() 2478 .unwrap() 2479 .lock() 2480 .unwrap() 2481 .vsock 2482 .clone() 2483 .unwrap(), 2484 vsock_config 2485 ); 2486 } 2487 } 2488