123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- package cgroups
- import (
- "bufio"
- "errors"
- "github.com/dotcloud/docker/pkg/mount"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
- )
- var (
- ErrNotFound = errors.New("mountpoint not found")
- )
- 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)
- CpusetCpus string `json:"cpuset_cpus,omitempty"` // CPU to use
- UnitProperties [][2]string `json:"unit_properties,omitempty"` // systemd unit properties
- }
- 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 "", ErrNotFound
- }
- // 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 "", ErrNotFound
- }
- 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) {
- // We have two implementation of cgroups support, one is based on
- // systemd and the dbus api, and one is based on raw cgroup fs operations
- // following the pre-single-writer model docs at:
- // http://www.freedesktop.org/wiki/Software/systemd/PaxControlGroups/
- if useSystemd() {
- return systemdApply(c, pid)
- } else {
- return rawApply(c, pid)
- }
- }
|