fce532280b
This leaves only the generic cgroup helper functions in cgroups.go and will allow easy implementations of other cgroup managers. This also wires up the call to Cleanup the cgroup which was missing before. Docker-DCO-1.1-Signed-off-by: Alexander Larsson <alexl@redhat.com> (github: alexlarsson)
91 lines
2.2 KiB
Go
91 lines
2.2 KiB
Go
package cgroups
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"github.com/dotcloud/docker/pkg/mount"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
type Cgroup struct {
|
|
Name string `json:"name,omitempty"`
|
|
Parent string `json:"parent,omitempty"`
|
|
|
|
DeviceAccess bool `json:"device_access,omitempty"` // name of parent cgroup or slice
|
|
Memory int64 `json:"memory,omitempty"` // Memory limit (in bytes)
|
|
MemorySwap int64 `json:"memory_swap,omitempty"` // Total memory usage (memory + swap); set `-1' to disable swap
|
|
CpuShares int64 `json:"cpu_shares,omitempty"` // CPU shares (relative weight vs. other containers)
|
|
}
|
|
|
|
type ActiveCgroup interface {
|
|
Cleanup() error
|
|
}
|
|
|
|
// https://www.kernel.org/doc/Documentation/cgroups/cgroups.txt
|
|
func FindCgroupMountpoint(subsystem string) (string, error) {
|
|
mounts, err := mount.GetMounts()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
for _, mount := range mounts {
|
|
if mount.Fstype == "cgroup" {
|
|
for _, opt := range strings.Split(mount.VfsOpts, ",") {
|
|
if opt == subsystem {
|
|
return mount.Mountpoint, nil
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return "", fmt.Errorf("cgroup mountpoint not found for %s", subsystem)
|
|
}
|
|
|
|
// Returns the relative path to the cgroup docker is running in.
|
|
func GetThisCgroupDir(subsystem string) (string, error) {
|
|
f, err := os.Open("/proc/self/cgroup")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer f.Close()
|
|
|
|
return parseCgroupFile(subsystem, f)
|
|
}
|
|
|
|
func GetInitCgroupDir(subsystem string) (string, error) {
|
|
f, err := os.Open("/proc/1/cgroup")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
defer f.Close()
|
|
|
|
return parseCgroupFile(subsystem, f)
|
|
}
|
|
|
|
func parseCgroupFile(subsystem string, r io.Reader) (string, error) {
|
|
s := bufio.NewScanner(r)
|
|
for s.Scan() {
|
|
if err := s.Err(); err != nil {
|
|
return "", err
|
|
}
|
|
text := s.Text()
|
|
parts := strings.Split(text, ":")
|
|
for _, subs := range strings.Split(parts[1], ",") {
|
|
if subs == subsystem {
|
|
return parts[2], nil
|
|
}
|
|
}
|
|
}
|
|
return "", fmt.Errorf("cgroup '%s' not found in /proc/self/cgroup", subsystem)
|
|
}
|
|
|
|
func writeFile(dir, file, data string) error {
|
|
return ioutil.WriteFile(filepath.Join(dir, file), []byte(data), 0700)
|
|
}
|
|
|
|
func (c *Cgroup) Apply(pid int) (ActiveCgroup, error) {
|
|
return rawApply(c, pid)
|
|
}
|