proc_cgroups.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Copyright 2021 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. "strconv"
  19. "strings"
  20. "github.com/prometheus/procfs/internal/util"
  21. )
  22. // CgroupSummary models one line from /proc/cgroups.
  23. // This file contains information about the controllers that are compiled into the kernel.
  24. //
  25. // Also see http://man7.org/linux/man-pages/man7/cgroups.7.html
  26. type CgroupSummary struct {
  27. // The name of the controller. controller is also known as subsystem.
  28. SubsysName string
  29. // The unique ID of the cgroup hierarchy on which this controller is mounted.
  30. Hierarchy int
  31. // The number of control groups in this hierarchy using this controller.
  32. Cgroups int
  33. // This field contains the value 1 if this controller is enabled, or 0 if it has been disabled
  34. Enabled int
  35. }
  36. // parseCgroupSummary parses each line of the /proc/cgroup file
  37. // Line format is `subsys_name hierarchy num_cgroups enabled`.
  38. func parseCgroupSummaryString(CgroupSummaryStr string) (*CgroupSummary, error) {
  39. var err error
  40. fields := strings.Fields(CgroupSummaryStr)
  41. // require at least 4 fields
  42. if len(fields) < 4 {
  43. return nil, fmt.Errorf("at least 4 fields required, found %d fields in cgroup info string: %s", len(fields), CgroupSummaryStr)
  44. }
  45. CgroupSummary := &CgroupSummary{
  46. SubsysName: fields[0],
  47. }
  48. CgroupSummary.Hierarchy, err = strconv.Atoi(fields[1])
  49. if err != nil {
  50. return nil, fmt.Errorf("failed to parse hierarchy ID")
  51. }
  52. CgroupSummary.Cgroups, err = strconv.Atoi(fields[2])
  53. if err != nil {
  54. return nil, fmt.Errorf("failed to parse Cgroup Num")
  55. }
  56. CgroupSummary.Enabled, err = strconv.Atoi(fields[3])
  57. if err != nil {
  58. return nil, fmt.Errorf("failed to parse Enabled")
  59. }
  60. return CgroupSummary, nil
  61. }
  62. // parseCgroupSummary reads each line of the /proc/cgroup file.
  63. func parseCgroupSummary(data []byte) ([]CgroupSummary, error) {
  64. var CgroupSummarys []CgroupSummary
  65. scanner := bufio.NewScanner(bytes.NewReader(data))
  66. for scanner.Scan() {
  67. CgroupSummaryString := scanner.Text()
  68. // ignore comment lines
  69. if strings.HasPrefix(CgroupSummaryString, "#") {
  70. continue
  71. }
  72. CgroupSummary, err := parseCgroupSummaryString(CgroupSummaryString)
  73. if err != nil {
  74. return nil, err
  75. }
  76. CgroupSummarys = append(CgroupSummarys, *CgroupSummary)
  77. }
  78. err := scanner.Err()
  79. return CgroupSummarys, err
  80. }
  81. // CgroupSummarys returns information about current /proc/cgroups.
  82. func (fs FS) CgroupSummarys() ([]CgroupSummary, error) {
  83. data, err := util.ReadFileNoStat(fs.proc.Path("cgroups"))
  84. if err != nil {
  85. return nil, err
  86. }
  87. return parseCgroupSummary(data)
  88. }