Integrating systemd freeze functionality.
This pulls together #6061 and #6125 Docker-DCO-1.1-Signed-off-by: Chris Alfonso <calfonso@redhat.com> (github: calfonso)
This commit is contained in:
parent
b054569cde
commit
26246ebd53
5 changed files with 34 additions and 55 deletions
|
@ -538,6 +538,11 @@ func (container *Container) KillSig(sig int) error {
|
||||||
container.Lock()
|
container.Lock()
|
||||||
defer container.Unlock()
|
defer container.Unlock()
|
||||||
|
|
||||||
|
// We could unpause the container for them rather than returning this error
|
||||||
|
if container.State.IsPaused() {
|
||||||
|
return fmt.Errorf("Container %s is paused. Unpause the container before stopping", container.ID)
|
||||||
|
}
|
||||||
|
|
||||||
if !container.State.IsRunning() {
|
if !container.State.IsRunning() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -594,11 +599,6 @@ func (container *Container) Stop(seconds int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// We could unpause the container for them rather than returning this error
|
|
||||||
if container.State.IsPaused() {
|
|
||||||
return fmt.Errorf("Container %s is paused. Unpause the container before stopping", container.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. Send a SIGTERM
|
// 1. Send a SIGTERM
|
||||||
if err := container.KillSig(15); err != nil {
|
if err := container.KillSig(15); err != nil {
|
||||||
log.Print("Failed to send SIGTERM to the process, force killing")
|
log.Print("Failed to send SIGTERM to the process, force killing")
|
||||||
|
|
|
@ -1015,8 +1015,7 @@ func (daemon *Daemon) Run(c *Container, pipes *execdriver.Pipes, startCallback e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (daemon *Daemon) Pause(c *Container) error {
|
func (daemon *Daemon) Pause(c *Container) error {
|
||||||
err := daemon.execDriver.Pause(c.command)
|
if err := daemon.execDriver.Pause(c.command); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.State.SetPaused()
|
c.State.SetPaused()
|
||||||
|
@ -1024,8 +1023,7 @@ func (daemon *Daemon) Pause(c *Container) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (daemon *Daemon) Unpause(c *Container) error {
|
func (daemon *Daemon) Unpause(c *Container) error {
|
||||||
err := daemon.execDriver.Unpause(c.command)
|
if err := daemon.execDriver.Unpause(c.command); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.State.SetUnpaused()
|
c.State.SetUnpaused()
|
||||||
|
|
|
@ -27,7 +27,6 @@ var actions = map[string]Action{
|
||||||
"cgroups.memory_reservation": memoryReservation, // set the memory reservation
|
"cgroups.memory_reservation": memoryReservation, // set the memory reservation
|
||||||
"cgroups.memory_swap": memorySwap, // set the memory swap limit
|
"cgroups.memory_swap": memorySwap, // set the memory swap limit
|
||||||
"cgroups.cpuset.cpus": cpusetCpus, // set the cpus used
|
"cgroups.cpuset.cpus": cpusetCpus, // set the cpus used
|
||||||
"cgroups.freezer": freezer, // set the frozen/thaw state
|
|
||||||
|
|
||||||
"systemd.slice": systemdSlice, // set parent Slice used for systemd unit
|
"systemd.slice": systemdSlice, // set parent Slice used for systemd unit
|
||||||
|
|
||||||
|
@ -36,16 +35,6 @@ var actions = map[string]Action{
|
||||||
"fs.readonly": readonlyFs, // make the rootfs of the container read only
|
"fs.readonly": readonlyFs, // make the rootfs of the container read only
|
||||||
}
|
}
|
||||||
|
|
||||||
func freezer(container *libcontainer.Container, context interface{}, value string) error {
|
|
||||||
if container.Cgroups == nil {
|
|
||||||
return fmt.Errorf("cannot set cgroups when they are disabled")
|
|
||||||
}
|
|
||||||
|
|
||||||
container.Cgroups.Freezer = value
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func cpusetCpus(container *libcontainer.Container, context interface{}, value string) error {
|
func cpusetCpus(container *libcontainer.Container, context interface{}, value string) error {
|
||||||
if container.Cgroups == nil {
|
if container.Cgroups == nil {
|
||||||
return fmt.Errorf("cannot set cgroups when they are disabled")
|
return fmt.Errorf("cannot set cgroups when they are disabled")
|
||||||
|
|
|
@ -147,28 +147,26 @@ func (d *driver) Kill(p *execdriver.Command, sig int) error {
|
||||||
|
|
||||||
func (d *driver) Pause(c *execdriver.Command) error {
|
func (d *driver) Pause(c *execdriver.Command) error {
|
||||||
active := d.activeContainers[c.ID]
|
active := d.activeContainers[c.ID]
|
||||||
active.container.Cgroups.Freezer = "FROZEN"
|
if active == nil {
|
||||||
pid := c.Process.Pid
|
return fmt.Errorf("active container for %s does not exist", c.ID)
|
||||||
|
|
||||||
if systemd.UseSystemd() {
|
|
||||||
_, err := systemd.Apply(active.container.Cgroups, pid)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
_, err := fs.Apply(active.container.Cgroups, pid)
|
active.container.Cgroups.Freezer = "FROZEN"
|
||||||
return err
|
if systemd.UseSystemd() {
|
||||||
|
return systemd.Freeze(active.container.Cgroups, active.container.Cgroups.Freezer)
|
||||||
|
}
|
||||||
|
return fs.Freeze(active.container.Cgroups, active.container.Cgroups.Freezer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *driver) Unpause(c *execdriver.Command) error {
|
func (d *driver) Unpause(c *execdriver.Command) error {
|
||||||
active := d.activeContainers[c.ID]
|
active := d.activeContainers[c.ID]
|
||||||
active.container.Cgroups.Freezer = "THAWED"
|
if active == nil {
|
||||||
pid := c.Process.Pid
|
return fmt.Errorf("active container for %s does not exist", c.ID)
|
||||||
|
|
||||||
if systemd.UseSystemd() {
|
|
||||||
_, err := systemd.Apply(active.container.Cgroups, pid)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
_, err := fs.Apply(active.container.Cgroups, pid)
|
active.container.Cgroups.Freezer = "THAWED"
|
||||||
return err
|
if systemd.UseSystemd() {
|
||||||
|
return systemd.Freeze(active.container.Cgroups, active.container.Cgroups.Freezer)
|
||||||
|
}
|
||||||
|
return fs.Freeze(active.container.Cgroups, active.container.Cgroups.Freezer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *driver) Terminate(p *execdriver.Command) error {
|
func (d *driver) Terminate(p *execdriver.Command) error {
|
||||||
|
|
|
@ -171,20 +171,17 @@ func InitServer(job *engine.Job) engine.Status {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (srv *Server) ContainerPause(job *engine.Job) engine.Status {
|
func (srv *Server) ContainerPause(job *engine.Job) engine.Status {
|
||||||
if n := len(job.Args); n < 1 || n > 2 {
|
if len(job.Args) != 1 {
|
||||||
return job.Errorf("Usage: %s CONTAINER", job.Name)
|
return job.Errorf("Usage: %s CONTAINER", job.Name)
|
||||||
}
|
}
|
||||||
var (
|
name := job.Args[0]
|
||||||
name = job.Args[0]
|
container := srv.daemon.Get(name)
|
||||||
)
|
if container == nil {
|
||||||
|
|
||||||
if container := srv.daemon.Get(name); container != nil {
|
|
||||||
if err := container.Pause(); err != nil {
|
|
||||||
return job.Errorf("Cannot pause container %s: %s", name, err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return job.Errorf("No such container: %s", name)
|
return job.Errorf("No such container: %s", name)
|
||||||
}
|
}
|
||||||
|
if err := container.Pause(); err != nil {
|
||||||
|
return job.Errorf("Cannot pause container %s: %s", name, err)
|
||||||
|
}
|
||||||
return engine.StatusOK
|
return engine.StatusOK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,17 +189,14 @@ func (srv *Server) ContainerUnpause(job *engine.Job) engine.Status {
|
||||||
if n := len(job.Args); n < 1 || n > 2 {
|
if n := len(job.Args); n < 1 || n > 2 {
|
||||||
return job.Errorf("Usage: %s CONTAINER", job.Name)
|
return job.Errorf("Usage: %s CONTAINER", job.Name)
|
||||||
}
|
}
|
||||||
var (
|
name := job.Args[0]
|
||||||
name = job.Args[0]
|
container := srv.daemon.Get(name)
|
||||||
)
|
if container == nil {
|
||||||
|
|
||||||
if container := srv.daemon.Get(name); container != nil {
|
|
||||||
if err := container.Unpause(); err != nil {
|
|
||||||
return job.Errorf("Cannot unpause container %s: %s", name, err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return job.Errorf("No such container: %s", name)
|
return job.Errorf("No such container: %s", name)
|
||||||
}
|
}
|
||||||
|
if err := container.Unpause(); err != nil {
|
||||||
|
return job.Errorf("Cannot unpause container %s: %s", name, err)
|
||||||
|
}
|
||||||
return engine.StatusOK
|
return engine.StatusOK
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue