From d7df30181b7bc7d3853b4a4b794d54e58816da6a Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Mon, 4 Jan 2021 15:39:05 -0800 Subject: [PATCH 1/2] libct: suppress bogus "unable to terminate" warnings While working on a test case for [1], I got the following warning: > level=warning msg="unable to terminate initProcess" error="exit status 1" Obviously, the warning is bogus since the initProcess is terminated. This is happening because terminate() can return errors from either Kill() or Wait(), and the latter returns an error if the process has not finished successfully (i.e. exit status is not 0 or it was killed). Check for a particular error type and filter out those errors. [1] https://github.com/opencontainers/runc/issues/2683 Signed-off-by: Kir Kolyshkin --- libcontainer/container_linux.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 8abdc3fe9a6..4dafa5636da 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -2067,9 +2067,17 @@ func ignoreTerminateErrors(err error) error { if err == nil { return nil } + // terminate() might return an error from ether Kill or Wait. + // The (*Cmd).Wait documentation says: "If the command fails to run + // or doesn't complete successfully, the error is of type *ExitError". + // Filter out such errors (like "exit status 1" or "signal: killed"). + var exitErr *exec.ExitError + if errors.As(err, &exitErr) { + return nil + } + s := err.Error() - if strings.Contains(s, "signal: killed") || - strings.Contains(s, "process already finished") || + if strings.Contains(s, "process already finished") || strings.Contains(s, "Wait was already called") { return nil } From 72f463891d8e550ba0f80f3337092c1c84aab5a5 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 5 Jan 2021 14:34:54 -0800 Subject: [PATCH 2/2] libct: add TODO about os.ErrProcessDone This is a new variable added by go 1.16 so we'll have to wait until 1.16 is minimally supported version, thus TODO for now. Signed-off-by: Kir Kolyshkin --- libcontainer/container_linux.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go index 4dafa5636da..3dca29e4c3f 100644 --- a/libcontainer/container_linux.go +++ b/libcontainer/container_linux.go @@ -2075,6 +2075,9 @@ func ignoreTerminateErrors(err error) error { if errors.As(err, &exitErr) { return nil } + // TODO: use errors.Is(err, os.ErrProcessDone) here and + // remove "process already finished" string comparison below + // once go 1.16 is minimally supported version. s := err.Error() if strings.Contains(s, "process already finished") ||