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