...
1
2
3
4
19
20 package pidlimit
21
22 import (
23 "fmt"
24 "os"
25 "strconv"
26 "strings"
27 "syscall"
28 "time"
29
30 v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
31 statsapi "k8s.io/kubelet/pkg/apis/stats/v1alpha1"
32 )
33
34
35 func Stats() (*statsapi.RlimitStats, error) {
36 rlimit := &statsapi.RlimitStats{}
37
38 taskMax := int64(-1)
39
40
41 for _, file := range []string{"/proc/sys/kernel/pid_max", "/proc/sys/kernel/threads-max"} {
42 if content, err := os.ReadFile(file); err == nil {
43 if limit, err := strconv.ParseInt(string(content[:len(content)-1]), 10, 64); err == nil {
44 if taskMax == -1 || taskMax > limit {
45 taskMax = limit
46 }
47 }
48 }
49 }
50
51 if taskMax >= 0 {
52 rlimit.MaxPID = &taskMax
53 }
54
55
56
57
58 if procs, err := runningTaskCount(); err == nil {
59 rlimit.NumOfRunningProcesses = &procs
60 } else {
61 var info syscall.Sysinfo_t
62 syscall.Sysinfo(&info)
63 procs := int64(info.Procs)
64 rlimit.NumOfRunningProcesses = &procs
65 }
66
67 rlimit.Time = v1.NewTime(time.Now())
68
69 return rlimit, nil
70 }
71
72 func runningTaskCount() (int64, error) {
73
74 bytes, err := os.ReadFile("/proc/loadavg")
75 if err != nil {
76 return 0, err
77 }
78 fields := strings.Fields(string(bytes))
79 if len(fields) < 5 {
80 return 0, fmt.Errorf("not enough fields in /proc/loadavg")
81 }
82 subfields := strings.Split(fields[3], "/")
83 if len(subfields) != 2 {
84 return 0, fmt.Errorf("error parsing fourth field of /proc/loadavg")
85 }
86 return strconv.ParseInt(subfields[1], 10, 64)
87 }
88
View as plain text