Skip to content

Commit

Permalink
Refactor into Cgroups Subsystems and Controllers
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Crosby <[email protected]>
  • Loading branch information
crosbymichael committed Oct 11, 2016
1 parent 70fca20 commit 74c68af
Show file tree
Hide file tree
Showing 20 changed files with 374 additions and 214 deletions.
20 changes: 10 additions & 10 deletions blkio.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@ import (
specs "github.com/opencontainers/runtime-spec/specs-go"
)

func NewBlkio(root string) *Blkio {
return &Blkio{
root: filepath.Join(root, "blkio"),
func NewBlkio(root string) *BlkioController {
return &BlkioController{
root: filepath.Join(root, string(Blkio)),
}
}

type Blkio struct {
type BlkioController struct {
root string
}

func (b *Blkio) Path(path string) string {
func (b *BlkioController) Path(path string) string {
return filepath.Join(b.root, path)
}

func (b *Blkio) Create(path string, resources *specs.Resources) error {
func (b *BlkioController) Create(path string, resources *specs.Resources) error {
if err := os.MkdirAll(b.Path(path), defaultDirPerm); err != nil {
return err
}
Expand All @@ -38,7 +38,7 @@ func (b *Blkio) Create(path string, resources *specs.Resources) error {
if err := ioutil.WriteFile(
filepath.Join(b.Path(path), fmt.Sprintf("blkio.%s", t.name)),
t.format(t.value),
0,
defaultFilePerm,
); err != nil {
return err
}
Expand All @@ -47,11 +47,11 @@ func (b *Blkio) Create(path string, resources *specs.Resources) error {
return nil
}

func (b *Blkio) Update(path string, resources *specs.Resources) error {
func (b *BlkioController) Update(path string, resources *specs.Resources) error {
return b.Create(path, resources)
}

func (b *Blkio) Stat(path string, stats *Stats) error {
func (b *BlkioController) Stat(path string, stats *Stats) error {
stats.Blkio = &BlkioStat{}
settings := []blkioStatSettings{
{
Expand Down Expand Up @@ -108,7 +108,7 @@ func (b *Blkio) Stat(path string, stats *Stats) error {
return nil
}

func (b *Blkio) readEntry(path, name string, entry []BlkioEntry) error {
func (b *BlkioController) readEntry(path, name string, entry []BlkioEntry) error {
f, err := os.Open(filepath.Join(b.Path(path), fmt.Sprintf("blkio.%s", name)))
if err != nil {
return err
Expand Down
55 changes: 34 additions & 21 deletions cgroup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,50 @@ import (
"path/filepath"
)

func newMock() (*mockHiearchy, error) {
dir, err := ioutil.TempDir("", "cgroups")
func init() {
defaultFilePerm = 0666
}

func newMock() (*mockCgroup, error) {
root, err := ioutil.TempDir("", "cgroups")
if err != nil {
return nil, err
}
for _, name := range []string{
"cpu",
"cpuset",
"cpuacct",
"pids",
"memory",
"net_cls",
"net_prio",
"hugetlb",
"freezer",
"blkio",
"perf_event",
} {
if err := os.MkdirAll(filepath.Join(dir, name), 0600); err != nil {
subsystems := make(map[Name]Subsystem)
for _, n := range Subsystems() {
name := string(n)
if err := os.MkdirAll(filepath.Join(root, name), defaultDirPerm); err != nil {
return nil, err
}
subsystems[n] = &mockSubsystem{
root: root,
name: n,
}
}
return &mockHiearchy{
root: dir,
return &mockCgroup{
root: root,
subsystems: subsystems,
}, nil
}

type mockHiearchy struct {
root string
type mockCgroup struct {
root string
subsystems map[Name]Subsystem
}

func (m *mockHiearchy) remove() error {
func (m *mockCgroup) delete() error {
return os.RemoveAll(m.root)
}

func (m *mockCgroup) hierarchy() (map[Name]Subsystem, error) {
return m.subsystems, nil
}

type mockSubsystem struct {
root string
name Name
}

func (m *mockSubsystem) Path(path string) string {
return filepath.Join(m.root, string(m.name), path)
}
65 changes: 55 additions & 10 deletions control.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,61 @@
package cgroups

import specs "github.com/opencontainers/runtime-spec/specs-go"
import (
"os"

specs "github.com/opencontainers/runtime-spec/specs-go"
)

type Name string

const (
Devices Name = "devices"
Hugetlb Name = "hugetlb"
Freezer Name = "freezer"
Pids Name = "pids"
NetCLS Name = "net_cls"
NetPrio Name = "net_prio"
PerfEvent Name = "perf_event"
Cpuset Name = "cpuset"
Cpu Name = "cpu"
Cpuacct Name = "cpuacct"
Memory Name = "memory"
Blkio Name = "blkio"
)

// Subsystems returns a complete list of the default cgroups
// avaliable on most linux systems
func Subsystems() []Name {
return []Name{
Devices,
Hugetlb,
Freezer,
Pids,
NetCLS,
NetPrio,
PerfEvent,
Cpuset,
Cpu,
Cpuacct,
Memory,
Blkio,
}
}

const (
defaultGroup = "devices"
freezerName = "freezer"
memoryName = "memory"
cgroupProcs = "cgroup.procs"
defaultDirPerm = 0600
defaultGroup = Devices
defaultDirPerm = 0755
)

type Group interface {
// defaultFilePerm is a var so that the test framework can change the filemode
// of all files created when the tests are running. The difference between the
// tests and real world use is that files like "cgroup.procs" will exist when writing
// to a read cgroup filesystem and do not exist prior when running in the tests.
// this is set to a non 0 value in the test code
var defaultFilePerm = os.FileMode(0)

type Subsystem interface {
Path(path string) string
}

Expand All @@ -27,13 +72,13 @@ type Updater interface {
}

// Hierarchy enableds both unified and split hierarchy for cgroups
type Hierarchy func() (map[string]Group, error)
type Hierarchy func() (map[Name]Subsystem, error)

type Path func(subsystem string) string
type Path func(subsystem Name) string

// Control handles interactions with the individual groups to perform
// Cgroup handles interactions with the individual groups to perform
// actions on them as them main interface to this cgroup package
type Control interface {
type Cgroup interface {
Add(pid int) error
Delete() error
Stat(ignoreNotExist bool) (*Stats, error)
Expand Down
18 changes: 9 additions & 9 deletions cpu.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ import (
specs "github.com/opencontainers/runtime-spec/specs-go"
)

func NewCpu(root string) *Cpu {
return &Cpu{
root: filepath.Join(root, "cpu"),
func NewCpu(root string) *CpuController {
return &CpuController{
root: filepath.Join(root, string(Cpu)),
}
}

type Cpu struct {
type CpuController struct {
root string
}

func (c *Cpu) Path(path string) string {
func (c *CpuController) Path(path string) string {
return filepath.Join(c.root, path)
}

func (c *Cpu) Create(path string, resources *specs.Resources) error {
func (c *CpuController) Create(path string, resources *specs.Resources) error {
if err := os.MkdirAll(c.Path(path), defaultDirPerm); err != nil {
return err
}
Expand Down Expand Up @@ -59,7 +59,7 @@ func (c *Cpu) Create(path string, resources *specs.Resources) error {
if err := ioutil.WriteFile(
filepath.Join(c.Path(path), fmt.Sprintf("cpu.%s", t.name)),
[]byte(strconv.FormatUint(*t.value, 10)),
0,
defaultFilePerm,
); err != nil {
return err
}
Expand All @@ -70,11 +70,11 @@ func (c *Cpu) Create(path string, resources *specs.Resources) error {
return nil
}

func (c *Cpu) Update(path string, resources *specs.Resources) error {
func (c *CpuController) Update(path string, resources *specs.Resources) error {
return c.Create(path, resources)
}

func (c *Cpu) Stat(path string, stats *Stats) error {
func (c *CpuController) Stat(path string, stats *Stats) error {
f, err := os.Open(filepath.Join(c.Path(path), "cpu.stat"))
if err != nil {
return err
Expand Down
16 changes: 8 additions & 8 deletions cpuacct.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@ const nanosecondsInSecond = 1000000000

var clockTicks = uint64(system.GetClockTicks())

func NewCpuacct(root string) *Cpuacct {
return &Cpuacct{
root: filepath.Join(root, "cpuacct"),
func NewCpuacct(root string) *CpuacctController {
return &CpuacctController{
root: filepath.Join(root, string(Cpuacct)),
}
}

type Cpuacct struct {
type CpuacctController struct {
root string
}

func (c *Cpuacct) Path(path string) string {
func (c *CpuacctController) Path(path string) string {
return filepath.Join(c.root, path)
}

func (c *Cpuacct) Stat(path string, stats *Stats) error {
func (c *CpuacctController) Stat(path string, stats *Stats) error {
user, kernel, err := c.getUsage(path)
if err != nil {
return err
Expand All @@ -55,7 +55,7 @@ func (c *Cpuacct) Stat(path string, stats *Stats) error {
return nil
}

func (c *Cpuacct) percpuUsage(path string) ([]uint64, error) {
func (c *CpuacctController) percpuUsage(path string) ([]uint64, error) {
var usage []uint64
data, err := ioutil.ReadFile(filepath.Join(c.Path(path), "cpuacct.usage_percpu"))
if err != nil {
Expand All @@ -71,7 +71,7 @@ func (c *Cpuacct) percpuUsage(path string) ([]uint64, error) {
return usage, nil
}

func (c *Cpuacct) getUsage(path string) (user uint64, kernel uint64, err error) {
func (c *CpuacctController) getUsage(path string) (user uint64, kernel uint64, err error) {
statPath := filepath.Join(c.Path(path), "cpuacct.stat")
data, err := ioutil.ReadFile(statPath)
if err != nil {
Expand Down
24 changes: 12 additions & 12 deletions cpuset.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ import (
specs "github.com/opencontainers/runtime-spec/specs-go"
)

func NewCputset(root string) *Cpuset {
return &Cpuset{
root: filepath.Join(root, "cpuset"),
func NewCputset(root string) *CpusetController {
return &CpusetController{
root: filepath.Join(root, string(Cpuset)),
}
}

type Cpuset struct {
type CpusetController struct {
root string
}

func (c *Cpuset) Path(path string) string {
func (c *CpusetController) Path(path string) string {
return filepath.Join(c.root, path)
}

func (c *Cpuset) Create(path string, resources *specs.Resources) error {
func (c *CpusetController) Create(path string, resources *specs.Resources) error {
if err := c.ensureParent(c.Path(path), c.root); err != nil {
return err
}
Expand Down Expand Up @@ -53,7 +53,7 @@ func (c *Cpuset) Create(path string, resources *specs.Resources) error {
if err := ioutil.WriteFile(
filepath.Join(c.Path(path), fmt.Sprintf("cpuset.%s", t.name)),
[]byte(*t.value),
0,
defaultFilePerm,
); err != nil {
return err
}
Expand All @@ -63,7 +63,7 @@ func (c *Cpuset) Create(path string, resources *specs.Resources) error {
return nil
}

func (c *Cpuset) getValues(path string) (cpus []byte, mems []byte, err error) {
func (c *CpusetController) getValues(path string) (cpus []byte, mems []byte, err error) {
if cpus, err = ioutil.ReadFile(filepath.Join(path, "cpuset.cpus")); err != nil {
return
}
Expand All @@ -76,7 +76,7 @@ func (c *Cpuset) getValues(path string) (cpus []byte, mems []byte, err error) {
// ensureParent makes sure that the parent directory of current is created
// and populated with the proper cpus and mems files copied from
// it's parent.
func (c *Cpuset) ensureParent(current, root string) error {
func (c *CpusetController) ensureParent(current, root string) error {
parent := filepath.Dir(current)
if _, err := filepath.Rel(root, parent); err != nil {
return nil
Expand All @@ -99,7 +99,7 @@ func (c *Cpuset) ensureParent(current, root string) error {

// copyIfNeeded copies the cpuset.cpus and cpuset.mems from the parent
// directory to the current directory if the file's contents are 0
func (c *Cpuset) copyIfNeeded(current, parent string) error {
func (c *CpusetController) copyIfNeeded(current, parent string) error {
var (
err error
currentCpus, currentMems []byte
Expand All @@ -115,7 +115,7 @@ func (c *Cpuset) copyIfNeeded(current, parent string) error {
if err := ioutil.WriteFile(
filepath.Join(current, "cpuset.cpus"),
parentCpus,
0,
defaultFilePerm,
); err != nil {
return err
}
Expand All @@ -124,7 +124,7 @@ func (c *Cpuset) copyIfNeeded(current, parent string) error {
if err := ioutil.WriteFile(
filepath.Join(current, "cpuset.mems"),
parentMems,
0,
defaultFilePerm,
); err != nil {
return err
}
Expand Down
Loading

0 comments on commit 74c68af

Please sign in to comment.