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