Skip to content

Instantly share code, notes, and snippets.

@r10r
Created October 9, 2020 14:17
Show Gist options
  • Save r10r/74e06ec509f9b0c92e809375386f5abf to your computer and use it in GitHub Desktop.
Save r10r/74e06ec509f9b0c92e809375386f5abf to your computer and use it in GitHub Desktop.
Example how to parse /proc/{pid}/task/{tid}/children recursively (see 'man 2 proc')
package main
import (
"fmt"
"io/ioutil"
"os"
"strings"
)
func GetAllChildren(proc string, pid string) ([]string, error) {
children, err := GetChildren(proc, pid)
if err != nil {
return nil, err
}
if len(children) == 0 {
return nil, nil
}
for _, childPid := range children {
grandChildren, err := GetAllChildren(proc, childPid)
if err != nil {
if os.IsNotExist(err) {
continue
}
return nil, err
}
if grandChildren != nil {
children = append(children, grandChildren...)
}
}
return children, nil
}
func GetChildren(proc string, pid string) ([]string, error) {
p := fmt.Sprintf("%s/%s/task/%s/children", proc, pid, pid)
data, err := ioutil.ReadFile(p)
if err != nil {
return nil, err
}
println(len(data))
if len(data) == 0 {
return nil, nil
}
return strings.Split(strings.TrimSpace(string(data)), " "), nil
}
package main
import (
"github.com/stretchr/testify/require"
"io/ioutil"
"os"
"path/filepath"
"testing"
)
func TestGetDescendants(t *testing.T) {
procValues := map[string]string{
"1/task/1/children": "2 3 4",
"2/task/2/children": "5 6 7",
"3/task/3/children": "8 9 10",
"4/task/4/children": "",
"5/task/5/children": "",
"6/task/6/children": "",
"7/task/7/children": "",
"8/task/8/children": "",
"9/task/9/children": "11 12 13",
"10/task/10/children": "",
"11/task/11/children": "",
}
dir, err := ioutil.TempDir("", "crio-lxc-proc")
require.NoError(t, err)
defer os.RemoveAll(dir)
for fileName, pids := range procValues {
fp := filepath.Join(dir, fileName)
os.MkdirAll(filepath.Dir(fp), 0755)
err := ioutil.WriteFile(fp, []byte(pids), 0660)
require.NoError(t, err)
}
c1, err := GetAllChildren(dir, "1")
require.NoError(t, err)
c1e := []string{"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"}
require.EqualValues(t, c1e, c1)
c2, err := GetAllChildren(dir, "2")
require.NoError(t, err)
c2e := []string{"5", "6", "7"}
require.EqualValues(t, c2, c2e)
c3, err := GetAllChildren(dir, "6")
require.Empty(t, c3)
require.NoError(t, err)
c4, err := GetAllChildren(dir, "12")
require.Empty(t, c4)
require.Error(t, os.ErrExist, err)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment