Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

133 рядки
3.4 KiB

  1. // Copyright 2019 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. "bytes"
  17. "fmt"
  18. "regexp"
  19. "github.com/prometheus/procfs/internal/util"
  20. )
  21. var (
  22. rPos = regexp.MustCompile(`^pos:\s+(\d+)$`)
  23. rFlags = regexp.MustCompile(`^flags:\s+(\d+)$`)
  24. rMntID = regexp.MustCompile(`^mnt_id:\s+(\d+)$`)
  25. rInotify = regexp.MustCompile(`^inotify`)
  26. rInotifyParts = regexp.MustCompile(`^inotify\s+wd:([0-9a-f]+)\s+ino:([0-9a-f]+)\s+sdev:([0-9a-f]+)(?:\s+mask:([0-9a-f]+))?`)
  27. )
  28. // ProcFDInfo contains represents file descriptor information.
  29. type ProcFDInfo struct {
  30. // File descriptor
  31. FD string
  32. // File offset
  33. Pos string
  34. // File access mode and status flags
  35. Flags string
  36. // Mount point ID
  37. MntID string
  38. // List of inotify lines (structured) in the fdinfo file (kernel 3.8+ only)
  39. InotifyInfos []InotifyInfo
  40. }
  41. // FDInfo constructor. On kernels older than 3.8, InotifyInfos will always be empty.
  42. func (p Proc) FDInfo(fd string) (*ProcFDInfo, error) {
  43. data, err := util.ReadFileNoStat(p.path("fdinfo", fd))
  44. if err != nil {
  45. return nil, err
  46. }
  47. var text, pos, flags, mntid string
  48. var inotify []InotifyInfo
  49. scanner := bufio.NewScanner(bytes.NewReader(data))
  50. for scanner.Scan() {
  51. text = scanner.Text()
  52. if rPos.MatchString(text) {
  53. pos = rPos.FindStringSubmatch(text)[1]
  54. } else if rFlags.MatchString(text) {
  55. flags = rFlags.FindStringSubmatch(text)[1]
  56. } else if rMntID.MatchString(text) {
  57. mntid = rMntID.FindStringSubmatch(text)[1]
  58. } else if rInotify.MatchString(text) {
  59. newInotify, err := parseInotifyInfo(text)
  60. if err != nil {
  61. return nil, err
  62. }
  63. inotify = append(inotify, *newInotify)
  64. }
  65. }
  66. i := &ProcFDInfo{
  67. FD: fd,
  68. Pos: pos,
  69. Flags: flags,
  70. MntID: mntid,
  71. InotifyInfos: inotify,
  72. }
  73. return i, nil
  74. }
  75. // InotifyInfo represents a single inotify line in the fdinfo file.
  76. type InotifyInfo struct {
  77. // Watch descriptor number
  78. WD string
  79. // Inode number
  80. Ino string
  81. // Device ID
  82. Sdev string
  83. // Mask of events being monitored
  84. Mask string
  85. }
  86. // InotifyInfo constructor. Only available on kernel 3.8+.
  87. func parseInotifyInfo(line string) (*InotifyInfo, error) {
  88. m := rInotifyParts.FindStringSubmatch(line)
  89. if len(m) >= 4 {
  90. var mask string
  91. if len(m) == 5 {
  92. mask = m[4]
  93. }
  94. i := &InotifyInfo{
  95. WD: m[1],
  96. Ino: m[2],
  97. Sdev: m[3],
  98. Mask: mask,
  99. }
  100. return i, nil
  101. }
  102. return nil, fmt.Errorf("invalid inode entry: %q", line)
  103. }
  104. // ProcFDInfos represents a list of ProcFDInfo structs.
  105. type ProcFDInfos []ProcFDInfo
  106. func (p ProcFDInfos) Len() int { return len(p) }
  107. func (p ProcFDInfos) Swap(i, j int) { p[i], p[j] = p[j], p[i] }
  108. func (p ProcFDInfos) Less(i, j int) bool { return p[i].FD < p[j].FD }
  109. // InotifyWatchLen returns the total number of inotify watches.
  110. func (p ProcFDInfos) InotifyWatchLen() (int, error) {
  111. length := 0
  112. for _, f := range p {
  113. length += len(f.InotifyInfos)
  114. }
  115. return length, nil
  116. }