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  }