@@ -108,14 +108,39 @@ fn fork_and_wait() -> Result<()> {
108108/// The reason we need this is because we actually need to attach to the
109109/// *supervised* process, not the *supervisor* process, which exists in
110110/// a different set of namespaces than the ones we want to attach to.
111+ ///
112+ /// Tries `/proc/<pid>/task/<pid>/children` first (requires CONFIG_PROC_CHILDREN),
113+ /// then falls back to scanning `/proc` for processes whose PPid matches.
111114fn first_child_pid_of ( parent : libc:: pid_t ) -> Result < libc:: pid_t > {
112- let child_set = fs:: read_to_string ( format ! ( "/proc/{parent}/task/{parent}/children" ) ) ?;
113- let first_child = child_set. split ( " " ) . collect :: < Vec < _ > > ( ) [ 0 ] ;
115+ // Fast path: use the children file if available (CONFIG_PROC_CHILDREN=y).
116+ let children_path = format ! ( "/proc/{parent}/task/{parent}/children" ) ;
117+ if let Ok ( child_set) = fs:: read_to_string ( & children_path) {
118+ let first_child = child_set. split ( ' ' ) . next ( ) . unwrap_or ( "" ) ;
119+ if let Ok ( v) = first_child. parse :: < libc:: pid_t > ( ) {
120+ return Ok ( v) ;
121+ }
122+ }
114123
115- match first_child. parse :: < libc:: pid_t > ( ) {
116- Ok ( v) => Ok ( v) ,
117- _ => Err ( anyhow ! ( "failed to find child PID" ) ) ,
124+ // Fallback: scan /proc for a process whose PPid matches parent.
125+ debug ! ( "children file unavailable for pid {parent}, falling back to /proc scan" ) ;
126+ let ppid_needle = format ! ( "PPid:\t {parent}" ) ;
127+ for entry in fs:: read_dir ( "/proc" ) ? {
128+ let entry = entry?;
129+ let name = entry. file_name ( ) ;
130+ let name_str = name. to_string_lossy ( ) ;
131+ if !name_str. chars ( ) . next ( ) . is_some_and ( |c| c. is_ascii_digit ( ) ) {
132+ continue ;
133+ }
134+ let status_path = format ! ( "/proc/{name_str}/status" ) ;
135+ if let Ok ( status) = fs:: read_to_string ( & status_path)
136+ && status. lines ( ) . any ( |line| line == ppid_needle)
137+ && let Ok ( pid) = name_str. parse :: < libc:: pid_t > ( )
138+ {
139+ return Ok ( pid) ;
140+ }
118141 }
142+
143+ Err ( anyhow ! ( "failed to find child PID of {parent}" ) )
119144}
120145
121146fn render_uidgid_mappings ( mappings : & [ IdMapping ] ) -> String {
0 commit comments