sysinfo_linux.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. package sysinfo
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "path"
  6. "strings"
  7. "github.com/Sirupsen/logrus"
  8. "github.com/opencontainers/runc/libcontainer/cgroups"
  9. )
  10. // New returns a new SysInfo, using the filesystem to detect which features
  11. // the kernel supports. If `quiet` is `false` warnings are printed in logs
  12. // whenever an error occurs or misconfigurations are present.
  13. func New(quiet bool) *SysInfo {
  14. sysInfo := &SysInfo{}
  15. sysInfo.cgroupMemInfo = checkCgroupMem(quiet)
  16. sysInfo.cgroupCPUInfo = checkCgroupCPU(quiet)
  17. sysInfo.cgroupBlkioInfo = checkCgroupBlkioInfo(quiet)
  18. sysInfo.cgroupCpusetInfo = checkCgroupCpusetInfo(quiet)
  19. _, err := cgroups.FindCgroupMountpoint("devices")
  20. sysInfo.CgroupDevicesEnabled = err == nil
  21. sysInfo.IPv4ForwardingDisabled = !readProcBool("/proc/sys/net/ipv4/ip_forward")
  22. sysInfo.BridgeNfCallIptablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-iptables")
  23. sysInfo.BridgeNfCallIP6tablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-ip6tables")
  24. // Check if AppArmor is supported.
  25. if _, err := os.Stat("/sys/kernel/security/apparmor"); !os.IsNotExist(err) {
  26. sysInfo.AppArmor = true
  27. }
  28. return sysInfo
  29. }
  30. // checkCgroupMem reads the memory information from the memory cgroup mount point.
  31. func checkCgroupMem(quiet bool) cgroupMemInfo {
  32. mountPoint, err := cgroups.FindCgroupMountpoint("memory")
  33. if err != nil {
  34. if !quiet {
  35. logrus.Warnf("Your kernel does not support cgroup memory limit: %v", err)
  36. }
  37. return cgroupMemInfo{}
  38. }
  39. swapLimit := cgroupEnabled(mountPoint, "memory.memsw.limit_in_bytes")
  40. if !quiet && !swapLimit {
  41. logrus.Warn("Your kernel does not support swap memory limit.")
  42. }
  43. oomKillDisable := cgroupEnabled(mountPoint, "memory.oom_control")
  44. if !quiet && !oomKillDisable {
  45. logrus.Warnf("Your kernel does not support oom control.")
  46. }
  47. memorySwappiness := cgroupEnabled(mountPoint, "memory.swappiness")
  48. if !quiet && !memorySwappiness {
  49. logrus.Warnf("Your kernel does not support memory swappiness.")
  50. }
  51. return cgroupMemInfo{
  52. MemoryLimit: true,
  53. SwapLimit: swapLimit,
  54. OomKillDisable: oomKillDisable,
  55. MemorySwappiness: memorySwappiness,
  56. }
  57. }
  58. // checkCgroupCPU reads the cpu information from the cpu cgroup mount point.
  59. func checkCgroupCPU(quiet bool) cgroupCPUInfo {
  60. mountPoint, err := cgroups.FindCgroupMountpoint("cpu")
  61. if err != nil {
  62. if !quiet {
  63. logrus.Warn(err)
  64. }
  65. return cgroupCPUInfo{}
  66. }
  67. cpuShares := cgroupEnabled(mountPoint, "cpu.shares")
  68. if !quiet && !cpuShares {
  69. logrus.Warn("Your kernel does not support cgroup cpu shares")
  70. }
  71. cpuCfsPeriod := cgroupEnabled(mountPoint, "cpu.cfs_period_us")
  72. if !quiet && !cpuCfsPeriod {
  73. logrus.Warn("Your kernel does not support cgroup cfs period")
  74. }
  75. cpuCfsQuota := cgroupEnabled(mountPoint, "cpu.cfs_quota_us")
  76. if !quiet && !cpuCfsQuota {
  77. logrus.Warn("Your kernel does not support cgroup cfs quotas")
  78. }
  79. return cgroupCPUInfo{
  80. CPUShares: cpuShares,
  81. CPUCfsPeriod: cpuCfsPeriod,
  82. CPUCfsQuota: cpuCfsQuota,
  83. }
  84. }
  85. // checkCgroupBlkioInfo reads the blkio information from the blkio cgroup mount point.
  86. func checkCgroupBlkioInfo(quiet bool) cgroupBlkioInfo {
  87. mountPoint, err := cgroups.FindCgroupMountpoint("blkio")
  88. if err != nil {
  89. if !quiet {
  90. logrus.Warn(err)
  91. }
  92. return cgroupBlkioInfo{}
  93. }
  94. w := cgroupEnabled(mountPoint, "blkio.weight")
  95. if !quiet && !w {
  96. logrus.Warn("Your kernel does not support cgroup blkio weight")
  97. }
  98. return cgroupBlkioInfo{BlkioWeight: w}
  99. }
  100. // checkCgroupCpusetInfo reads the cpuset information from the cpuset cgroup mount point.
  101. func checkCgroupCpusetInfo(quiet bool) cgroupCpusetInfo {
  102. _, err := cgroups.FindCgroupMountpoint("cpuset")
  103. if err != nil {
  104. if !quiet {
  105. logrus.Warn(err)
  106. }
  107. return cgroupCpusetInfo{}
  108. }
  109. return cgroupCpusetInfo{Cpuset: true}
  110. }
  111. func cgroupEnabled(mountPoint, name string) bool {
  112. _, err := os.Stat(path.Join(mountPoint, name))
  113. return err == nil
  114. }
  115. func readProcBool(path string) bool {
  116. val, err := ioutil.ReadFile(path)
  117. if err != nil {
  118. return false
  119. }
  120. return strings.TrimSpace(string(val)) == "1"
  121. }