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