proc_limits.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package procfs
  2. import (
  3. "bufio"
  4. "fmt"
  5. "os"
  6. "regexp"
  7. "strconv"
  8. )
  9. // ProcLimits represents the soft limits for each of the process's resource
  10. // limits. For more information see getrlimit(2):
  11. // http://man7.org/linux/man-pages/man2/getrlimit.2.html.
  12. type ProcLimits struct {
  13. // CPU time limit in seconds.
  14. CPUTime int
  15. // Maximum size of files that the process may create.
  16. FileSize int
  17. // Maximum size of the process's data segment (initialized data,
  18. // uninitialized data, and heap).
  19. DataSize int
  20. // Maximum size of the process stack in bytes.
  21. StackSize int
  22. // Maximum size of a core file.
  23. CoreFileSize int
  24. // Limit of the process's resident set in pages.
  25. ResidentSet int
  26. // Maximum number of processes that can be created for the real user ID of
  27. // the calling process.
  28. Processes int
  29. // Value one greater than the maximum file descriptor number that can be
  30. // opened by this process.
  31. OpenFiles int
  32. // Maximum number of bytes of memory that may be locked into RAM.
  33. LockedMemory int
  34. // Maximum size of the process's virtual memory address space in bytes.
  35. AddressSpace int
  36. // Limit on the combined number of flock(2) locks and fcntl(2) leases that
  37. // this process may establish.
  38. FileLocks int
  39. // Limit of signals that may be queued for the real user ID of the calling
  40. // process.
  41. PendingSignals int
  42. // Limit on the number of bytes that can be allocated for POSIX message
  43. // queues for the real user ID of the calling process.
  44. MsqqueueSize int
  45. // Limit of the nice priority set using setpriority(2) or nice(2).
  46. NicePriority int
  47. // Limit of the real-time priority set using sched_setscheduler(2) or
  48. // sched_setparam(2).
  49. RealtimePriority int
  50. // Limit (in microseconds) on the amount of CPU time that a process
  51. // scheduled under a real-time scheduling policy may consume without making
  52. // a blocking system call.
  53. RealtimeTimeout int
  54. }
  55. const (
  56. limitsFields = 3
  57. limitsUnlimited = "unlimited"
  58. )
  59. var (
  60. limitsDelimiter = regexp.MustCompile(" +")
  61. )
  62. // NewLimits returns the current soft limits of the process.
  63. func (p Proc) NewLimits() (ProcLimits, error) {
  64. f, err := os.Open(p.path("limits"))
  65. if err != nil {
  66. return ProcLimits{}, err
  67. }
  68. defer f.Close()
  69. var (
  70. l = ProcLimits{}
  71. s = bufio.NewScanner(f)
  72. )
  73. for s.Scan() {
  74. fields := limitsDelimiter.Split(s.Text(), limitsFields)
  75. if len(fields) != limitsFields {
  76. return ProcLimits{}, fmt.Errorf(
  77. "couldn't parse %s line %s", f.Name(), s.Text())
  78. }
  79. switch fields[0] {
  80. case "Max cpu time":
  81. l.CPUTime, err = parseInt(fields[1])
  82. case "Max file size":
  83. l.FileSize, err = parseInt(fields[1])
  84. case "Max data size":
  85. l.DataSize, err = parseInt(fields[1])
  86. case "Max stack size":
  87. l.StackSize, err = parseInt(fields[1])
  88. case "Max core file size":
  89. l.CoreFileSize, err = parseInt(fields[1])
  90. case "Max resident set":
  91. l.ResidentSet, err = parseInt(fields[1])
  92. case "Max processes":
  93. l.Processes, err = parseInt(fields[1])
  94. case "Max open files":
  95. l.OpenFiles, err = parseInt(fields[1])
  96. case "Max locked memory":
  97. l.LockedMemory, err = parseInt(fields[1])
  98. case "Max address space":
  99. l.AddressSpace, err = parseInt(fields[1])
  100. case "Max file locks":
  101. l.FileLocks, err = parseInt(fields[1])
  102. case "Max pending signals":
  103. l.PendingSignals, err = parseInt(fields[1])
  104. case "Max msgqueue size":
  105. l.MsqqueueSize, err = parseInt(fields[1])
  106. case "Max nice priority":
  107. l.NicePriority, err = parseInt(fields[1])
  108. case "Max realtime priority":
  109. l.RealtimePriority, err = parseInt(fields[1])
  110. case "Max realtime timeout":
  111. l.RealtimeTimeout, err = parseInt(fields[1])
  112. }
  113. if err != nil {
  114. return ProcLimits{}, err
  115. }
  116. }
  117. return l, s.Err()
  118. }
  119. func parseInt(s string) (int, error) {
  120. if s == limitsUnlimited {
  121. return -1, nil
  122. }
  123. i, err := strconv.ParseInt(s, 10, 32)
  124. if err != nil {
  125. return 0, fmt.Errorf("couldn't parse value %s: %s", s, err)
  126. }
  127. return int(i), nil
  128. }