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