proc_limits.go 4.4 KB

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