826c468f2c
sysinfo struct was initialized at daemon startup to make sure kernel configs such as device cgroup are present and error out if not. The struct was embedded in daemon struct making impossible to detect if some system config is changed at daemon runtime (i.e. someone umount the memory cgroup). This leads to container's starts failure if some config is changed at daemon runtime. This patch moves sysinfo out of daemon and initilize and check it when needed (daemon startup, containers creation, contaienrs startup for now). Signed-off-by: Antonio Murdaca <runcom@linux.com> (cherry picked from commit 472b6f66e03f9a85fe8d23098dac6f55a87456d8)
134 lines
3.6 KiB
Go
134 lines
3.6 KiB
Go
package sysinfo
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/Sirupsen/logrus"
|
|
"github.com/opencontainers/runc/libcontainer/cgroups"
|
|
)
|
|
|
|
// New returns a new SysInfo, using the filesystem to detect which features
|
|
// the kernel supports. If `quiet` is `false` warnings are printed in logs
|
|
// whenever an error occurs or misconfigurations are present.
|
|
func New(quiet bool) *SysInfo {
|
|
sysInfo := &SysInfo{}
|
|
sysInfo.cgroupMemInfo = checkCgroupMem(quiet)
|
|
sysInfo.cgroupCPUInfo = checkCgroupCPU(quiet)
|
|
sysInfo.cgroupBlkioInfo = checkCgroupBlkioInfo(quiet)
|
|
sysInfo.cgroupCpusetInfo = checkCgroupCpusetInfo(quiet)
|
|
|
|
_, err := cgroups.FindCgroupMountpoint("devices")
|
|
sysInfo.CgroupDevicesEnabled = err == nil
|
|
|
|
sysInfo.IPv4ForwardingDisabled = !readProcBool("/proc/sys/net/ipv4/ip_forward")
|
|
sysInfo.BridgeNfCallIptablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-iptables")
|
|
sysInfo.BridgeNfCallIP6tablesDisabled = !readProcBool("/proc/sys/net/bridge/bridge-nf-call-ip6tables")
|
|
|
|
// Check if AppArmor is supported.
|
|
if _, err := os.Stat("/sys/kernel/security/apparmor"); !os.IsNotExist(err) {
|
|
sysInfo.AppArmor = true
|
|
}
|
|
|
|
return sysInfo
|
|
}
|
|
|
|
func checkCgroupMem(quiet bool) *cgroupMemInfo {
|
|
info := &cgroupMemInfo{}
|
|
mountPoint, err := cgroups.FindCgroupMountpoint("memory")
|
|
if err != nil {
|
|
if !quiet {
|
|
logrus.Warnf("Your kernel does not support cgroup memory limit: %v", err)
|
|
}
|
|
return info
|
|
}
|
|
info.MemoryLimit = true
|
|
|
|
info.SwapLimit = cgroupEnabled(mountPoint, "memory.memsw.limit_in_bytes")
|
|
if !quiet && !info.SwapLimit {
|
|
logrus.Warn("Your kernel does not support swap memory limit.")
|
|
}
|
|
info.OomKillDisable = cgroupEnabled(mountPoint, "memory.oom_control")
|
|
if !quiet && !info.OomKillDisable {
|
|
logrus.Warnf("Your kernel does not support oom control.")
|
|
}
|
|
info.MemorySwappiness = cgroupEnabled(mountPoint, "memory.swappiness")
|
|
if !quiet && !info.MemorySwappiness {
|
|
logrus.Warnf("Your kernel does not support memory swappiness.")
|
|
}
|
|
|
|
return info
|
|
}
|
|
|
|
func checkCgroupCPU(quiet bool) *cgroupCPUInfo {
|
|
info := &cgroupCPUInfo{}
|
|
mountPoint, err := cgroups.FindCgroupMountpoint("cpu")
|
|
if err != nil {
|
|
if !quiet {
|
|
logrus.Warn(err)
|
|
}
|
|
return info
|
|
}
|
|
|
|
info.CPUShares = cgroupEnabled(mountPoint, "cpu.shares")
|
|
if !quiet && !info.CPUShares {
|
|
logrus.Warn("Your kernel does not support cgroup cpu shares")
|
|
}
|
|
|
|
info.CPUCfsPeriod = cgroupEnabled(mountPoint, "cpu.cfs_period_us")
|
|
if !quiet && !info.CPUCfsPeriod {
|
|
logrus.Warn("Your kernel does not support cgroup cfs period")
|
|
}
|
|
|
|
info.CPUCfsQuota = cgroupEnabled(mountPoint, "cpu.cfs_quota_us")
|
|
if !quiet && !info.CPUCfsQuota {
|
|
logrus.Warn("Your kernel does not support cgroup cfs quotas")
|
|
}
|
|
return info
|
|
}
|
|
|
|
func checkCgroupBlkioInfo(quiet bool) *cgroupBlkioInfo {
|
|
info := &cgroupBlkioInfo{}
|
|
mountPoint, err := cgroups.FindCgroupMountpoint("blkio")
|
|
if err != nil {
|
|
if !quiet {
|
|
logrus.Warn(err)
|
|
}
|
|
return info
|
|
}
|
|
|
|
info.BlkioWeight = cgroupEnabled(mountPoint, "blkio.weight")
|
|
if !quiet && !info.BlkioWeight {
|
|
logrus.Warn("Your kernel does not support cgroup blkio weight")
|
|
}
|
|
return info
|
|
}
|
|
|
|
func checkCgroupCpusetInfo(quiet bool) *cgroupCpusetInfo {
|
|
info := &cgroupCpusetInfo{}
|
|
_, err := cgroups.FindCgroupMountpoint("cpuset")
|
|
if err != nil {
|
|
if !quiet {
|
|
logrus.Warn(err)
|
|
}
|
|
return info
|
|
}
|
|
|
|
info.Cpuset = true
|
|
return info
|
|
}
|
|
|
|
func cgroupEnabled(mountPoint, name string) bool {
|
|
_, err := os.Stat(path.Join(mountPoint, name))
|
|
return err == nil
|
|
}
|
|
|
|
func readProcBool(path string) bool {
|
|
val, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return strings.TrimSpace(string(val)) == "1"
|
|
}
|