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