Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions src/libstore/export-import.cc
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,15 @@ StorePaths importPaths(Store & store, Source & source, CheckSigsFlag checkSigs)
/* Empty version 1 nario, nothing to do. */
break;

case 1:
case 1: {
/* Reuse a string buffer to avoid kernel overhead allocating
memory for large strings. */
StringSink saved;

/* Non-empty version 1 nario. */
while (true) {
/* Extract the NAR from the source. */
StringSink saved;
saved.s.clear();
TeeSource tee{source, saved};
NullFileSystemObjectSink ether;
parseDump(ether, tee);
Expand All @@ -101,23 +105,26 @@ StorePaths importPaths(Store & store, Source & source, CheckSigsFlag checkSigs)

auto references = CommonProto::Serialise<StorePathSet>::read(store, CommonProto::ReadConn{.from = source});
auto deriver = readString(source);
auto narHash = hashString(HashAlgorithm::SHA256, saved.s);

ValidPathInfo info{path, narHash};
if (deriver != "")
info.deriver = store.parseStorePath(deriver);
info.references = references;
info.narSize = saved.s.size();

// Ignore optional legacy signature.
if (readInt(source) == 1)
readString(source);

// Can't use underlying source, which would have been exhausted.
auto source2 = StringSource(saved.s);
store.addToStore(info, source2, NoRepair, checkSigs);
if (!store.isValidPath(path)) {
auto narHash = hashString(HashAlgorithm::SHA256, saved.s);

res.push_back(info.path);
ValidPathInfo info{path, narHash};
if (deriver != "")
info.deriver = store.parseStorePath(deriver);
info.references = references;
info.narSize = saved.s.size();

// Can't use underlying source, which would have been exhausted.
auto source2 = StringSource(saved.s);
store.addToStore(info, source2, NoRepair, checkSigs);
}

res.push_back(path);

auto n = readNum<uint64_t>(source);
if (n == 0)
Expand All @@ -126,6 +133,7 @@ StorePaths importPaths(Store & store, Source & source, CheckSigsFlag checkSigs)
throw Error("input doesn't look like a nario");
}
break;
}

case exportMagicV2:
while (true) {
Expand Down
16 changes: 10 additions & 6 deletions src/libstore/local-store.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1049,12 +1049,16 @@ void LocalStore::addToStore(const ValidPathInfo & info, Source & source, RepairF
bool narRead = false;
Finally cleanup = [&]() {
if (!narRead) {
NullFileSystemObjectSink sink;
try {
parseDump(sink, source);
} catch (...) {
// TODO: should Interrupted be handled here?
ignoreExceptionInDestructor();
if (info.narSize)
source.skip(info.narSize);
else {
NullFileSystemObjectSink sink;
try {
parseDump(sink, source);
} catch (...) {
// TODO: should Interrupted be handled here?
ignoreExceptionInDestructor();
}
}
}
};
Expand Down
2 changes: 2 additions & 0 deletions src/libutil/include/nix/util/serialise.hh
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@ struct StringSource : Source
}

size_t read(char * data, size_t len) override;

void skip(size_t len) override;
};

/**
Expand Down
10 changes: 10 additions & 0 deletions src/libutil/serialise.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,16 @@ size_t StringSource::read(char * data, size_t len)
return n;
}

void StringSource::skip(size_t len)
{
const size_t remain = s.size() - pos;
if (len > remain) {
pos = s.size();
throw EndOfFile("end of string reached");
}
pos += len;
}

std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun)
{
struct SourceToSink : FinishSink
Expand Down