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