No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 

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