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