From fb74bc5ce2a510e38b9a8a83d4524876f1881759 Mon Sep 17 00:00:00 2001 From: lujingxiao Date: Sat, 19 Jan 2019 11:11:25 +0800 Subject: [PATCH 002/111] pause: docker pause set timeout 30s reason:fix docker pause in infinite loop case,when the process in D status libcontainer: cgroups: Write freezer state after every state check This commit ensures we write the expected freezer cgroup state after every state check, in case the state check does not give the expected result. This can happen when a new task is created and prevents the whole cgroup to be FROZEN, leaving the state into FREEZING instead. This patch prevents the case of an infinite loop to happen. Cherry-pick from https://github.com/opencontainers/runc/pull/1610 Change-Id: Ib5355b9d928c491e120439780c1f03c18aa68b73 Signed-off-by: panwenxiang Signed-off-by: zhangyu235 Signed-off-by: lujingxiao --- components/engine/daemon/freezer/freezer.go | 37 +++++++++++++++------ 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/components/engine/daemon/freezer/freezer.go b/components/engine/daemon/freezer/freezer.go index 774f5c21ed..cd8b3513d7 100644 --- a/components/engine/daemon/freezer/freezer.go +++ b/components/engine/daemon/freezer/freezer.go @@ -161,19 +161,36 @@ func (f *freezer) IsPaused() (bool, error) { } func (f *freezer) updateCgroup(state string) error { - if err := writeFile(f.path, "freezer.state", state); err != nil { - return err + curState, err := readFile(f.path, "freezer.state") + if err != nil { + return fmt.Errorf("read current state failed for %#v", err) } + curState = strings.TrimSpace(curState) + timeout := time.After(30 * time.Second) + tick := time.Tick(1 * time.Millisecond) for { - newState, err := readFile(f.path, "freezer.state") - if err != nil { - return err - } - if strings.TrimSpace(newState) == state { - break + select { + case <-timeout: + if err := writeFile(f.path, "freezer.state", curState); err != nil { + return fmt.Errorf("cannot write %s to freezer for %#v", curState, err) + } + return fmt.Errorf("update freezer cgroup timeout for 30s") + case <-tick: + // In case this loop does not exit because it doesn't get the expected + // state, let's write again this state, hoping it's going to be properly + // set this time. Otherwise, this loop could run infinitely, waiting for + // a state change that would never happen. + if err := writeFile(f.path, "freezer.state", state); err != nil { + return fmt.Errorf("cannot write freezer.state for %#v", err) + } + newState, err := readFile(f.path, "freezer.state") + if err != nil { + return err + } + if strings.TrimSpace(newState) == state { + return nil + } } - time.Sleep(1 * time.Millisecond) } - return nil } -- 2.17.1