@@ -17,7 +17,7 @@ limitations under the License.
17
17
#[ cfg( target_os = "windows" ) ]
18
18
use core:: ffi:: c_void;
19
19
use std:: sync:: atomic:: { AtomicBool , Ordering } ;
20
- use std:: sync:: { Arc , Mutex } ;
20
+ use std:: sync:: { Arc , Mutex , MutexGuard } ;
21
21
use std:: thread;
22
22
use std:: thread:: { sleep, JoinHandle } ;
23
23
use std:: time:: Duration ;
@@ -64,6 +64,7 @@ pub(crate) struct HypervisorHandler {
64
64
communication_channels : HvHandlerCommChannels ,
65
65
configuration : HvHandlerConfig ,
66
66
execution_variables : HvHandlerExecVars ,
67
+ hypervisor : Option < Arc < Mutex < Box < dyn Hypervisor > > > > ,
67
68
}
68
69
69
70
impl HypervisorHandler {
@@ -215,9 +216,23 @@ impl HypervisorHandler {
215
216
communication_channels,
216
217
configuration,
217
218
execution_variables,
219
+ hypervisor : None ,
218
220
}
219
221
}
220
222
223
+ /// Sets the hypervisor for the Hypervisor Handler.
224
+ pub ( crate ) fn set_hypervisor ( & mut self , hv : Box < dyn Hypervisor > ) {
225
+ self . hypervisor = Some ( Arc :: new ( Mutex :: new ( hv) ) ) ;
226
+ }
227
+
228
+ /// Gets the hypervisor for the Hypervisor Handler.
229
+ pub ( crate ) fn get_hypervisor ( & self ) -> Result < MutexGuard < Box < dyn Hypervisor > > > {
230
+ self . hypervisor
231
+ . as_ref ( )
232
+ . ok_or_else ( || new_error ! ( "Failed to get hypervisor: {}:{}:" , file!( ) , line!( ) ) )
233
+ . map ( |hv| hv. lock ( ) . unwrap ( ) )
234
+ }
235
+
221
236
/// Sets up a Hypervisor 'handler', designed to listen to messages to execute a specific action,
222
237
/// such as:
223
238
/// - `initialise` resources,
@@ -228,13 +243,10 @@ impl HypervisorHandler {
228
243
#[ instrument( err( Debug ) , skip_all, parent = Span :: current( ) , level = "Trace" ) ]
229
244
pub ( crate ) fn start_hypervisor_handler (
230
245
& mut self ,
231
- mut sandbox_memory_manager : SandboxMemoryManager < GuestSharedMemory > ,
246
+ sandbox_memory_manager : SandboxMemoryManager < GuestSharedMemory > ,
232
247
) -> Result < ( ) > {
248
+ let mut sandbox_memory_manager_clone = sandbox_memory_manager. clone ( ) ;
233
249
let configuration = self . configuration . clone ( ) ;
234
- let mut hv = set_up_hypervisor_partition (
235
- & mut sandbox_memory_manager,
236
- configuration. outb_handler . clone ( ) ,
237
- ) ?;
238
250
#[ cfg( target_os = "windows" ) ]
239
251
let in_process = sandbox_memory_manager. is_in_process ( ) ;
240
252
@@ -267,20 +279,14 @@ impl HypervisorHandler {
267
279
#[ cfg( target_os = "linux" ) ]
268
280
self . execution_variables . run_cancelled . store ( false ) ;
269
281
270
- #[ cfg( target_os = "windows" ) ]
271
- if !in_process {
272
- self . execution_variables
273
- . set_partition_handle ( hv. get_partition_handle ( ) ) ?;
274
- }
275
-
276
282
let to_handler_rx = self . communication_channels . to_handler_rx . clone ( ) ;
277
283
#[ cfg( target_os = "windows" ) ]
278
284
let execution_variables = self . execution_variables . clone ( ) ;
279
285
#[ cfg( target_os = "linux" ) ]
280
286
let mut execution_variables = self . execution_variables . clone ( ) ;
281
287
// ^^^ this needs to be mut on linux to set_thread_id
282
288
let from_handler_tx = self . communication_channels . from_handler_tx . clone ( ) ;
283
- let hv_handler_clone = self . clone ( ) ;
289
+ let mut hv_handler_clone = self . clone ( ) ;
284
290
285
291
// Hyperlight has two signal handlers:
286
292
// (1) for timeouts, and
@@ -298,6 +304,23 @@ impl HypervisorHandler {
298
304
for action in to_handler_rx {
299
305
match action {
300
306
HypervisorHandlerAction :: Initialise => {
307
+ {
308
+ let hv = set_up_hypervisor_partition (
309
+ & mut sandbox_memory_manager_clone,
310
+ configuration. outb_handler . clone ( ) ,
311
+ ) ?;
312
+
313
+ hv_handler_clone. set_hypervisor ( hv) ;
314
+ }
315
+
316
+ let mut hv = hv_handler_clone. get_hypervisor ( ) ?;
317
+
318
+ #[ cfg( target_os = "windows" ) ]
319
+ if !in_process {
320
+ execution_variables
321
+ . set_partition_handle ( hv. get_partition_handle ( ) ) ?;
322
+ }
323
+
301
324
#[ cfg( target_os = "linux" ) ]
302
325
{
303
326
// We cannot use the Killable trait, so we get the `pthread_t` via a libc
@@ -362,6 +385,8 @@ impl HypervisorHandler {
362
385
}
363
386
}
364
387
HypervisorHandlerAction :: DispatchCallFromHost ( function_name) => {
388
+ let mut hv = hv_handler_clone. get_hypervisor ( ) ?;
389
+
365
390
// Lock to indicate an action is being performed in the hypervisor
366
391
execution_variables. running . store ( true , Ordering :: SeqCst ) ;
367
392
@@ -944,6 +969,13 @@ mod tests {
944
969
}
945
970
}
946
971
972
+ #[ test]
973
+ fn create_10_sandboxes ( ) {
974
+ for _ in 0 ..10 {
975
+ create_multi_use_sandbox ( ) ;
976
+ }
977
+ }
978
+
947
979
#[ test]
948
980
fn hello_world ( ) -> Result < ( ) > {
949
981
let mut sandbox = create_multi_use_sandbox ( ) ;
0 commit comments