ghostscope_process/pid/
session.rs1use std::fmt;
2
3use tracing::warn;
4
5use super::{
6 build_runtime_pid_plan, detect_runtime_environment, resolve_input_pid, PidModeFailFast,
7 PidViews, RuntimeEnvironmentInfo, RuntimePidPlan, RuntimePidPlanInput,
8};
9
10#[derive(Debug)]
11pub enum ResolvePidSessionError {
12 Resolve(anyhow::Error),
13 FailFast(PidModeFailFast),
14}
15
16impl fmt::Display for ResolvePidSessionError {
17 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18 match self {
19 ResolvePidSessionError::Resolve(err) => write!(f, "{err}"),
20 ResolvePidSessionError::FailFast(PidModeFailFast { proc_pid }) => {
21 write!(f, "PID mode is not reliable for proc pid {proc_pid}")
22 }
23 }
24 }
25}
26
27impl std::error::Error for ResolvePidSessionError {
28 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
29 match self {
30 ResolvePidSessionError::Resolve(err) => Some(err.as_ref()),
31 ResolvePidSessionError::FailFast(_) => None,
32 }
33 }
34}
35
36impl From<anyhow::Error> for ResolvePidSessionError {
37 fn from(value: anyhow::Error) -> Self {
38 ResolvePidSessionError::Resolve(value)
39 }
40}
41
42#[derive(Debug, Clone)]
43pub struct ResolvedPidSession {
44 pub runtime_env: RuntimeEnvironmentInfo,
45 pub target_pid_views: Option<PidViews>,
46 pub self_pid_views: Option<PidViews>,
47 pub runtime_pid_plan: RuntimePidPlan,
48}
49
50pub fn resolve_pid_session(
51 input_pid: Option<u32>,
52 helper_supported: bool,
53) -> Result<ResolvedPidSession, ResolvePidSessionError> {
54 let runtime_env = detect_runtime_environment();
55 let in_container = runtime_env.is_container_likely();
56
57 let target_pid_views = input_pid.map(resolve_input_pid).transpose()?;
58 let self_pid_views = if helper_supported && in_container {
59 let self_pid = std::process::id();
60 match resolve_input_pid(self_pid) {
61 Ok(pid_views) => Some(pid_views),
62 Err(err) => {
63 warn!(
64 "Failed to resolve self PID namespace context (self pid={}): {}",
65 self_pid, err
66 );
67 None
68 }
69 }
70 } else {
71 None
72 };
73
74 let runtime_pid_plan = build_runtime_pid_plan(RuntimePidPlanInput {
75 target_pid_views: target_pid_views.as_ref(),
76 self_pid_views: self_pid_views.as_ref(),
77 in_container,
78 helper_supported,
79 })
80 .map_err(ResolvePidSessionError::FailFast)?;
81
82 Ok(ResolvedPidSession {
83 runtime_env,
84 target_pid_views,
85 self_pid_views,
86 runtime_pid_plan,
87 })
88}