github.com/kata-containers/runtime@v0.0.0-20210505125100-04f29832a923/virtcontainers/utils/proc_linux.go (about)

     1  // Copyright (c) 2019 Hyper.sh
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  //
     5  
     6  package utils
     7  
     8  import (
     9  	"io/ioutil"
    10  	"path/filepath"
    11  	"strconv"
    12  
    13  	"github.com/pkg/errors"
    14  	"github.com/prometheus/procfs"
    15  )
    16  
    17  const taskPath = "task"
    18  
    19  type Proc struct {
    20  	*procfs.Proc
    21  }
    22  
    23  func NewProc(pid int) (*Proc, error) {
    24  	p, err := procfs.NewProc(pid)
    25  	if err != nil {
    26  		return nil, errors.Wrapf(err, "Invalid pid %v", pid)
    27  	}
    28  
    29  	return &Proc{&p}, nil
    30  }
    31  
    32  // We should try to upstream this but let's keep it until upstream supports it.
    33  func (p *Proc) Children() ([]*Proc, error) {
    34  	parent := strconv.Itoa(p.PID)
    35  	infos, err := ioutil.ReadDir(filepath.Join(procfs.DefaultMountPoint, parent, taskPath))
    36  	if err != nil {
    37  		return nil, errors.Wrapf(err, "Fail to read pid %v proc task dir", p.PID)
    38  	}
    39  
    40  	var children []*Proc
    41  	for _, info := range infos {
    42  		if !info.IsDir() || info.Name() == parent {
    43  			continue
    44  		}
    45  		pid, err := strconv.Atoi(info.Name())
    46  		if err != nil {
    47  			return nil, errors.Wrapf(err, "Invalid child pid %v", info.Name())
    48  		}
    49  		child, err := NewProc(pid)
    50  		if err != nil {
    51  			return nil, err
    52  		}
    53  		children = append(children, child)
    54  	}
    55  
    56  	return children, nil
    57  }