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
|
// 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)
|
ns, err := namespaces.NamespaceRequired(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var args []string
|
var args []string
|
||||||
for k, vs := range uri.Query() {
|
for k, vs := range uri.Query() {
|
||||||
args = append(args, k)
|
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()
|
out, err := newPipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to create stdout pipes")
|
||||||
}
|
}
|
||||||
|
closers = append(closers, out.Close)
|
||||||
|
|
||||||
serr, err := newPipe()
|
serr, err := newPipe()
|
||||||
if err != nil {
|
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()
|
r, w, err := os.Pipe()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
closers = append(closers, r.Close, w.Close)
|
||||||
|
|
||||||
cmd := exec.Command(uri.Path, args...)
|
cmd := exec.Command(uri.Path, args...)
|
||||||
cmd.Env = append(cmd.Env,
|
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
|
// don't need to register this with the reaper or wait when
|
||||||
// running inside a shim
|
// running inside a shim
|
||||||
if err := cmd.Start(); err != nil {
|
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
|
// close our side of the pipe after start
|
||||||
if err := w.Close(); err != nil {
|
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
|
// wait for the logging binary to be ready
|
||||||
b := make([]byte, 1)
|
b := make([]byte, 1)
|
||||||
if _, err := r.Read(b); err != nil && err != io.EOF {
|
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{
|
return &binaryIO{
|
||||||
cmd: cmd,
|
cmd: cmd,
|
||||||
out: out,
|
out: out,
|
||||||
@ -423,9 +443,15 @@ type pipe struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *pipe) Close() error {
|
func (p *pipe) Close() error {
|
||||||
err := p.w.Close()
|
var result *multierror.Error
|
||||||
if rerr := p.r.Close(); err == nil {
|
|
||||||
err = rerr
|
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