Esempio n. 1
0
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
}
Esempio n. 2
0
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
}
Esempio n. 3
0
func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) {
	mountpoint, err := cgroups.FindCgroupMountpoint(subsystem)
	if err != nil {
		return "", err
	}

	initPath, err := cgroups.GetInitCgroupDir(subsystem)
	if err != nil {
		return "", err
	}
	// if pid 1 is systemd 226 or later, it will be in init.scope, not the root
	initPath = strings.TrimSuffix(filepath.Clean(initPath), "init.scope")

	slice := "system.slice"
	if c.Parent != "" {
		slice = c.Parent
	}

	slice, err = ExpandSlice(slice)
	if err != nil {
		return "", err
	}

	return filepath.Join(mountpoint, initPath, slice, getUnitName(c)), nil
}
Esempio n. 4
0
// checkCgroupBlkioInfo reads the blkio information from the blkio cgroup mount point.
func checkCgroupBlkioInfo(quiet bool) cgroupBlkioInfo {
	mountPoint, err := cgroups.FindCgroupMountpoint("blkio")
	if err != nil {
		if !quiet {
			logrus.Warn(err)
		}
		return cgroupBlkioInfo{}
	}

	weight := cgroupEnabled(mountPoint, "blkio.weight")
	if !quiet && !weight {
		logrus.Warn("Your kernel does not support cgroup blkio weight")
	}

	weightDevice := cgroupEnabled(mountPoint, "blkio.weight_device")
	if !quiet && !weightDevice {
		logrus.Warn("Your kernel does not support cgroup blkio weight_device")
	}

	readBpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.read_bps_device")
	if !quiet && !readBpsDevice {
		logrus.Warn("Your kernel does not support cgroup blkio throttle.read_bps_device")
	}

	writeBpsDevice := cgroupEnabled(mountPoint, "blkio.throttle.write_bps_device")
	if !quiet && !writeBpsDevice {
		logrus.Warn("Your kernel does not support cgroup blkio throttle.write_bps_device")
	}
	return cgroupBlkioInfo{
		BlkioWeight:         weight,
		BlkioWeightDevice:   weightDevice,
		BlkioReadBpsDevice:  readBpsDevice,
		BlkioWriteBpsDevice: writeBpsDevice,
	}
}
Esempio n. 5
0
// 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
	}

	// Check if Seccomp is supported, via CONFIG_SECCOMP.
	if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_GET_SECCOMP, 0, 0); err != syscall.EINVAL {
		// Make sure the kernel has CONFIG_SECCOMP_FILTER.
		if _, _, err := syscall.RawSyscall(syscall.SYS_PRCTL, syscall.PR_SET_SECCOMP, SeccompModeFilter, 0); err != syscall.EINVAL {
			sysInfo.Seccomp = true
		}
	}

	return sysInfo
}
Esempio n. 6
0
// checkCgroupMem reads the memory information from the memory cgroup mount point.
func checkCgroupMem(quiet bool) cgroupMemInfo {
	mountPoint, err := cgroups.FindCgroupMountpoint("memory")
	if err != nil {
		if !quiet {
			logrus.Warnf("Your kernel does not support cgroup memory limit: %v", err)
		}
		return cgroupMemInfo{}
	}

	swapLimit := cgroupEnabled(mountPoint, "memory.memsw.limit_in_bytes")
	if !quiet && !swapLimit {
		logrus.Warn("Your kernel does not support swap memory limit.")
	}
	oomKillDisable := cgroupEnabled(mountPoint, "memory.oom_control")
	if !quiet && !oomKillDisable {
		logrus.Warnf("Your kernel does not support oom control.")
	}
	memorySwappiness := cgroupEnabled(mountPoint, "memory.swappiness")
	if !quiet && !memorySwappiness {
		logrus.Warnf("Your kernel does not support memory swappiness.")
	}

	return cgroupMemInfo{
		MemoryLimit:      true,
		SwapLimit:        swapLimit,
		OomKillDisable:   oomKillDisable,
		MemorySwappiness: memorySwappiness,
	}
}
Esempio n. 7
0
// checkCgroupCpusetInfo reads the cpuset information from the cpuset cgroup mount point.
func checkCgroupCpusetInfo(quiet bool) cgroupCpusetInfo {
	mountPoint, err := cgroups.FindCgroupMountpoint("cpuset")
	if err != nil {
		if !quiet {
			logrus.Warn(err)
		}
		return cgroupCpusetInfo{}
	}

	cpus, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.cpus"))
	if err != nil {
		return cgroupCpusetInfo{}
	}

	mems, err := ioutil.ReadFile(path.Join(mountPoint, "cpuset.mems"))
	if err != nil {
		return cgroupCpusetInfo{}
	}

	return cgroupCpusetInfo{
		Cpuset: true,
		Cpus:   strings.TrimSpace(string(cpus)),
		Mems:   strings.TrimSpace(string(mems)),
	}
}
Esempio n. 8
0
// checkCgroupCPU reads the cpu information from the cpu cgroup mount point.
func checkCgroupCPU(quiet bool) cgroupCPUInfo {
	mountPoint, err := cgroups.FindCgroupMountpoint("cpu")
	if err != nil {
		if !quiet {
			logrus.Warn(err)
		}
		return cgroupCPUInfo{}
	}

	cpuShares := cgroupEnabled(mountPoint, "cpu.shares")
	if !quiet && !cpuShares {
		logrus.Warn("Your kernel does not support cgroup cpu shares")
	}

	cpuCfsPeriod := cgroupEnabled(mountPoint, "cpu.cfs_period_us")
	if !quiet && !cpuCfsPeriod {
		logrus.Warn("Your kernel does not support cgroup cfs period")
	}

	cpuCfsQuota := cgroupEnabled(mountPoint, "cpu.cfs_quota_us")
	if !quiet && !cpuCfsQuota {
		logrus.Warn("Your kernel does not support cgroup cfs quotas")
	}
	return cgroupCPUInfo{
		CPUShares:    cpuShares,
		CPUCfsPeriod: cpuCfsPeriod,
		CPUCfsQuota:  cpuCfsQuota,
	}
}
Esempio n. 9
0
func setupCGroups(partitions map[string]int64) error {
	subsystems, err := cgroups.GetAllSubsystems()
	if err != nil {
		return fmt.Errorf("error getting cgroup subsystems: %s", err)
	} else if len(subsystems) == 0 {
		return fmt.Errorf("failed to detect any cgroup subsystems")
	}

	for _, subsystem := range subsystems {
		if _, err := cgroups.FindCgroupMountpoint(subsystem); err == nil {
			// subsystem already mounted
			continue
		}
		path := filepath.Join(cgroupRoot, subsystem)
		if err := os.Mkdir(path, 0755); err != nil && !os.IsExist(err) {
			return fmt.Errorf("error creating %s cgroup directory: %s", subsystem, err)
		}
		if err := syscall.Mount("cgroup", path, "cgroup", 0, subsystem); err != nil {
			return fmt.Errorf("error mounting %s cgroup: %s", subsystem, err)
		}
	}

	for name, shares := range partitions {
		if err := createCGroupPartition(name, shares); err != nil {
			return err
		}
	}
	return nil
}
func getSubsystemPath(subsystem string, id string) (string, error) {
	var subsystemPath string
	systemSlice := "system.slice"
	// hack for finding proper mount point for shares
	// cpu shares are part of cpu group, but openlibcontainers does not support it
	if subsystem == "shares" {
		subsystem = "cpu"
	}
	groupPath, err := cgroups.FindCgroupMountpoint(subsystem)
	if err != nil {
		fmt.Fprintf(os.Stderr, "[WARNING] Could not find mount point for %v\n", subsystem)
		return "", err
	}
	if isHost(id) {
		if isRunningSystemd() {
			subsystemPath = filepath.Join(groupPath, systemSlice)
		} else {
			subsystemPath = groupPath
		}
		return subsystemPath, nil
	}

	if isFsCgroupParent(groupPath) {
		// default cgroupfs parent is used for container
		subsystemPath = filepath.Join(groupPath, "docker", id)
	} else {
		// cgroup is created under systemd.slice
		subsystemPath = filepath.Join(groupPath, systemSlice, "docker-"+id+".scope")
	}

	return subsystemPath, nil
}
Esempio n. 11
0
// checkCgroupCpusetInfo reads the cpuset information from the cpuset cgroup mount point.
func checkCgroupCpusetInfo(quiet bool) cgroupCpusetInfo {
	_, err := cgroups.FindCgroupMountpoint("cpuset")
	if err != nil {
		if !quiet {
			logrus.Warn(err)
		}
		return cgroupCpusetInfo{}
	}

	return cgroupCpusetInfo{Cpuset: true}
}
Esempio n. 12
0
func findCgroupRootAndDir(subsystem string) (string, string, error) {
	cgroupRoot, err := cgroups.FindCgroupMountpoint(subsystem)
	if err != nil {
		return "", "", err
	}

	cgroupDir, err := cgroups.GetThisCgroupDir(subsystem)
	if err != nil {
		return "", "", err
	}
	return cgroupRoot, cgroupDir, nil
}
Esempio n. 13
0
func createCgroupdir(dir string) error {
	for _, subsystem := range []string{"memory", "cpu", "cpuset", "blkio"} {
		subsystemDir, err := cgroups.FindCgroupMountpoint(subsystem)
		if err != nil {
			return err
		}
		if err := os.MkdirAll(filepath.Join(subsystemDir, dir), 0700); err != nil {
			return err
		}
	}
	return nil
}
Esempio n. 14
0
func (h *cgroupfsHelper) apply(subsystem, file, data string) error {
	subsystemDir, err := cgroups.FindCgroupMountpoint(subsystem)
	if err != nil {
		return err
	}
	if err := os.MkdirAll(filepath.Join(subsystemDir, h.cgroupDir), 0700); err != nil {
		return err
	}
	if err := writeFile(filepath.Join(subsystemDir, h.cgroupDir), file, data); err != nil {
		return err
	}
	return nil
}
Esempio n. 15
0
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
}
Esempio n. 16
0
// checkCgroupPids reads the pids information from the pids cgroup mount point.
func checkCgroupPids(quiet bool) cgroupPids {
	_, err := cgroups.FindCgroupMountpoint("pids")
	if err != nil {
		if !quiet {
			logrus.Warn(err)
		}
		return cgroupPids{}
	}

	return cgroupPids{
		PidsLimit: true,
	}
}
Esempio n. 17
0
func (d Dir) Lookup(ctx context.Context, name string) (fusefs.Node, error) {
	if name == "hello" {
		return File{}, nil
	} else if fileInfo, ok := fileMap[name]; ok {
		mountPoint, err := cgroups.FindCgroupMountpoint(fileInfo.subsysName)
		if err != nil {
			return nil, fuse.ENODATA
		}

		fileInfo.initFunc(filepath.Join(mountPoint, d.cgroupdir), fileInfo)
		return fileInfo.node, nil
	}
	return nil, fuse.ENOENT
}
Esempio n. 18
0
// checkCgroupBlkioInfo reads the blkio information from the blkio cgroup mount point.
func checkCgroupBlkioInfo(quiet bool) cgroupBlkioInfo {
	mountPoint, err := cgroups.FindCgroupMountpoint("blkio")
	if err != nil {
		if !quiet {
			logrus.Warn(err)
		}
		return cgroupBlkioInfo{}
	}

	w := cgroupEnabled(mountPoint, "blkio.weight")
	if !quiet && !w {
		logrus.Warn("Your kernel does not support cgroup blkio weight")
	}
	return cgroupBlkioInfo{BlkioWeight: w}
}
Esempio n. 19
0
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
}
Esempio n. 20
0
func validateCgroupMounts() (string, string) {
	const recommendedMount = "/sys/fs/cgroup"
	desc := fmt.Sprintf("\tAny cgroup mount point that is detectible and accessible is supported. %s is recommended as a standard location.\n", recommendedMount)
	mnt, err := cgroups.FindCgroupMountpoint("cpu")
	if err != nil {
		out := "Could not locate cgroup mount point.\n"
		out += desc
		return Unknown, out
	}
	mnt = path.Dir(mnt)
	if !utils.FileExists(mnt) {
		out := fmt.Sprintf("Cgroup mount directory %s inaccessible.\n", mnt)
		out += desc
		return Unsupported, out
	}
	mounts, err := ioutil.ReadDir(mnt)
	if err != nil {
		out := fmt.Sprintf("Could not read cgroup mount directory %s.\n", mnt)
		out += desc
		return Unsupported, out
	}
	mountNames := "\tCgroup mount directories: "
	for _, mount := range mounts {
		mountNames += mount.Name() + " "
	}
	mountNames += "\n"
	out := fmt.Sprintf("Cgroups are mounted at %s.\n", mnt)
	out += mountNames
	out += desc
	info, err := ioutil.ReadFile("/proc/mounts")
	if err != nil {
		out := fmt.Sprintf("Could not read /proc/mounts.\n")
		out += desc
		return Unsupported, out
	}
	out += "\tCgroup mounts:\n"
	for _, line := range strings.Split(string(info), "\n") {
		if strings.Contains(line, " cgroup ") {
			out += "\t" + line + "\n"
		}
	}
	if mnt == recommendedMount {
		return Recommended, out
	}
	return Supported, out
}
func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) {
	mountpoint, err := cgroups.FindCgroupMountpoint(subsystem)
	if err != nil {
		return "", err
	}

	initPath, err := cgroups.GetInitCgroupDir(subsystem)
	if err != nil {
		return "", err
	}

	slice := "system.slice"
	if c.Slice != "" {
		slice = c.Slice
	}

	return filepath.Join(mountpoint, initPath, slice, getUnitName(c)), nil
}
Esempio n. 22
0
func (raw *data) path(subsystem string) (string, error) {
	mnt, err := cgroups.FindCgroupMountpoint(subsystem)
	// If we didn't mount the subsystem, there is no point we make the path.
	if err != nil {
		return "", err
	}

	// If the cgroup name/path is absolute do not look relative to the cgroup of the init process.
	if filepath.IsAbs(raw.cgroup) {
		return filepath.Join(raw.root, subsystem, raw.cgroup), nil
	}

	parent, err := raw.parent(subsystem, mnt)
	if err != nil {
		return "", err
	}

	return filepath.Join(parent, raw.cgroup), nil
}
Esempio n. 23
0
// New returns a new SysInfo, using the filesystem to detect which features the kernel supports.
func New(quiet bool) *SysInfo {
	sysInfo := &SysInfo{}
	sysInfo.cgroupMemInfo = checkCgroupMem(quiet)
	sysInfo.cgroupCpuInfo = checkCgroupCpu(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
}
Esempio n. 24
0
func UseSystemd() bool {
	check.Do(func() {
		if *noSystemd {
			return
		}
		// Check for system.slice in systemd and cpu cgroup.
		for _, cgroupType := range []string{"name=systemd", "cpu"} {
			mnt, err := cgroups.FindCgroupMountpoint(cgroupType)
			if err == nil {
				// systemd presence does not mean systemd controls cgroups.
				// If system.slice cgroup exists, then systemd is taking control.
				// This breaks if user creates system.slice manually :)
				if utils.FileExists(path.Join(mnt, "system.slice")) {
					useSystemd = true
					break
				}
			}
		}
	})
	return useSystemd
}
Esempio n. 25
0
func newCgroupfsHelper(mountpoint, cgroupDir string) (*cgroupfsHelper, error) {
	var err error
	if mountpoint == "" {
		if mountpoint, err = ioutil.TempDir("", ""); err != nil {
			return nil, err
		}
	}
	memCgroupDir, err := cgroups.FindCgroupMountpoint("memory")
	if err != nil {
		return nil, err
	}
	if cgroupDir == "" {
		if cgroupDir, err = ioutil.TempDir(memCgroupDir, ""); err != nil {
			return nil, err
		}
		cgroupDir = strings.TrimPrefix(cgroupDir, memCgroupDir)
	}
	if err := createCgroupdir(cgroupDir); err != nil {
		return nil, err
	}
	return &cgroupfsHelper{mountpoint, cgroupDir}, nil
}
Esempio n. 26
0
func validateMemoryAccounting(available_cgroups map[string]int) string {
	ok, _ := areCgroupsPresent(available_cgroups, []string{"memory"})
	if !ok {
		return "\tHierarchical memory accounting status unknown: memory cgroup not enabled.\n"
	}
	mnt, err := cgroups.FindCgroupMountpoint("memory")
	if err != nil {
		return "\tHierarchical memory accounting status unknown: memory cgroup not mounted.\n"
	}
	hier, err := ioutil.ReadFile(path.Join(mnt, "memory.use_hierarchy"))
	if err != nil {
		return "\tHierarchical memory accounting status unknown: hierarchy interface unavailable.\n"
	}
	var enabled int
	n, err := fmt.Sscanf(string(hier), "%d", &enabled)
	if err != nil || n != 1 {
		return "\tHierarchical memory accounting status unknown: hierarchy interface unreadable.\n"
	}
	if enabled == 1 {
		return "\tHierarchical memory accounting enabled. Reported memory usage includes memory used by child containers.\n"
	}
	return "\tHierarchical memory accounting disabled. Memory usage does not include usage from child containers.\n"

}
Esempio n. 27
0
// +build !windows

package main

import (
	"io/ioutil"
	"path"

	"github.com/opencontainers/runc/libcontainer/cgroups"
)

var (
	cpuCfsPeriod = testRequirement{
		func() bool {
			cgroupCPUMountpoint, err := cgroups.FindCgroupMountpoint("cpu")
			if err != nil {
				return false
			}
			if _, err := ioutil.ReadFile(path.Join(cgroupCPUMountpoint, "cpu.cfs_period_us")); err != nil {
				return false
			}
			return true
		},
		"Test requires an environment that supports cgroup cfs period.",
	}
	cpuCfsQuota = testRequirement{
		func() bool {
			cgroupCPUMountpoint, err := cgroups.FindCgroupMountpoint("cpu")
			if err != nil {
				return false
			}
// FindCgroupMountpoint returns cgroup mountpoint of a given subsystem
func (dc *DockerClient) FindCgroupMountpoint(subsystem string) (string, error) {
	return cgroups.FindCgroupMountpoint(subsystem)
}