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