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