Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for unknown serve command 13 #3041

Merged
merged 2 commits into from Aug 16, 2019
Merged

Conversation

zimbatm
Copy link
Member

@zimbatm zimbatm commented Aug 12, 2019

Fixes #3039

libstore->addToStore(ValidPathInfo & info, Source & source, ...) can exit early if the path already exists into the store. It's an optimization. The source doesn't need to be read and is left untouched.

Unfortunately, the remote store protocols assume that the while NAR file will be send. So when that happens the protocol gets out of sync.

This PR introduces a SizedSource(Source & source, size_t size) which reads the source until size is reached. That way we can wrap the source and make sure it's read until narSize is reached. And then nix-store and nix-daemon are patched to use that new source.

If the NAR file is not consumed by addToStore the protocol gets out of sync. This introduces a new SizedReader that we can drain at the end in order to keep the protocol in sync. It means that

@@ -950,8 +950,12 @@ static void opServe(Strings opFlags, Strings opArgs)
info.sigs = readStrings<StringSet>(in);
in >> info.ca;

// FIXME: race if addToStore doesn't read source?
store->addToStore(info, in, NoRepair, NoCheckSigs);
SizedSource sizedSource(in, info.narSize);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand what SizedSource is for, in conjunction with drainAll(). Shouldn't drainAll just read and discard remain bytes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be a check for info.narSize == 0, which can happen in some legacy situations. It's probably fine to just throw an exception.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The SizedSource is a way to track the remain bytes inside of addToStore() since we don't know how much it will consume. It also acts as a guard that addToStore() won't read more than info.narSize on the socket (not that this has been a problem).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I thought but I assumed the point is so that you can then skip remain bytes at the end (rather than drain the FD, which introduces problems when the client is pipelining requests or hasn't written everything yet).

src/libutil/serialise.cc Outdated Show resolved Hide resolved
src/libutil/serialise.hh Outdated Show resolved Hide resolved
src/nix-store/nix-store.cc Show resolved Hide resolved
@zimbatm
Copy link
Member Author

zimbatm commented Aug 14, 2019

hitting issues with error: sized: unexpected end-of-file at the moment

@zimbatm zimbatm force-pushed the nix-store-error-13 branch 6 times, most recently from df5b6a5 to fa9550f Compare August 16, 2019 11:08
Introduce the SizeSource which allows to bound how much data is being
read from a source. It also contains a drainAll() function to discard
the rest of the source, useful to keep the nix protocol in sync.
If a NAR is already in the store, addToStore doesn't read the source
which makes the protocol go out of sync. This happens for example when
two client try to nix-copy-closure the same derivation at the same time.
@zimbatm
Copy link
Member Author

zimbatm commented Aug 16, 2019

I removed the nix-daemon patch because it had unexpected side-effects. The PR is now ready to be merged and has been tested manually.

@edolstra edolstra merged commit f435634 into NixOS:master Aug 16, 2019
@zimbatm zimbatm deleted the nix-store-error-13 branch August 16, 2019 14:22
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.

unknown serve command 13
2 participants