mirror of
https://github.com/kata-containers/kata-containers.git
synced 2026-02-22 06:43:41 +00:00
runtime: Map empty ReadStdout/ReadStderr response to io.EOF
After the kata-agent "drain-after-exit" change, stdout/stderr EOF is signaled by a successful ReadStdout/ReadStderr reply with empty Data (len==0), instead of an RPC error. However, runtime-go currently returns (0, nil) to io.CopyBuffer() when resp.Data is empty, which violates Go io.Reader semantics and can cause `kubectl exec` to hang after the command output is already printed. To avoid exec hang: In readProcessStream(), map an empty response (len(resp.Data)==0) into (0, io.EOF). This allows the stdout/stderr copy goroutines to terminate, closes exitIOch, and unblocks the wait path so exec can complete normally. Signed-off-by: Alex Lyn <alex.lyn@antgroup.com>
This commit is contained in:
committed by
Fabiano Fidêncio
parent
ffb8a6a9c3
commit
41e8acbc5e
@@ -11,6 +11,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"path"
|
||||
@@ -2485,11 +2486,16 @@ func (k *kataAgent) readProcessStream(containerID, processID string, data []byte
|
||||
ContainerId: containerID,
|
||||
ExecId: processID,
|
||||
Len: uint32(len(data))})
|
||||
if err == nil {
|
||||
copy(data, resp.Data)
|
||||
return len(resp.Data), nil
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return 0, err
|
||||
|
||||
if len(resp.Data) == 0 {
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
copy(data, resp.Data)
|
||||
return len(resp.Data), nil
|
||||
}
|
||||
|
||||
func (k *kataAgent) getGuestDetails(ctx context.Context, req *grpc.GuestDetailsRequest) (*grpc.GuestDetailsResponse, error) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"bufio"
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@@ -176,10 +177,14 @@ func TestKataAgentSendReq(t *testing.T) {
|
||||
assert.Nil(err)
|
||||
|
||||
_, err = k.readProcessStdout(ctx, container, execid, []byte{})
|
||||
assert.Nil(err)
|
||||
if err != nil {
|
||||
assert.ErrorIs(err, io.EOF)
|
||||
}
|
||||
|
||||
_, err = k.readProcessStderr(ctx, container, execid, []byte{})
|
||||
assert.Nil(err)
|
||||
if err != nil {
|
||||
assert.ErrorIs(err, io.EOF)
|
||||
}
|
||||
|
||||
_, err = k.getOOMEvent(ctx)
|
||||
assert.Nil(err)
|
||||
|
||||
Reference in New Issue
Block a user