154e523c3SRob Bradford // Copyright © 2021 Intel Corporation
254e523c3SRob Bradford //
354e523c3SRob Bradford // SPDX-License-Identifier: Apache-2.0
454e523c3SRob Bradford //
554e523c3SRob Bradford
6*61e57e1cSRuoqing He use std::panic::AssertUnwindSafe;
7*61e57e1cSRuoqing He use std::thread::{self, JoinHandle};
888a9f799SRob Bradford
988a9f799SRob Bradford use seccompiler::{apply_filter, SeccompAction};
1088a9f799SRob Bradford use vmm_sys_util::eventfd::EventFd;
1188a9f799SRob Bradford
12*61e57e1cSRuoqing He use crate::epoll_helper::EpollHelperError;
13*61e57e1cSRuoqing He use crate::seccomp_filters::{get_seccomp_filter, Thread};
14*61e57e1cSRuoqing He use crate::ActivateError;
1554e523c3SRob Bradford
spawn_virtio_thread<F>( name: &str, seccomp_action: &SeccompAction, thread_type: Thread, epoll_threads: &mut Vec<JoinHandle<()>>, exit_evt: &EventFd, f: F, ) -> Result<(), ActivateError> where F: FnOnce() -> std::result::Result<(), EpollHelperError>, F: Send + 'static,1654e523c3SRob Bradford pub(crate) fn spawn_virtio_thread<F>(
1754e523c3SRob Bradford name: &str,
1854e523c3SRob Bradford seccomp_action: &SeccompAction,
1954e523c3SRob Bradford thread_type: Thread,
2054e523c3SRob Bradford epoll_threads: &mut Vec<JoinHandle<()>>,
21687d646cSRob Bradford exit_evt: &EventFd,
2254e523c3SRob Bradford f: F,
2354e523c3SRob Bradford ) -> Result<(), ActivateError>
2454e523c3SRob Bradford where
25df5b803aSBo Chen F: FnOnce() -> std::result::Result<(), EpollHelperError>,
2654e523c3SRob Bradford F: Send + 'static,
2754e523c3SRob Bradford {
2854e523c3SRob Bradford let seccomp_filter = get_seccomp_filter(seccomp_action, thread_type)
2954e523c3SRob Bradford .map_err(ActivateError::CreateSeccompFilter)?;
3054e523c3SRob Bradford
31687d646cSRob Bradford let thread_exit_evt = exit_evt
32687d646cSRob Bradford .try_clone()
33687d646cSRob Bradford .map_err(ActivateError::CloneExitEventFd)?;
34687d646cSRob Bradford let thread_name = name.to_string();
35687d646cSRob Bradford
3654e523c3SRob Bradford thread::Builder::new()
3754e523c3SRob Bradford .name(name.to_string())
3854e523c3SRob Bradford .spawn(move || {
3954e523c3SRob Bradford if !seccomp_filter.is_empty() {
4054e523c3SRob Bradford if let Err(e) = apply_filter(&seccomp_filter) {
4154e523c3SRob Bradford error!("Error applying seccomp filter: {:?}", e);
42687d646cSRob Bradford thread_exit_evt.write(1).ok();
4354e523c3SRob Bradford return;
4454e523c3SRob Bradford }
4554e523c3SRob Bradford }
46df5b803aSBo Chen match std::panic::catch_unwind(AssertUnwindSafe(f)) {
47df5b803aSBo Chen Err(_) => {
48687d646cSRob Bradford error!("{} thread panicked", thread_name);
49df5b803aSBo Chen thread_exit_evt.write(1).ok();
50df5b803aSBo Chen }
51df5b803aSBo Chen Ok(r) => {
52df5b803aSBo Chen if let Err(e) = r {
53df5b803aSBo Chen error!("Error running worker: {:?}", e);
54df5b803aSBo Chen thread_exit_evt.write(1).ok();
55df5b803aSBo Chen }
56df5b803aSBo Chen }
57df5b803aSBo Chen };
5854e523c3SRob Bradford })
5954e523c3SRob Bradford .map(|thread| epoll_threads.push(thread))
6054e523c3SRob Bradford .map_err(|e| {
6154e523c3SRob Bradford error!("Failed to spawn thread for {}: {}", name, e);
62687d646cSRob Bradford ActivateError::ThreadSpawn(e)
6354e523c3SRob Bradford })
6454e523c3SRob Bradford }
65