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