github.com/cloudfoundry-attic/garden-linux@v0.333.2-candidate/linux_container/cgroups_manager/container_cgroups_manager.go (about)

     1  package cgroups_manager
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"io/ioutil"
     7  	"os"
     8  	"path"
     9  	"strings"
    10  )
    11  
    12  type ContainerCgroupsManager struct {
    13  	cgroupsPath  string
    14  	containerID  string
    15  	cgroupReader CgroupReader
    16  }
    17  
    18  //go:generate counterfeiter -o fake_cgroup_reader/FakeCgroupReader.go . CgroupReader
    19  type CgroupReader interface {
    20  	CgroupNode(subsytem string) (string, error)
    21  }
    22  
    23  func New(cgroupsPath, containerID string, cgroupReader CgroupReader) *ContainerCgroupsManager {
    24  	return &ContainerCgroupsManager{cgroupsPath, containerID, cgroupReader}
    25  }
    26  
    27  func (m *ContainerCgroupsManager) Set(subsystem, name, value string) error {
    28  	cgroupPath, err := m.SubsystemPath(subsystem)
    29  	if err != nil {
    30  		return fmt.Errorf("cgroups_manager: set: %s", err)
    31  	}
    32  	return ioutil.WriteFile(path.Join(cgroupPath, name), []byte(value), 0644)
    33  }
    34  
    35  func (m *ContainerCgroupsManager) Get(subsystem, name string) (string, error) {
    36  	cgroupPath, err := m.SubsystemPath(subsystem)
    37  	if err != nil {
    38  		return "", fmt.Errorf("cgroups_manager: get: %s", err)
    39  	}
    40  	body, err := ioutil.ReadFile(path.Join(cgroupPath, name))
    41  	if err != nil {
    42  		return "", err
    43  	}
    44  
    45  	return strings.Trim(string(body), "\n"), nil
    46  }
    47  
    48  func (m *ContainerCgroupsManager) Setup(subsystems ...string) error {
    49  	for _, subsystem := range subsystems {
    50  		subsystemPath, err := m.SubsystemPath(subsystem)
    51  		if err != nil {
    52  			return err
    53  		}
    54  
    55  		if err := os.MkdirAll(subsystemPath, 0755); err != nil {
    56  			return err
    57  		}
    58  
    59  		if subsystem == "cpuset" {
    60  			for _, file := range []string{"cpuset.cpus", "cpuset.mems"} {
    61  				systemCgroup, err := os.Open(path.Join(m.cgroupsPath, subsystem, file))
    62  				if err != nil {
    63  					return fmt.Errorf("cgroups: initialize cpuset: %s", err)
    64  				}
    65  
    66  				defer systemCgroup.Close()
    67  				subsystemCgroup, err := os.OpenFile(path.Join(subsystemPath, file), os.O_RDWR|os.O_CREATE, 0600)
    68  				if err != nil {
    69  					return fmt.Errorf("cgroups: initialize cpuset: %s", err)
    70  				}
    71  
    72  				defer subsystemCgroup.Close()
    73  				if _, err := io.Copy(subsystemCgroup, systemCgroup); err != nil {
    74  					return err
    75  				}
    76  			}
    77  		}
    78  	}
    79  	return nil
    80  }
    81  
    82  func (m *ContainerCgroupsManager) Add(pid int, subsystems ...string) error {
    83  	for _, subsystem := range subsystems {
    84  		subsystemPath, err := m.SubsystemPath(subsystem)
    85  		if err != nil {
    86  			return err
    87  		}
    88  
    89  		tasks, err := os.OpenFile(path.Join(subsystemPath, "tasks"), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
    90  		if err != nil {
    91  			return err
    92  		}
    93  		defer tasks.Close()
    94  
    95  		if _, err := fmt.Fprintf(tasks, "%d\n", pid); err != nil {
    96  			return err
    97  		}
    98  	}
    99  	return nil
   100  }
   101  
   102  func (m *ContainerCgroupsManager) SubsystemPath(subsystem string) (string, error) {
   103  	cgroupNode, err := m.cgroupReader.CgroupNode(subsystem)
   104  	if err != nil {
   105  		return "", err
   106  	}
   107  	return path.Join(m.cgroupsPath, subsystem, cgroupNode, "instance-"+m.containerID), nil
   108  }