copy: prevent potential deadlock if close before fully written
We also need an additional check to avoid setting both the error and response which can create a race where they can arrive in the receiving thread in either order. If we hit an error, we don't need to send the response. > There is a condition where the registry (unexpectedly, not to spec) > returns 201 or 204 on the put before the body is fully written. I would > expect that the http library would issue close and could fall into a > deadlock here. We could just read respC and call setResponse. In that > case ErrClosedPipe would get returned and Commit shouldn't be called > anyway. Signed-off-by: Justin Chadwell <me@jedevc.com>
This commit is contained in:
parent
b48e1141eb
commit
a9152ebf89
@ -297,6 +297,7 @@ func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, ref str
|
|||||||
err := remoteserrors.NewUnexpectedStatusErr(resp)
|
err := remoteserrors.NewUnexpectedStatusErr(resp)
|
||||||
log.G(ctx).WithField("resp", resp).WithField("body", string(err.(remoteserrors.ErrUnexpectedStatus).Body)).Debug("unexpected response")
|
log.G(ctx).WithField("resp", resp).WithField("body", string(err.(remoteserrors.ErrUnexpectedStatus).Body)).Debug("unexpected response")
|
||||||
pushw.setError(err)
|
pushw.setError(err)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
pushw.setResponse(resp)
|
pushw.setResponse(resp)
|
||||||
}()
|
}()
|
||||||
@ -432,6 +433,8 @@ func (pw *pushWriter) Write(p []byte) (n int, err error) {
|
|||||||
pw.Close()
|
pw.Close()
|
||||||
case p := <-pw.pipeC:
|
case p := <-pw.pipeC:
|
||||||
return 0, pw.replacePipe(p)
|
return 0, pw.replacePipe(p)
|
||||||
|
case resp := <-pw.respC:
|
||||||
|
pw.setResponse(resp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
status.Offset += int64(n)
|
status.Offset += int64(n)
|
||||||
|
Loading…
Reference in New Issue
Block a user