You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

157 lines
4.6 KiB

  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. //
  76. // Deprecated: use p.Limits() instead
  77. func (p Proc) NewLimits() (ProcLimits, error) {
  78. return p.Limits()
  79. }
  80. // Limits returns the current soft limits of the process.
  81. func (p Proc) Limits() (ProcLimits, error) {
  82. f, err := os.Open(p.path("limits"))
  83. if err != nil {
  84. return ProcLimits{}, err
  85. }
  86. defer f.Close()
  87. var (
  88. l = ProcLimits{}
  89. s = bufio.NewScanner(f)
  90. )
  91. for s.Scan() {
  92. fields := limitsDelimiter.Split(s.Text(), limitsFields)
  93. if len(fields) != limitsFields {
  94. return ProcLimits{}, fmt.Errorf(
  95. "couldn't parse %s line %s", f.Name(), s.Text())
  96. }
  97. switch fields[0] {
  98. case "Max cpu time":
  99. l.CPUTime, err = parseInt(fields[1])
  100. case "Max file size":
  101. l.FileSize, err = parseInt(fields[1])
  102. case "Max data size":
  103. l.DataSize, err = parseInt(fields[1])
  104. case "Max stack size":
  105. l.StackSize, err = parseInt(fields[1])
  106. case "Max core file size":
  107. l.CoreFileSize, err = parseInt(fields[1])
  108. case "Max resident set":
  109. l.ResidentSet, err = parseInt(fields[1])
  110. case "Max processes":
  111. l.Processes, err = parseInt(fields[1])
  112. case "Max open files":
  113. l.OpenFiles, err = parseInt(fields[1])
  114. case "Max locked memory":
  115. l.LockedMemory, err = parseInt(fields[1])
  116. case "Max address space":
  117. l.AddressSpace, err = parseInt(fields[1])
  118. case "Max file locks":
  119. l.FileLocks, err = parseInt(fields[1])
  120. case "Max pending signals":
  121. l.PendingSignals, err = parseInt(fields[1])
  122. case "Max msgqueue size":
  123. l.MsqqueueSize, err = parseInt(fields[1])
  124. case "Max nice priority":
  125. l.NicePriority, err = parseInt(fields[1])
  126. case "Max realtime priority":
  127. l.RealtimePriority, err = parseInt(fields[1])
  128. case "Max realtime timeout":
  129. l.RealtimeTimeout, err = parseInt(fields[1])
  130. }
  131. if err != nil {
  132. return ProcLimits{}, err
  133. }
  134. }
  135. return l, s.Err()
  136. }
  137. func parseInt(s string) (int64, error) {
  138. if s == limitsUnlimited {
  139. return -1, nil
  140. }
  141. i, err := strconv.ParseInt(s, 10, 64)
  142. if err != nil {
  143. return 0, fmt.Errorf("couldn't parse value %s: %s", s, err)
  144. }
  145. return i, nil
  146. }