github.com/damirazo/docker@v1.9.0/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 w := cgroupEnabled(mountPoint, "blkio.weight") 121 if !quiet && !w { 122 logrus.Warn("Your kernel does not support cgroup blkio weight") 123 } 124 return cgroupBlkioInfo{BlkioWeight: w} 125 } 126 127 // checkCgroupCpusetInfo reads the cpuset information from the cpuset cgroup mount point. 128 func checkCgroupCpusetInfo(quiet bool) cgroupCpusetInfo { 129 mountPoint, err := cgroups.FindCgroupMountpoint("cpuset") 130 if err != nil { 131 if !quiet { 132 logrus.Warn(err) 133 } 134 return cgroupCpusetInfo{} 135 } 136 137 cpus, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.cpus")) 138 if err != nil { 139 return cgroupCpusetInfo{} 140 } 141 142 mems, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.mems")) 143 if err != nil { 144 return cgroupCpusetInfo{} 145 } 146 147 return cgroupCpusetInfo{ 148 Cpuset: true, 149 Cpus: strings.TrimSpace(string(cpus)), 150 Mems: strings.TrimSpace(string(mems)), 151 } 152 } 153 154 func cgroupEnabled(mountPoint, name string) bool { 155 _, err := os.Stat(path.Join(mountPoint, name)) 156 return err == nil 157 } 158 159 func readProcBool(path string) bool { 160 val, err := ioutil.ReadFile(path) 161 if err != nil { 162 return false 163 } 164 return strings.TrimSpace(string(val)) == "1" 165 }