Cleanup binary IO resources on error
Signed-off-by: Maksym Pavlenko <makpav@amazon.com>
This commit is contained in:
parent
0dc7c85956
commit
9175401b28
@ -246,11 +246,12 @@ func (c *countingWriteCloser) Close() error {
|
||||
}
|
||||
|
||||
// NewBinaryIO runs a custom binary process for pluggable shim logging
|
||||
func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error) {
|
||||
func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (_ runc.IO, err error) {
|
||||
ns, err := namespaces.NamespaceRequired(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var args []string
|
||||
for k, vs := range uri.Query() {
|
||||
args = append(args, k)
|
||||
@ -259,20 +260,35 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error)
|
||||
}
|
||||
}
|
||||
|
||||
var closers []func() error
|
||||
defer func() {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
result := multierror.Append(err)
|
||||
for _, fn := range closers {
|
||||
result = multierror.Append(result, fn())
|
||||
}
|
||||
err = multierror.Flatten(result)
|
||||
}()
|
||||
|
||||
out, err := newPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "failed to create stdout pipes")
|
||||
}
|
||||
closers = append(closers, out.Close)
|
||||
|
||||
serr, err := newPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "failed to create stderr pipes")
|
||||
}
|
||||
closers = append(closers, serr.Close)
|
||||
|
||||
r, w, err := os.Pipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
closers = append(closers, r.Close, w.Close)
|
||||
|
||||
cmd := exec.Command(uri.Path, args...)
|
||||
cmd.Env = append(cmd.Env,
|
||||
@ -284,17 +300,21 @@ func NewBinaryIO(ctx context.Context, id string, uri *url.URL) (runc.IO, error)
|
||||
// don't need to register this with the reaper or wait when
|
||||
// running inside a shim
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "failed to start binary process")
|
||||
}
|
||||
closers = append(closers, func() error { return cmd.Process.Kill() })
|
||||
|
||||
// close our side of the pipe after start
|
||||
if err := w.Close(); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "failed to close write pipe after start")
|
||||
}
|
||||
|
||||
// wait for the logging binary to be ready
|
||||
b := make([]byte, 1)
|
||||
if _, err := r.Read(b); err != nil && err != io.EOF {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "failed to read from logging binary")
|
||||
}
|
||||
|
||||
return &binaryIO{
|
||||
cmd: cmd,
|
||||
out: out,
|
||||
@ -423,9 +443,15 @@ type pipe struct {
|
||||
}
|
||||
|
||||
func (p *pipe) Close() error {
|
||||
err := p.w.Close()
|
||||
if rerr := p.r.Close(); err == nil {
|
||||
err = rerr
|
||||
var result *multierror.Error
|
||||
|
||||
if err := p.w.Close(); err != nil {
|
||||
result = multierror.Append(result, errors.Wrap(err, "failed to close write pipe"))
|
||||
}
|
||||
return err
|
||||
|
||||
if err := p.r.Close(); err != nil {
|
||||
result = multierror.Append(result, errors.Wrap(err, "failed to close read pipe"))
|
||||
}
|
||||
|
||||
return multierror.Prefix(result.ErrorOrNil(), "pipe:")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user