proc.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. package proc
  2. import (
  3. "bytes"
  4. "fmt"
  5. "os"
  6. "path"
  7. "strconv"
  8. "strings"
  9. "github.com/coroot/coroot-node-agent/cgroup"
  10. )
  11. var root = "/proc"
  12. func Path(pid uint32, subpath ...string) string {
  13. return path.Join(append([]string{root, strconv.Itoa(int(pid))}, subpath...)...)
  14. }
  15. func HostPath(p string) string {
  16. return Path(1, "root", p)
  17. }
  18. func GetCmdline(pid uint32) []byte {
  19. cmdline, err := os.ReadFile(Path(pid, "cmdline"))
  20. if err != nil {
  21. return nil
  22. }
  23. return bytes.TrimSuffix(cmdline, []byte{0})
  24. }
  25. func GetRealCmdline(pid uint32) []byte {
  26. cmdline, err := os.ReadFile(Path(pid, "cmdline"))
  27. if err != nil {
  28. return nil
  29. }
  30. return bytes.ReplaceAll(cmdline, []byte("\x00"), []byte(" "))
  31. }
  32. func GetExe(pid uint32) []byte {
  33. exe, err := os.ReadFile(Path(pid, "exe"))
  34. if err != nil {
  35. fmt.Printf("Error reading executable path for PID %d: %v\n", pid, err)
  36. return nil
  37. }
  38. return bytes.TrimSuffix(exe, []byte{0})
  39. }
  40. func GetNsPid(pid uint32) uint32 {
  41. data, err := os.ReadFile(Path(pid, "status"))
  42. if err != nil {
  43. return pid
  44. }
  45. for _, line := range strings.Split(string(data), "\n") {
  46. fields := strings.Fields(line)
  47. if len(fields) < 2 {
  48. continue
  49. }
  50. if fields[0] == "NSpid:" {
  51. if len(fields) == 3 {
  52. if nsPid, err := strconv.ParseUint(fields[2], 10, 32); err == nil {
  53. return uint32(nsPid)
  54. }
  55. }
  56. return pid
  57. }
  58. }
  59. return pid
  60. }
  61. func ReadCgroup(pid uint32) (*cgroup.Cgroup, error) {
  62. return cgroup.NewFromProcessCgroupFile(Path(pid, "cgroup"))
  63. }
  64. func ListPids() ([]uint32, error) {
  65. root, err := os.Open(root)
  66. if err != nil {
  67. return nil, err
  68. }
  69. defer root.Close()
  70. dirs, err := root.Readdirnames(0)
  71. if err != nil {
  72. return nil, err
  73. }
  74. res := make([]uint32, 0, len(dirs))
  75. for _, dir := range dirs {
  76. pid64, err := strconv.ParseUint(dir, 10, 32)
  77. if err != nil {
  78. continue
  79. }
  80. res = append(res, uint32(pid64))
  81. }
  82. return res, nil
  83. }
  84. func GetProcName(pid uint32) string {
  85. comm, err := os.ReadFile(Path(pid, "comm"))
  86. if err != nil {
  87. return ""
  88. }
  89. return string(bytes.TrimRight(comm, "\n"))
  90. }