From b3f3344cdfcf61d99dfd75a329d12ac781aec48d Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Wed, 12 Oct 2016 11:35:42 -0700 Subject: [PATCH] Add freeze state to output Signed-off-by: Michael Crosby --- control.go | 11 +++++++++++ freezer.go | 34 +++++++++++++++++----------------- v1.go | 17 +++++++++++++++++ 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/control.go b/control.go index a16478fb..2b103e33 100644 --- a/control.go +++ b/control.go @@ -89,6 +89,16 @@ type Hierarchy func() ([]Subsystem, error) type Path func(subsystem Name) string +type State string + +const ( + Unknown State = "" + Thawed State = "thawed" + Frozen State = "frozen" + Freezing State = "freezing" + Deleted State = "deleted" +) + // Cgroup handles interactions with the individual groups to perform // actions on them as them main interface to this cgroup package type Cgroup interface { @@ -100,4 +110,5 @@ type Cgroup interface { Freeze() error Thaw() error OOMEventFD() (uintptr, error) + State() State } diff --git a/freezer.go b/freezer.go index 5d941889..523a6549 100644 --- a/freezer.go +++ b/freezer.go @@ -7,13 +7,6 @@ import ( "time" ) -type freezerState string - -const ( - frozen freezerState = "FROZEN" - thawed freezerState = "THAWED" -) - func NewFreezer(root string) *FreezerController { return &FreezerController{ root: filepath.Join(root, string(Freezer)), @@ -33,35 +26,42 @@ func (f *FreezerController) Path(path string) string { } func (f *FreezerController) Freeze(path string) error { - if err := f.changeState(path, frozen); err != nil { + if err := f.changeState(path, Frozen); err != nil { return err } - return f.waitState(path, frozen) + return f.waitState(path, Frozen) } func (f *FreezerController) Thaw(path string) error { - if err := f.changeState(path, thawed); err != nil { + if err := f.changeState(path, Thawed); err != nil { return err } - return f.waitState(path, thawed) + return f.waitState(path, Thawed) } -func (f *FreezerController) changeState(path string, state freezerState) error { +func (f *FreezerController) changeState(path string, state State) error { return ioutil.WriteFile( filepath.Join(f.root, path, "freezer.state"), - []byte(state), + []byte(strings.ToUpper(string(state))), defaultFilePerm, ) } -func (f *FreezerController) waitState(path string, state freezerState) error { - file := filepath.Join(f.root, path, "freezer.state") +func (f *FreezerController) state(path string) (State, error) { + current, err := ioutil.ReadFile(filepath.Join(f.root, path, "freezer.state")) + if err != nil { + return "", err + } + return State(strings.ToLower(strings.TrimSpace(string(current)))), nil +} + +func (f *FreezerController) waitState(path string, state State) error { for { - current, err := ioutil.ReadFile(file) + current, err := f.state(path) if err != nil { return err } - if freezerState(strings.TrimSpace(string(current))) == state { + if current == state { return nil } time.Sleep(1 * time.Millisecond) diff --git a/v1.go b/v1.go index a4f1ab54..f305a9fd 100644 --- a/v1.go +++ b/v1.go @@ -242,6 +242,23 @@ func (c *v1) OOMEventFD() (uintptr, error) { return s.(*MemoryController).OOMEventFD(c.path(Memory)) } +func (c *v1) State() State { + c.mu.Lock() + defer c.mu.Unlock() + if c.err != nil && c.err == ErrCgroupDeleted { + return Deleted + } + s := c.getSubsystem(Freezer) + if s == nil { + return Thawed + } + state, err := s.(*FreezerController).state(c.path(Freezer)) + if err != nil { + return Unknown + } + return state +} + func (c *v1) getSubsystem(n Name) Subsystem { for _, s := range c.subsystems { if s.Name() == n {