Skip to content

Commit ae04c16

Browse files
committed
runtime: guard Close() until both streams are complete
Signed-off-by: Peter Wagner <[email protected]>
1 parent e96ac20 commit ae04c16

1 file changed

Lines changed: 20 additions & 2 deletions

File tree

  • runtime/v1/linux/proc

runtime/v1/linux/proc/io.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
"os/exec"
2828
"path/filepath"
2929
"sync"
30+
"sync/atomic"
3031
"syscall"
3132

3233
"github.com/containerd/containerd/log"
@@ -123,7 +124,7 @@ func createIO(ctx context.Context, id string, ioUID, ioGID int, stdio proc.Stdio
123124
}
124125

125126
func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, wg, cwg *sync.WaitGroup) error {
126-
var sameFile io.WriteCloser
127+
var sameFile *countingWriteCloser
127128
for _, i := range []struct {
128129
name string
129130
dest func(wc io.WriteCloser, rc io.Closer)
@@ -185,14 +186,18 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w
185186
}
186187
} else {
187188
if sameFile != nil {
189+
sameFile.count++
188190
i.dest(sameFile, nil)
189191
continue
190192
}
191193
if fw, err = os.OpenFile(i.name, syscall.O_WRONLY|syscall.O_APPEND, 0); err != nil {
192194
return fmt.Errorf("containerd-shim: opening %s failed: %s", i.name, err)
193195
}
194196
if stdout == stderr {
195-
sameFile = fw
197+
sameFile = &countingWriteCloser{
198+
WriteCloser: fw,
199+
count: 1,
200+
}
196201
}
197202
}
198203
i.dest(fw, fr)
@@ -217,6 +222,19 @@ func copyPipes(ctx context.Context, rio runc.IO, stdin, stdout, stderr string, w
217222
return nil
218223
}
219224

225+
// countingWriteCloser masks io.Closer() until close has been invoked a certain number of times.
226+
type countingWriteCloser struct {
227+
io.WriteCloser
228+
count int64
229+
}
230+
231+
func (c *countingWriteCloser) Close() error {
232+
if atomic.AddInt64(&c.count, -1) > 0 {
233+
return nil
234+
}
235+
return c.WriteCloser.Close()
236+
}
237+
220238
// isFifo checks if a file is a fifo
221239
// if the file does not exist then it returns false
222240
func isFifo(path string) (bool, error) {

0 commit comments

Comments
 (0)