xref: /cloud-hypervisor/vmm/src/lib.rs (revision 07d1208dd53a207a65b649b8952780dfd0ca59d9)
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