@@ -246,11 +246,12 @@ func (c *countingWriteCloser) Close() error {
246246}
247247
248248// NewBinaryIO runs a custom binary process for pluggable shim logging
249- func NewBinaryIO (ctx context.Context , id string , uri * url.URL ) (runc.IO , error ) {
249+ func NewBinaryIO (ctx context.Context , id string , uri * url.URL ) (_ runc.IO , err error ) {
250250 ns , err := namespaces .NamespaceRequired (ctx )
251251 if err != nil {
252252 return nil , err
253253 }
254+
254255 var args []string
255256 for k , vs := range uri .Query () {
256257 args = append (args , k )
@@ -259,20 +260,35 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error)
259260 }
260261 }
261262
263+ var closers []func () error
264+ defer func () {
265+ if err == nil {
266+ return
267+ }
268+ result := multierror .Append (err )
269+ for _ , fn := range closers {
270+ result = multierror .Append (result , fn ())
271+ }
272+ err = multierror .Flatten (result )
273+ }()
274+
262275 out , err := newPipe ()
263276 if err != nil {
264- return nil , err
277+ return nil , errors . Wrap ( err , "failed to create stdout pipes" )
265278 }
279+ closers = append (closers , out .Close )
266280
267281 serr , err := newPipe ()
268282 if err != nil {
269- return nil , err
283+ return nil , errors . Wrap ( err , "failed to create stderr pipes" )
270284 }
285+ closers = append (closers , serr .Close )
271286
272287 r , w , err := os .Pipe ()
273288 if err != nil {
274289 return nil , err
275290 }
291+ closers = append (closers , r .Close , w .Close )
276292
277293 cmd := exec .Command (uri .Path , args ... )
278294 cmd .Env = append (cmd .Env ,
@@ -284,17 +300,21 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error)
284300 // don't need to register this with the reaper or wait when
285301 // running inside a shim
286302 if err := cmd .Start (); err != nil {
287- return nil , err
303+ return nil , errors . Wrap ( err , "failed to start binary process" )
288304 }
305+ closers = append (closers , func () error { return cmd .Process .Kill () })
306+
289307 // close our side of the pipe after start
290308 if err := w .Close (); err != nil {
291- return nil , err
309+ return nil , errors . Wrap ( err , "failed to close write pipe after start" )
292310 }
311+
293312 // wait for the logging binary to be ready
294313 b := make ([]byte , 1 )
295314 if _ , err := r .Read (b ); err != nil && err != io .EOF {
296- return nil , err
315+ return nil , errors . Wrap ( err , "failed to read from logging binary" )
297316 }
317+
298318 return & binaryIO {
299319 cmd : cmd ,
300320 out : out ,
@@ -423,9 +443,15 @@ type pipe struct {
423443}
424444
425445func (p * pipe ) Close () error {
426- err := p .w .Close ()
427- if rerr := p .r .Close (); err == nil {
428- err = rerr
446+ var result * multierror.Error
447+
448+ if err := p .w .Close (); err != nil {
449+ result = multierror .Append (result , errors .Wrap (err , "failed to close write pipe" ))
450+ }
451+
452+ if err := p .r .Close (); err != nil {
453+ result = multierror .Append (result , errors .Wrap (err , "failed to close read pipe" ))
429454 }
430- return err
455+
456+ return multierror .Prefix (result .ErrorOrNil (), "pipe:" )
431457}
0 commit comments