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