1use anyhow::{Context, Result};
2use nix::{
3 sched::{self, CloneFlags},
4 unistd::Pid,
5};
6use oci_spec::runtime::LinuxNamespace;
7use procfs::process::{ProcState, Process};
8
9use crate::linux::namespace;
10
11pub fn clone_child(
16 namespace_list: &[LinuxNamespace],
17 child_fn: impl FnMut() -> isize,
18) -> Result<Pid> {
19 const STACK_SIZE: usize = 4 * 1024 * 1024;
20 let mut stack: [u8; STACK_SIZE] = [0; STACK_SIZE];
21
22 let clone_flags = namespace_list
23 .iter()
24 .map(namespace::linux_namespace_to_clone_flags)
25 .reduce(|flag_1, flag_2| flag_1 | flag_2)
26 .unwrap_or(CloneFlags::empty());
27
28 let pid = sched::clone(Box::new(child_fn), &mut stack, clone_flags, None)
29 .context("failed to clone the container process")?;
30 Ok(pid)
31}
32
33pub fn inspect_process(pid: i32) -> Result<ProcState> {
36 let process = Process::new(pid).context(format!("failed to inspect the process {}", pid))?;
37 let process_stat = process
38 .stat()
39 .context(format!("failed to inspect the status of process {}", pid))?;
40 let state = process_stat
41 .state()
42 .context(format!("failed to inspect the state of process {}", pid))?;
43 Ok(state)
44}