hyperlight_host/sandbox/
mod.rs1pub mod config;
19pub(crate) mod host_funcs;
21pub(crate) mod hypervisor;
23pub mod initialized_multi_use;
26pub(crate) mod outb;
27pub mod uninitialized;
30pub(crate) mod uninitialized_evolve;
33
34pub mod snapshot;
36
37mod callable;
39
40#[cfg(feature = "trace_guest")]
42pub(crate) mod trace;
43
44pub use callable::Callable;
46pub use config::SandboxConfiguration;
48pub use initialized_multi_use::MultiUseSandbox;
50use tracing::{Span, instrument};
51pub use uninitialized::GuestBinary;
53pub use uninitialized::UninitializedSandbox;
55
56#[instrument(skip_all, parent = Span::current())]
61pub fn is_hypervisor_present() -> bool {
62 hypervisor::get_available_hypervisor().is_some()
63}
64
65#[cfg(test)]
66mod tests {
67 use std::sync::Arc;
68 use std::thread;
69
70 use crossbeam_queue::ArrayQueue;
71 use hyperlight_testing::simple_guest_as_string;
72
73 use crate::sandbox::uninitialized::GuestBinary;
74 use crate::{MultiUseSandbox, UninitializedSandbox, new_error};
75
76 #[test]
77 #[cfg(target_os = "linux")]
79 fn is_hypervisor_present() {
80 use std::path::Path;
81
82 cfg_if::cfg_if! {
83 if #[cfg(all(kvm, mshv3))] {
84 assert_eq!(Path::new("/dev/kvm").exists() || Path::new("/dev/mshv").exists(), super::is_hypervisor_present());
85 } else if #[cfg(kvm)] {
86 assert_eq!(Path::new("/dev/kvm").exists(), super::is_hypervisor_present());
87 } else if #[cfg(mshv3)] {
88 assert_eq!(Path::new("/dev/mshv").exists(), super::is_hypervisor_present());
89 } else {
90 assert!(!super::is_hypervisor_present());
91 }
92 }
93 }
94
95 #[test]
96 fn check_create_and_use_sandbox_on_different_threads() {
97 let unintializedsandbox_queue = Arc::new(ArrayQueue::<UninitializedSandbox>::new(10));
98 let sandbox_queue = Arc::new(ArrayQueue::<MultiUseSandbox>::new(10));
99
100 for i in 0..10 {
101 let simple_guest_path = simple_guest_as_string().expect("Guest Binary Missing");
102 let unintializedsandbox =
103 UninitializedSandbox::new(GuestBinary::FilePath(simple_guest_path), None)
104 .unwrap_or_else(|_| panic!("Failed to create UninitializedSandbox {}", i));
105
106 unintializedsandbox_queue
107 .push(unintializedsandbox)
108 .unwrap_or_else(|_| panic!("Failed to push UninitializedSandbox {}", i));
109 }
110
111 let thread_handles = (0..10)
112 .map(|i| {
113 let uq = unintializedsandbox_queue.clone();
114 let sq = sandbox_queue.clone();
115 thread::spawn(move || {
116 let uninitialized_sandbox = uq.pop().unwrap_or_else(|| {
117 panic!("Failed to pop UninitializedSandbox thread {}", i)
118 });
119 let host_funcs = uninitialized_sandbox
120 .host_funcs
121 .try_lock()
122 .map_err(|_| new_error!("Error locking"));
123
124 assert!(host_funcs.is_ok());
125
126 host_funcs
127 .unwrap()
128 .host_print(format!(
129 "Printing from UninitializedSandbox on Thread {}\n",
130 i
131 ))
132 .unwrap();
133
134 let sandbox = uninitialized_sandbox.evolve().unwrap_or_else(|_| {
135 panic!("Failed to initialize UninitializedSandbox thread {}", i)
136 });
137
138 sq.push(sandbox).unwrap_or_else(|_| {
139 panic!("Failed to push UninitializedSandbox thread {}", i)
140 })
141 })
142 })
143 .collect::<Vec<_>>();
144
145 for handle in thread_handles {
146 handle.join().unwrap();
147 }
148
149 let thread_handles = (0..10)
150 .map(|i| {
151 let sq = sandbox_queue.clone();
152 thread::spawn(move || {
153 let sandbox = sq
154 .pop()
155 .unwrap_or_else(|| panic!("Failed to pop Sandbox thread {}", i));
156 let host_funcs = sandbox
157 .host_funcs
158 .try_lock()
159 .map_err(|_| new_error!("Error locking"));
160
161 assert!(host_funcs.is_ok());
162
163 host_funcs
164 .unwrap()
165 .host_print(format!("Print from Sandbox on Thread {}\n", i))
166 .unwrap();
167 })
168 })
169 .collect::<Vec<_>>();
170
171 for handle in thread_handles {
172 handle.join().unwrap();
173 }
174 }
175}