proc.go 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package proc
  2. import (
  3. "bytes"
  4. "os"
  5. "path"
  6. "strconv"
  7. "strings"
  8. "github.com/coroot/coroot-node-agent/cgroup"
  9. )
  10. var root = "/proc"
  11. func Path(pid uint32, subpath ...string) string {
  12. return path.Join(append([]string{root, strconv.Itoa(int(pid))}, subpath...)...)
  13. }
  14. func HostPath(p string) string {
  15. return Path(1, "root", p)
  16. }
  17. func GetCmdline(pid uint32) []byte {
  18. cmdline, err := os.ReadFile(Path(pid, "cmdline"))
  19. if err != nil {
  20. return nil
  21. }
  22. return bytes.TrimSuffix(cmdline, []byte{0})
  23. }
  24. func GetNsPid(pid uint32) uint32 {
  25. data, err := os.ReadFile(Path(pid, "status"))
  26. if err != nil {
  27. return pid
  28. }
  29. for _, line := range strings.Split(string(data), "\n") {
  30. fields := strings.Fields(line)
  31. if len(fields) < 2 {
  32. continue
  33. }
  34. if fields[0] == "NSpid:" {
  35. if len(fields) == 3 {
  36. if nsPid, err := strconv.ParseUint(fields[2], 10, 32); err == nil {
  37. return uint32(nsPid)
  38. }
  39. }
  40. return pid
  41. }
  42. }
  43. return pid
  44. }
  45. func ReadCgroup(pid uint32) (*cgroup.Cgroup, error) {
  46. return cgroup.NewFromProcessCgroupFile(Path(pid, "cgroup"))
  47. }
  48. func ListPids() ([]uint32, error) {
  49. root, err := os.Open(root)
  50. if err != nil {
  51. return nil, err
  52. }
  53. defer root.Close()
  54. dirs, err := root.Readdirnames(0)
  55. if err != nil {
  56. return nil, err
  57. }
  58. res := make([]uint32, 0, len(dirs))
  59. for _, dir := range dirs {
  60. pid64, err := strconv.ParseUint(dir, 10, 32)
  61. if err != nil {
  62. continue
  63. }
  64. res = append(res, uint32(pid64))
  65. }
  66. return res, nil
  67. }