1 // Copyright © 2021 Intel Corporation 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 6 use crate::{ 7 seccomp_filters::{get_seccomp_filter, Thread}, 8 ActivateError, 9 }; 10 use seccompiler::{apply_filter, SeccompAction}; 11 use std::{ 12 panic::AssertUnwindSafe, 13 thread::{self, JoinHandle}, 14 }; 15 use vmm_sys_util::eventfd::EventFd; 16 17 pub(crate) fn spawn_virtio_thread<F>( 18 name: &str, 19 seccomp_action: &SeccompAction, 20 thread_type: Thread, 21 epoll_threads: &mut Vec<JoinHandle<()>>, 22 exit_evt: &EventFd, 23 f: F, 24 ) -> Result<(), ActivateError> 25 where 26 F: FnOnce(), 27 F: Send + 'static, 28 { 29 let seccomp_filter = get_seccomp_filter(seccomp_action, thread_type) 30 .map_err(ActivateError::CreateSeccompFilter)?; 31 32 let thread_exit_evt = exit_evt 33 .try_clone() 34 .map_err(ActivateError::CloneExitEventFd)?; 35 let thread_name = name.to_string(); 36 37 thread::Builder::new() 38 .name(name.to_string()) 39 .spawn(move || { 40 if !seccomp_filter.is_empty() { 41 if let Err(e) = apply_filter(&seccomp_filter) { 42 error!("Error applying seccomp filter: {:?}", e); 43 thread_exit_evt.write(1).ok(); 44 return; 45 } 46 } 47 std::panic::catch_unwind(AssertUnwindSafe(move || f())) 48 .or_else(|_| { 49 error!("{} thread panicked", thread_name); 50 thread_exit_evt.write(1) 51 }) 52 .ok(); 53 }) 54 .map(|thread| epoll_threads.push(thread)) 55 .map_err(|e| { 56 error!("Failed to spawn thread for {}: {}", name, e); 57 ActivateError::ThreadSpawn(e) 58 }) 59 } 60