Skip to content

*: io.Copy improvements - #437

Merged
cyphar merged 2 commits into
opencontainers:mainfrom
cyphar:io-copy-improvements
May 18, 2022
Merged

cyphar merged 2 commits into
opencontainers:mainfrom
cyphar:io-copy-improvements

Conversation

@cyphar

@cyphar cyphar commented May 11, 2022

Copy link
Copy Markdown
Member
  • Implement EINTR-retry logic for io.Copy users to avoid erroring out for no reason.
  • Improve io.Pipe CloseWithError usage so that we make any pipe-passed errors louder.

These changes might help with #436 but I'm not sure whether these were the root cause of the issue.

Signed-off-by: Aleksa Sarai cyphar@cyphar.com

cyphar added 2 commits May 11, 2022 12:16
This is necessary to make sure we don't error out for no reason. In
addition, there have been cases where errors are not correctly passed on
through CloseWithError, which could result in truncated data being
written into images.

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
While the Go stdlib bug has been fixed[1], closing a single pipe
multiple times with different CloseWithError() calls doesn't make much
sense (even if they are now a no-op).

In addition, log a warning whenever we use CloseWithError() because
we've observed flaky tests and bug reports where even though an error
should've been propogated all the way up through CloseWithError() it
seems that the error still got lost. This way at least you can tell an
issue occurred during generation.

[1]: https://golang.org/issue/24283

Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
@cyphar
cyphar force-pushed the io-copy-improvements branch from f9700be to 2163223 Compare May 11, 2022 02:16
@codecov-commenter

codecov-commenter commented May 11, 2022 •

Copy link
Copy Markdown

Codecov Report

Merging #437 (2163223) into main (90f64d5) will decrease coverage by 0.33%.
The diff coverage is 39.65%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #437      +/-   ##
==========================================
- Coverage   74.12%   73.78%   -0.34%     
==========================================
  Files          59       60       +1     
  Lines        4831     4872      +41     
==========================================
+ Hits         3581     3595      +14     
- Misses        898      923      +25     
- Partials      352      354       +2     
Impacted Files Coverage Δ
oci/layer/unpack.go 58.01% <0.00%> (+1.41%) ⬆️
mutate/compress.go 43.33% <21.05%> (-12.67%) ⬇️
pkg/system/copy.go 37.93% <37.93%> (ø)
oci/cas/dir/dir.go 59.28% <100.00%> (ø)
oci/casext/blob.go 81.25% <100.00%> (ø)
oci/layer/generate.go 66.01% <100.00%> (+0.67%) ⬆️
oci/layer/tar_extract.go 63.86% <100.00%> (ø)
oci/layer/tar_generate.go 71.42% <100.00%> (ø)
pkg/hardening/verified_reader.go 83.51% <100.00%> (ø)
... and 1 more

@cyphar

cyphar commented May 16, 2022

Copy link
Copy Markdown
Member Author

/cc @mikemccracken
/ping @tych0

@tych0

tych0 commented May 16, 2022

Copy link
Copy Markdown
Member

I'm a little suspicious that we're hitting EINTR; most of these files we're writing to will have been created via the dir cas backend's PutBlob(), which it looks like uses ioutil.TempFile(), which doesn't open things as O_NONBLOCK AFAIK.

The patch itself looks fine to me, though.

@cyphar

cyphar commented May 18, 2022

Copy link
Copy Markdown
Member Author

@tych0 From a few Go releases ago, you can get EINTR randomly because Go now has far more aggressive preeimptive scheduling which results in loads of EINTRs popping up in IO operations. We had to switch to EINTR retry loops in runc and a few other projects. I don't know if that is the root cause (especially since they didn't see any errors during building) but I'd be surprised if this isn't something that might happen.

@tych0

tych0 commented May 18, 2022

Copy link
Copy Markdown
Member

Yeah, I've heard about this change. But man, that sucks. Really feels like you should not have to deal with EINTR from every possible function call that could cause a kernel sleep...

@cyphar

cyphar commented May 18, 2022

Copy link
Copy Markdown
Member Author

Yeah I don't understand why they didn't handle this in the stdlib -- the behaviour of io.Copy should pretty clearly indicate that an EINTR should be ignored...

@cyphar cyphar closed this in 4270d5b May 18, 2022
@cyphar
cyphar merged commit 4270d5b into opencontainers:main May 18, 2022
@cyphar
cyphar deleted the io-copy-improvements branch May 18, 2022 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

⌂ 换网址