Merge pull request #339 from avagin/api-freezer

new-api: implement Pause() and Resume()
This commit is contained in:
Mrunal Patel 2015-01-19 15:17:45 -08:00
commit c70b6812b5
4 changed files with 94 additions and 10 deletions

View File

@ -143,14 +143,16 @@ func (m *Manager) Freeze(state cgroups.FreezerState) error {
return err
}
prevState := m.Cgroups.Freezer
m.Cgroups.Freezer = state
freezer := subsystems["freezer"]
err = freezer.Set(d)
if err != nil {
m.Cgroups.Freezer = prevState
return err
}
m.Cgroups.Freezer = state
return nil
}

View File

@ -204,6 +204,9 @@ func newTestRoot() (string, error) {
}
func TestEnter(t *testing.T) {
if testing.Short() {
return
}
root, err := newTestRoot()
if err != nil {
t.Fatal(err)
@ -300,3 +303,77 @@ func TestEnter(t *testing.T) {
t.Fatal("The second process isn't in the required pid namespace", pidns, pidns2)
}
}
func TestFreeze(t *testing.T) {
if testing.Short() {
return
}
root, err := newTestRoot()
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(root)
rootfs, err := newRootFs()
if err != nil {
t.Fatal(err)
}
defer remove(rootfs)
config := newTemplateConfig(rootfs)
factory, err := libcontainer.New(root, []string{os.Args[0], "init", "--"})
if err != nil {
t.Fatal(err)
}
container, err := factory.Create("test", config)
if err != nil {
t.Fatal(err)
}
defer container.Destroy()
stdinR, stdinW, err := os.Pipe()
if err != nil {
t.Fatal(err)
}
pconfig := libcontainer.ProcessConfig{
Args: []string{"cat"},
Stdin: stdinR,
}
pid, err := container.StartProcess(&pconfig)
stdinR.Close()
defer stdinW.Close()
if err != nil {
t.Fatal(err)
}
process, err := os.FindProcess(pid)
if err != nil {
t.Fatal(err)
}
if err := container.Pause(); err != nil {
t.Fatal(err)
}
state, err := container.RunState()
if err != nil {
t.Fatal(err)
}
if state != configs.Paused {
t.Fatal("Unexpected state: ", state)
}
if err := container.Resume(); err != nil {
t.Fatal(err)
}
stdinW.Close()
s, err := process.Wait()
if err != nil {
t.Fatal(err)
}
if !s.Success() {
t.Fatal(s.String())
}
}

View File

@ -48,6 +48,11 @@ func (c *linuxContainer) RunState() (configs.RunState, error) {
return 0, err
}
if c.config.Cgroups != nil &&
c.config.Cgroups.Freezer == cgroups.Frozen {
return configs.Paused, nil
}
//FIXME get a cgroup state to check other states
return configs.Running, nil
@ -163,13 +168,11 @@ func (c *linuxContainer) Destroy() error {
}
func (c *linuxContainer) Pause() error {
glog.Info("pause container")
panic("not implemented")
return c.cgroupManager.Freeze(cgroups.Frozen)
}
func (c *linuxContainer) Resume() error {
glog.Info("resume container")
panic("not implemented")
return c.cgroupManager.Freeze(cgroups.Thawed)
}
func (c *linuxContainer) Signal(pid, signal int) error {

View File

@ -19,9 +19,7 @@ import (
// Move this to libcontainer package.
// Exec performs setup outside of a namespace so that a container can be
// executed. Exec is a high level function for working with container namespaces.
func Exec(args []string, env []string, console string, command *exec.Cmd, container *configs.Config, cgroupManager cgroups.Manager, state *configs.State) error {
var err error
func Exec(args []string, env []string, console string, command *exec.Cmd, container *configs.Config, cgroupManager cgroups.Manager, state *configs.State) (err error) {
// create a pipe so that we can syncronize with the namespaced process and
// pass the state and configuration to the child process
parent, child, err := newInitPipe()
@ -73,7 +71,11 @@ func Exec(args []string, env []string, console string, command *exec.Cmd, contai
if err != nil {
return terminate(err)
}
defer cgroupManager.Destroy()
defer func() {
if err != nil {
cgroupManager.Destroy()
}
}()
var networkState network.NetworkState
if err := InitializeNetworking(container, command.Process.Pid, &networkState); err != nil {