github.com/walkingsparrow/docker@v1.4.2-0.20151218153551-b708a2249bfa/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 memoryReservation := cgroupEnabled(mountPoint, "memory.soft_limit_in_bytes") 53 if !quiet && !memoryReservation { 54 logrus.Warn("Your kernel does not support memory reservation.") 55 } 56 oomKillDisable := cgroupEnabled(mountPoint, "memory.oom_control") 57 if !quiet && !oomKillDisable { 58 logrus.Warnf("Your kernel does not support oom control.") 59 } 60 memorySwappiness := cgroupEnabled(mountPoint, "memory.swappiness") 61 if !quiet && !memorySwappiness { 62 logrus.Warnf("Your kernel does not support memory swappiness.") 63 } 64 kernelMemory := cgroupEnabled(mountPoint, "memory.kmem.limit_in_bytes") 65 if !quiet && !kernelMemory { 66 logrus.Warnf("Your kernel does not support kernel memory limit.") 67 } 68 69 return cgroupMemInfo{ 70 MemoryLimit: true, 71 SwapLimit: swapLimit, 72 MemoryReservation: memoryReservation, 73 OomKillDisable: oomKillDisable, 74 MemorySwappiness: memorySwappiness, 75 KernelMemory: kernelMemory, 76 } 77 } 78 79 // checkCgroupCPU reads the cpu information from the cpu cgroup mount point. 80 func checkCgroupCPU(quiet bool) cgroupCPUInfo { 81 mountPoint, err := cgroups.FindCgroupMountpoint("cpu") 82 if err != nil { 83 if !quiet { 84 logrus.Warn(err) 85 } 86 return cgroupCPUInfo{} 87 } 88 89 cpuShares := cgroupEnabled(mountPoint, "cpu.shares") 90 if !quiet && !cpuShares { 91 logrus.Warn("Your kernel does not support cgroup cpu shares") 92 } 93 94 cpuCfsPeriod := cgroupEnabled(mountPoint, "cpu.cfs_period_us") 95 if !quiet && !cpuCfsPeriod { 96 logrus.Warn("Your kernel does not support cgroup cfs period") 97 } 98 99 cpuCfsQuota := cgroupEnabled(mountPoint, "cpu.cfs_quota_us") 100 if !quiet && !cpuCfsQuota { 101 logrus.Warn("Your kernel does not support cgroup cfs quotas") 102 } 103 return cgroupCPUInfo{ 104 CPUShares: cpuShares, 105 CPUCfsPeriod: cpuCfsPeriod, 106 CPUCfsQuota: cpuCfsQuota, 107 } 108 } 109 110 // checkCgroupBlkioInfo reads the blkio information from the blkio cgroup mount point. 111 func checkCgroupBlkioInfo(quiet bool) cgroupBlkioInfo { 112 mountPoint, err := cgroups.FindCgroupMountpoint("blkio") 113 if err != nil { 114 if !quiet { 115 logrus.Warn(err) 116 } 117 return cgroupBlkioInfo{} 118 } 119 120 weight := cgroupEnabled(mountPoint, "blkio.weight") 121 if !quiet && !weight { 122 logrus.Warn("Your kernel does not support cgroup blkio weight") 123 } 124 125 weightDevice := cgroupEnabled(mountPoint, "blkio.weight_device") 126 if !quiet && !weightDevice { 127 logrus.Warn("Your kernel does not support cgroup blkio weight_device") 128 } 129 130 readBpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.read_bps_device") 131 if !quiet && !readBpsDevice { 132 logrus.Warn("Your kernel does not support cgroup blkio throttle.read_bps_device") 133 } 134 135 writeBpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.write_bps_device") 136 if !quiet && !writeBpsDevice { 137 logrus.Warn("Your kernel does not support cgroup blkio throttle.write_bps_device") 138 } 139 return cgroupBlkioInfo{ 140 BlkioWeight: weight, 141 BlkioWeightDevice: weightDevice, 142 BlkioReadBpsDevice: readBpsDevice, 143 BlkioWriteBpsDevice: writeBpsDevice, 144 } 145 } 146 147 // checkCgroupCpusetInfo reads the cpuset information from the cpuset cgroup mount point. 148 func checkCgroupCpusetInfo(quiet bool) cgroupCpusetInfo { 149 mountPoint, err := cgroups.FindCgroupMountpoint("cpuset") 150 if err != nil { 151 if !quiet { 152 logrus.Warn(err) 153 } 154 return cgroupCpusetInfo{} 155 } 156 157 cpus, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.cpus")) 158 if err != nil { 159 return cgroupCpusetInfo{} 160 } 161 162 mems, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.mems")) 163 if err != nil { 164 return cgroupCpusetInfo{} 165 } 166 167 return cgroupCpusetInfo{ 168 Cpuset: true, 169 Cpus: strings.TrimSpace(string(cpus)), 170 Mems: strings.TrimSpace(string(mems)), 171 } 172 } 173 174 func cgroupEnabled(mountPoint, name string) bool { 175 _, err := os.Stat(path.Join(mountPoint, name)) 176 return err == nil 177 } 178 179 func readProcBool(path string) bool { 180 val, err := ioutil.ReadFile(path) 181 if err != nil { 182 return false 183 } 184 return strings.TrimSpace(string(val)) == "1" 185 }