xref: /cloud-hypervisor/virtio-devices/src/thread_helper.rs (revision 61e57e1cb149de03ae1e0b799b9e5ba9a4a63ace)
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