本站源代码
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.

133 lines
3.4KB

  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. "fmt"
  17. "io/ioutil"
  18. "os"
  19. "regexp"
  20. "strings"
  21. )
  22. // Regexp variables
  23. var (
  24. rPos = regexp.MustCompile(`^pos:\s+(\d+)$`)
  25. rFlags = regexp.MustCompile(`^flags:\s+(\d+)$`)
  26. rMntID = regexp.MustCompile(`^mnt_id:\s+(\d+)$`)
  27. rInotify = regexp.MustCompile(`^inotify`)
  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 (structed) 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. f, err := os.Open(p.path("fdinfo", fd))
  45. if err != nil {
  46. return nil, err
  47. }
  48. defer f.Close()
  49. fdinfo, err := ioutil.ReadAll(f)
  50. if err != nil {
  51. return nil, fmt.Errorf("could not read %s: %s", f.Name(), err)
  52. }
  53. var text, pos, flags, mntid string
  54. var inotify []InotifyInfo
  55. scanner := bufio.NewScanner(strings.NewReader(string(fdinfo)))
  56. for scanner.Scan() {
  57. text = scanner.Text()
  58. if rPos.MatchString(text) {
  59. pos = rPos.FindStringSubmatch(text)[1]
  60. } else if rFlags.MatchString(text) {
  61. flags = rFlags.FindStringSubmatch(text)[1]
  62. } else if rMntID.MatchString(text) {
  63. mntid = rMntID.FindStringSubmatch(text)[1]
  64. } else if rInotify.MatchString(text) {
  65. newInotify, err := parseInotifyInfo(text)
  66. if err != nil {
  67. return nil, err
  68. }
  69. inotify = append(inotify, *newInotify)
  70. }
  71. }
  72. i := &ProcFDInfo{
  73. FD: fd,
  74. Pos: pos,
  75. Flags: flags,
  76. MntID: mntid,
  77. InotifyInfos: inotify,
  78. }
  79. return i, nil
  80. }
  81. // InotifyInfo represents a single inotify line in the fdinfo file.
  82. type InotifyInfo struct {
  83. // Watch descriptor number
  84. WD string
  85. // Inode number
  86. Ino string
  87. // Device ID
  88. Sdev string
  89. // Mask of events being monitored
  90. Mask string
  91. }
  92. // InotifyInfo constructor. Only available on kernel 3.8+.
  93. func parseInotifyInfo(line string) (*InotifyInfo, error) {
  94. r := regexp.MustCompile(`^inotify\s+wd:([0-9a-f]+)\s+ino:([0-9a-f]+)\s+sdev:([0-9a-f]+)\s+mask:([0-9a-f]+)`)
  95. m := r.FindStringSubmatch(line)
  96. i := &InotifyInfo{
  97. WD: m[1],
  98. Ino: m[2],
  99. Sdev: m[3],
  100. Mask: m[4],
  101. }
  102. return i, nil
  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. }
上海开阖软件有限公司 沪ICP备12045867号-1