From 8438114399ce025b6977215dbaedc05697a6d958 Mon Sep 17 00:00:00 2001 From: Magic_RB Date: Mon, 3 May 2021 09:54:31 +0200 Subject: [PATCH 01/23] Add ignored_acls setting Signed-off-by: Magic_RB --- src/libstore/globals.hh | 9 +++++++++ src/libstore/local-store.cc | 4 +--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 8784d5faf..7e01b4960 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -805,6 +805,15 @@ public: may be useful in certain scenarios (e.g. to spin up containers or set up userspace network interfaces in tests). )"}; + + Setting ignoredAcls{ + this, {"security.selinux"}, "ignored-acls", + R"( + A list of ACLs that should be ignored, normally Nix attempts to + remove all ACLs from files and directories in the Nix store, but + some ACLs like `security.selinux` or `system.nfs4_acl` can't be + removed even by root. Therefore it's best to just ignore them. + )"}; #endif Setting hashedMirrors{ diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 747eb205e..c6f774bc2 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -583,9 +583,7 @@ static void canonicalisePathMetaData_(const Path & path, uid_t fromUid, InodesSe throw SysError("querying extended attributes of '%s'", path); for (auto & eaName: tokenizeString(std::string(eaBuf.data(), eaSize), std::string("\000", 1))) { - /* Ignore SELinux security labels since these cannot be - removed even by root. */ - if (eaName == "security.selinux") continue; + if (settings.ignoredAcls.get().count(eaName)) continue; if (lremovexattr(path.c_str(), eaName.c_str()) == -1) throw SysError("removing extended attribute '%s' from '%s'", eaName, path); } From 374fe49ff78c13457c6cfe396f9ed0cb986c903b Mon Sep 17 00:00:00 2001 From: Michael Bishop Date: Sun, 19 Sep 2021 23:07:10 -0300 Subject: [PATCH 02/23] set the PER_LINUX32 personality flag, when building for armv6l-linux or armv7l-linux this prevents 32bit builds from detecting a 64bit kernel and picking the wrong target --- src/libstore/build/local-derivation-goal.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc index 518edae9c..21d7d7408 100644 --- a/src/libstore/build/local-derivation-goal.cc +++ b/src/libstore/build/local-derivation-goal.cc @@ -1778,6 +1778,10 @@ void LocalDerivationGoal::runChild() if (personality(PER_LINUX32) == -1) throw SysError("cannot set i686-linux personality"); } + if (drv->platform == "armv7l-linux" || drv->platform == "armv6l-linux") { + if (personality(PER_LINUX32) == -1) + throw SysError("cannot set 32bit linux personality"); + } /* Impersonate a Linux 2.6 machine to get some determinism in builds that depend on the kernel version. */ From 9d67332e4b8d75a101b8cf6e1d7e4dc8e99e964a Mon Sep 17 00:00:00 2001 From: Geoff Reedy Date: Wed, 22 Sep 2021 20:30:31 -0600 Subject: [PATCH 03/23] Better eval error locations for interpolation and + Previously, type or coercion errors for string interpolation, path interpolation, and plus expressions were always reported at the beginning of the outer expression. This leads to confusing evaluation error messages making it hard to accurately diagnose and then fix the error. For example, errors were reported as follows. ``` cannot coerce an integer to a string 1| let foo = 7; in "bar" + foo | ^ cannot add a string to an integer 1| let foo = "bar"; in 4 + foo | ^ cannot coerce an integer to a string 1| let foo = 7; in "x${foo}" | ^ ``` This commit changes the ExprConcatStrings expression vector to store a sequence of expressions *and* their expansion locations so that error locations can be reported accurately. For interpolation, the error is reported at the beginning of the entire `${foo}`, not at the beginning of `foo` because I thought this was slightly clearer. The previous errors are now reported as: ``` cannot coerce an integer to a string 1| let foo = 7; in "bar" + foo | ^ cannot add a string to an integer 1| let foo = "bar"; in 4 + foo | ^ cannot coerce an integer to a string 1| let foo = 7; in "x${foo}" | ^ ``` The error is reported at this kind of precise location even for multi-line indented strings. This probably helps with at least some of the cases mentioned in #561 --- src/libexpr/eval.cc | 8 ++++---- src/libexpr/nixexpr.cc | 4 ++-- src/libexpr/nixexpr.hh | 4 ++-- src/libexpr/parser.y | 38 +++++++++++++++++++------------------- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index bc41a2cd9..3f18ad1ed 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1577,7 +1577,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) bool first = !forceString; ValueType firstType = nString; - for (auto & i : *es) { + for (auto & [i_pos, i] : *es) { Value vTmp; i->eval(state, env, vTmp); @@ -1598,19 +1598,19 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v) nf = n; nf += vTmp.fpoint; } else - throwEvalError(pos, "cannot add %1% to an integer", showType(vTmp)); + throwEvalError(i_pos, "cannot add %1% to an integer", showType(vTmp)); } else if (firstType == nFloat) { if (vTmp.type() == nInt) { nf += vTmp.integer; } else if (vTmp.type() == nFloat) { nf += vTmp.fpoint; } else - throwEvalError(pos, "cannot add %1% to a float", showType(vTmp)); + throwEvalError(i_pos, "cannot add %1% to a float", showType(vTmp)); } else /* skip canonization of first path, which would only be not canonized in the first place if it's coming from a ./${foo} type path */ - s << state.coerceToString(pos, vTmp, context, false, firstType == nString, !first); + s << state.coerceToString(i_pos, vTmp, context, false, firstType == nString, !first); first = false; } diff --git a/src/libexpr/nixexpr.cc b/src/libexpr/nixexpr.cc index 492b819e7..15d963d55 100644 --- a/src/libexpr/nixexpr.cc +++ b/src/libexpr/nixexpr.cc @@ -181,7 +181,7 @@ void ExprConcatStrings::show(std::ostream & str) const str << "("; for (auto & i : *es) { if (first) first = false; else str << " + "; - str << *i; + str << i.second; } str << ")"; } @@ -413,7 +413,7 @@ void ExprOpNot::bindVars(const StaticEnv & env) void ExprConcatStrings::bindVars(const StaticEnv & env) { for (auto & i : *es) - i->bindVars(env); + i.second->bindVars(env); } void ExprPos::bindVars(const StaticEnv & env) diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 51a14cd59..d3f7f5bd6 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -321,8 +321,8 @@ struct ExprConcatStrings : Expr { Pos pos; bool forceString; - vector * es; - ExprConcatStrings(const Pos & pos, bool forceString, vector * es) + vector > * es; + ExprConcatStrings(const Pos & pos, bool forceString, vector > * es) : pos(pos), forceString(forceString), es(es) { }; COMMON_METHODS }; diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index e3749783a..c21d7b033 100644 --- a/src/libexpr/parser.y +++ b/src/libexpr/parser.y @@ -154,7 +154,7 @@ static void addFormal(const Pos & pos, Formals * formals, const Formal & formal) } -static Expr * stripIndentation(const Pos & pos, SymbolTable & symbols, vector & es) +static Expr * stripIndentation(const Pos & pos, SymbolTable & symbols, vector > & es) { if (es.empty()) return new ExprString(symbols.create("")); @@ -164,7 +164,7 @@ static Expr * stripIndentation(const Pos & pos, SymbolTable & symbols, vector(i); if (!e) { /* Anti-quotations end the current start-of-line whitespace. */ @@ -194,12 +194,12 @@ static Expr * stripIndentation(const Pos & pos, SymbolTable & symbols, vector * es2 = new vector; + vector > * es2 = new vector >; atStartOfLine = true; size_t curDropped = 0; size_t n = es.size(); - for (vector::iterator i = es.begin(); i != es.end(); ++i, --n) { - ExprIndStr * e = dynamic_cast(*i); + for (vector >::iterator i = es.begin(); i != es.end(); ++i, --n) { + ExprIndStr * e = dynamic_cast(i->second); if (!e) { atStartOfLine = false; curDropped = 0; @@ -236,11 +236,11 @@ static Expr * stripIndentation(const Pos & pos, SymbolTable & symbols, vectorpush_back(new ExprString(symbols.create(s2))); + es2->emplace_back(i->first, new ExprString(symbols.create(s2))); } /* If this is a single string, then don't do a concatenation. */ - return es2->size() == 1 && dynamic_cast((*es2)[0]) ? (*es2)[0] : new ExprConcatStrings(pos, true, es2); + return es2->size() == 1 && dynamic_cast((*es2)[0].second) ? (*es2)[0].second : new ExprConcatStrings(pos, true, es2); } @@ -279,7 +279,7 @@ void yyerror(YYLTYPE * loc, yyscan_t scanner, ParseData * data, const char * err char * path; char * uri; std::vector * attrNames; - std::vector * string_parts; + std::vector > * string_parts; } %type start expr expr_function expr_if expr_op @@ -366,7 +366,7 @@ expr_op | expr_op UPDATE expr_op { $$ = new ExprOpUpdate(CUR_POS, $1, $3); } | expr_op '?' attrpath { $$ = new ExprOpHasAttr($1, *$3); } | expr_op '+' expr_op - { $$ = new ExprConcatStrings(CUR_POS, false, new vector({$1, $3})); } + { $$ = new ExprConcatStrings(CUR_POS, false, new vector >({{makeCurPos(@1, data), $1}, {makeCurPos(@3, data), $3}})); } | expr_op '-' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprVar(data->symbols.create("__sub")), $1), $3); } | expr_op '*' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprVar(data->symbols.create("__mul")), $1), $3); } | expr_op '/' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprVar(data->symbols.create("__div")), $1), $3); } @@ -407,7 +407,7 @@ expr_simple } | path_start PATH_END { $$ = $1; } | path_start string_parts_interpolated PATH_END { - $2->insert($2->begin(), $1); + $2->insert($2->begin(), {makeCurPos(@1, data), $1}); $$ = new ExprConcatStrings(CUR_POS, false, $2); } | SPATH { @@ -445,13 +445,13 @@ string_parts ; string_parts_interpolated - : string_parts_interpolated STR { $$ = $1; $1->push_back($2); } - | string_parts_interpolated DOLLAR_CURLY expr '}' { $$ = $1; $1->push_back($3); } - | DOLLAR_CURLY expr '}' { $$ = new vector; $$->push_back($2); } + : string_parts_interpolated STR { $$ = $1; $1->emplace_back(makeCurPos(@2, data), $2); } + | string_parts_interpolated DOLLAR_CURLY expr '}' { $$ = $1; $1->emplace_back(makeCurPos(@2, data), $3); } + | DOLLAR_CURLY expr '}' { $$ = new vector >; $$->emplace_back(makeCurPos(@1, data), $2); } | STR DOLLAR_CURLY expr '}' { - $$ = new vector; - $$->push_back($1); - $$->push_back($3); + $$ = new vector >; + $$->emplace_back(makeCurPos(@1, data), $1); + $$->emplace_back(makeCurPos(@2, data), $3); } ; @@ -470,9 +470,9 @@ path_start ; ind_string_parts - : ind_string_parts IND_STR { $$ = $1; $1->push_back($2); } - | ind_string_parts DOLLAR_CURLY expr '}' { $$ = $1; $1->push_back($3); } - | { $$ = new vector; } + : ind_string_parts IND_STR { $$ = $1; $1->emplace_back(makeCurPos(@2, data), $2); } + | ind_string_parts DOLLAR_CURLY expr '}' { $$ = $1; $1->emplace_back(makeCurPos(@2, data), $3); } + | { $$ = new vector >; } ; binds From a2473823d748b0249804d393c739622146954d02 Mon Sep 17 00:00:00 2001 From: figsoda Date: Wed, 27 Oct 2021 14:18:30 -0400 Subject: [PATCH 04/23] run: use pname as a fallback for main program --- src/nix/app.cc | 3 +++ src/nix/run.md | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/nix/app.cc b/src/nix/app.cc index 9719a65dd..2fcf4752c 100644 --- a/src/nix/app.cc +++ b/src/nix/app.cc @@ -83,11 +83,14 @@ UnresolvedApp Installable::toApp(EvalState & state) auto outPath = cursor->getAttr(state.sOutPath)->getString(); auto outputName = cursor->getAttr(state.sOutputName)->getString(); auto name = cursor->getAttr(state.sName)->getString(); + auto aPname = cursor->maybeGetAttr("pname"); auto aMeta = cursor->maybeGetAttr("meta"); auto aMainProgram = aMeta ? aMeta->maybeGetAttr("mainProgram") : nullptr; auto mainProgram = aMainProgram ? aMainProgram->getString() + : aPname + ? aPname->getString() : DrvName(name).name; auto program = outPath + "/bin/" + mainProgram; return UnresolvedApp { App { diff --git a/src/nix/run.md b/src/nix/run.md index a76750376..697db9a96 100644 --- a/src/nix/run.md +++ b/src/nix/run.md @@ -44,9 +44,10 @@ program specified by the app definition. If *installable* evaluates to a derivation, it will try to execute the program `/bin/`, where *out* is the primary output store path of the derivation and *name* is the `meta.mainProgram` attribute -of the derivation if it exists, and otherwise the name part of the -value of the `name` attribute of the derivation (e.g. if `name` is set -to `hello-1.10`, it will run `$out/bin/hello`). +of the derivation if it exists, and otherwise the `pname` attribute of +the derivation or the name part of the value of the `name` attribute of +the derivation (e.g. if `name` is set to `hello-1.10`, it will run +`$out/bin/hello`). # Flake output attributes From 1f15441103caab1b41317a6107fc2560eb109a4a Mon Sep 17 00:00:00 2001 From: John Ericson Date: Tue, 30 Nov 2021 20:23:13 +0000 Subject: [PATCH 05/23] Tidy up the logging Use the macros more, so we properly skip work when the log level excludes. Also log the daemon operation number on the daemon side. --- src/libstore/daemon.cc | 4 +++- src/libstore/store-api.cc | 2 +- src/libutil/logging.hh | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index 2eb566080..58c567b05 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -951,7 +951,7 @@ void processConnection( Finally finally([&]() { _isInterrupted = false; - prevLogger->log(lvlDebug, fmt("%d operations", opCount)); + printMsgUsing(prevLogger, lvlDebug, "%d operations", opCount); }); if (GET_PROTOCOL_MINOR(clientVersion) >= 14 && readInt(from)) { @@ -984,6 +984,8 @@ void processConnection( break; } + printMsgUsing(prevLogger, lvlDebug, "received daemon op %d", op); + opCount++; try { diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc index 71350906e..aab4ce94c 100644 --- a/src/libstore/store-api.cc +++ b/src/libstore/store-api.cc @@ -1079,7 +1079,7 @@ std::map copyPaths( nrFailed++; if (!settings.keepGoing) throw e; - logger->log(lvlError, fmt("could not copy %s: %s", dstStore.printStorePath(storePath), e.what())); + printMsg(lvlError, "could not copy %s: %s", dstStore.printStorePath(storePath), e.what()); showProgress(); return; } diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index 96ad69790..ce9c3dfed 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -189,13 +189,14 @@ extern Verbosity verbosity; /* suppress msgs > this */ /* Print a string message if the current log level is at least the specified level. Note that this has to be implemented as a macro to ensure that the arguments are evaluated lazily. */ -#define printMsg(level, args...) \ +#define printMsgUsing(loggerParam, level, args...) \ do { \ auto __lvl = level; \ if (__lvl <= nix::verbosity) { \ - logger->log(__lvl, fmt(args)); \ + loggerParam->log(__lvl, fmt(args)); \ } \ } while (0) +#define printMsg(level, args...) printMsgUsing(logger, level, args) #define printError(args...) printMsg(lvlError, args) #define notice(args...) printMsg(lvlNotice, args) From 55e3a1108cb41801c92d3697620408d9d272c2d2 Mon Sep 17 00:00:00 2001 From: regnat Date: Thu, 9 Dec 2021 16:35:27 +0100 Subject: [PATCH 06/23] Properly take the last assignment in the REPL When a variable is assigned in the REPL, make sure to remove any possible reference to the old one so that we correctly pick the new one afterwards Fix #5706 --- src/nix/repl.cc | 2 ++ tests/repl.sh | 1 + 2 files changed, 3 insertions(+) diff --git a/src/nix/repl.cc b/src/nix/repl.cc index 42143871f..f453343f3 100644 --- a/src/nix/repl.cc +++ b/src/nix/repl.cc @@ -672,6 +672,8 @@ void NixRepl::addVarToScope(const Symbol & name, Value & v) { if (displ >= envSize) throw Error("environment full; cannot add more variables"); + if (auto oldVar = staticEnv.find(name); oldVar != staticEnv.vars.end()) + staticEnv.vars.erase(oldVar); staticEnv.vars.emplace_back(name, displ); staticEnv.sort(); env->values[displ++] = &v; diff --git a/tests/repl.sh b/tests/repl.sh index f592822bc..995db869c 100644 --- a/tests/repl.sh +++ b/tests/repl.sh @@ -1,6 +1,7 @@ source common.sh replCmds=" +simple = 1 simple = import ./simple.nix :b simple :log simple From 0bd93ed7478a827ea81e71dbce113cd7e073d8cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amon=20Stopin=C5=A1ek?= Date: Thu, 9 Dec 2021 16:44:24 +0000 Subject: [PATCH 07/23] Fix link to nixos channel The old link returned 404 errror. --- doc/manual/src/package-management/basic-package-mgmt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/manual/src/package-management/basic-package-mgmt.md b/doc/manual/src/package-management/basic-package-mgmt.md index 50c6d3c2d..5f1d7a89c 100644 --- a/doc/manual/src/package-management/basic-package-mgmt.md +++ b/doc/manual/src/package-management/basic-package-mgmt.md @@ -40,7 +40,7 @@ $ nix-channel --update > > On NixOS, you’re automatically subscribed to a NixOS channel > corresponding to your NixOS major release (e.g. -> ). A NixOS channel is identical +> ). A NixOS channel is identical > to the Nixpkgs channel, except that it contains only Linux binaries > and is updated only if a set of regression tests succeed. From 5d64c33fa534773cbebfec3eee59d7b0ac74e59c Mon Sep 17 00:00:00 2001 From: Tom Bereknyei Date: Thu, 9 Dec 2021 14:27:05 -0500 Subject: [PATCH 08/23] add pull_request_template.md --- .github/PULL_REQUEST_TEMPLATE/pull_request_template.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template.md diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 000000000..537aa0909 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,7 @@ +**Release Notes** +Please include relevant [release notes](https://github.com/NixOS/nix/blob/master/doc/manual/src/release-notes/rl-next.md) as needed. + + +**Testing** + +If this issue is a regression or something that should block release, please consider including a test either in the [testsuite](https://github.com/NixOS/nix/tree/master/tests) or as a [hydraJob]( https://github.com/NixOS/nix/blob/master/flake.nix#L396) so that it can be part of the [automatic checks](https://hydra.nixos.org/jobset/nix/master). From 4194b682500ee1e40b575e9729a8ddcbb6ac1518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janne=20He=C3=9F?= Date: Fri, 10 Dec 2021 12:58:12 +0100 Subject: [PATCH 09/23] doc: Fix command for distributed builds We also need to build impurely or the lookup will not work. --- doc/manual/src/advanced-topics/distributed-builds.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/manual/src/advanced-topics/distributed-builds.md b/doc/manual/src/advanced-topics/distributed-builds.md index 580b36736..c4c60db15 100644 --- a/doc/manual/src/advanced-topics/distributed-builds.md +++ b/doc/manual/src/advanced-topics/distributed-builds.md @@ -53,8 +53,8 @@ example, the following command allows you to build a derivation for $ uname Linux -$ nix build \ - '(with import { system = "x86_64-darwin"; }; runCommand "foo" {} "uname > $out")' \ +$ nix build --impure \ + --expr '(with import { system = "x86_64-darwin"; }; runCommand "foo" {} "uname > $out")' \ --builders 'ssh://mac x86_64-darwin' [1/0/1 built, 0.0 MiB DL] building foo on ssh://mac From 20b1290103f23e40614518291b8d4847e37fea05 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 10 Dec 2021 15:12:55 +0100 Subject: [PATCH 10/23] Ignore system.nfs4_acl Closes #1584. --- src/libstore/globals.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 2f9e8c6e8..433deaf0f 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -799,7 +799,7 @@ public: )"}; Setting ignoredAcls{ - this, {"security.selinux"}, "ignored-acls", + this, {"security.selinux", "system.nfs4_acl"}, "ignored-acls", R"( A list of ACLs that should be ignored, normally Nix attempts to remove all ACLs from files and directories in the Nix store, but From be1055f2cc8841954521bf30a6f886cf3c807a28 Mon Sep 17 00:00:00 2001 From: Yorick van Pelt Date: Fri, 10 Dec 2021 17:00:32 +0100 Subject: [PATCH 11/23] extract_archive: use copy_pathname instead of set_pathname. Libarchive documentation mentions that archive_entry_set_pathname expects us to keep the passed string alive, which we don't. --- src/libutil/tarfile.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libutil/tarfile.cc b/src/libutil/tarfile.cc index 50e691a3d..934b70162 100644 --- a/src/libutil/tarfile.cc +++ b/src/libutil/tarfile.cc @@ -93,7 +93,7 @@ static void extract_archive(TarArchive & archive, const Path & destDir) else archive.check(r); - archive_entry_set_pathname(entry, + archive_entry_copy_pathname(entry, (destDir + "/" + name).c_str()); archive.check(archive_read_extract(archive.archive, entry, flags)); From 0e0de90b35b61edcfae3030c150b9d7e42bf39fe Mon Sep 17 00:00:00 2001 From: Yorick van Pelt Date: Fri, 10 Dec 2021 17:03:51 +0100 Subject: [PATCH 12/23] extract_archive: fix "Hard-link target '...'" error Fixes #5741 --- src/libutil/tarfile.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libutil/tarfile.cc b/src/libutil/tarfile.cc index 934b70162..790bc943a 100644 --- a/src/libutil/tarfile.cc +++ b/src/libutil/tarfile.cc @@ -96,6 +96,13 @@ static void extract_archive(TarArchive & archive, const Path & destDir) archive_entry_copy_pathname(entry, (destDir + "/" + name).c_str()); + // Patch hardlink path + const char *original_hardlink = archive_entry_hardlink(entry); + if (original_hardlink) { + archive_entry_copy_hardlink(entry, + (destDir + "/" + original_hardlink).c_str()); + } + archive.check(archive_read_extract(archive.archive, entry, flags)); } From 33e96820d52dcfea387214f84ff2271959b3467b Mon Sep 17 00:00:00 2001 From: Yorick van Pelt Date: Sat, 11 Dec 2021 16:02:08 +0100 Subject: [PATCH 13/23] EvalCommand::getEvalState: use gc tracable allocator for EvalState --- src/libcmd/command.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libcmd/command.cc b/src/libcmd/command.cc index fd3edfc46..429cd32cc 100644 --- a/src/libcmd/command.cc +++ b/src/libcmd/command.cc @@ -73,8 +73,13 @@ ref EvalCommand::getEvalStore() ref EvalCommand::getEvalState() { - if (!evalState) - evalState = std::make_shared(searchPath, getEvalStore(), getStore()); + if (!evalState) evalState = +#if HAVE_BOEHMGC + std::allocate_shared(traceable_allocator(), +#else + std::make_shared( +#endif + searchPath, getEvalStore(), getStore()); return ref(evalState); } From 3f417c8d1c3fc05af16766f21f13f2ecc15192a0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 29 Nov 2021 12:42:01 +0100 Subject: [PATCH 14/23] Add release notes entry for #5149 --- doc/manual/src/release-notes/rl-next.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md index cf2da9aa8..61c189d22 100644 --- a/doc/manual/src/release-notes/rl-next.md +++ b/doc/manual/src/release-notes/rl-next.md @@ -1,5 +1,9 @@ # Release 2.5 (2021-XX-XX) +* The garbage collector no longer blocks new builds, so the message + `waiting for the big garbage collector lock...` is a thing of the + past. + * Binary cache stores now have a setting `compression-level`. * `nix develop` now has a flag `--unpack` to run `unpackPhase`. From f133001dc8c849053b8af9933902d11f274426bd Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Dec 2021 16:48:44 +0100 Subject: [PATCH 15/23] Move rl-next.md to rl-2.5.md --- doc/manual/src/SUMMARY.md.in | 1 + doc/manual/src/release-notes/rl-2.5.md | 16 ++++++++++++++++ doc/manual/src/release-notes/rl-next.md | 17 +---------------- 3 files changed, 18 insertions(+), 16 deletions(-) create mode 100644 doc/manual/src/release-notes/rl-2.5.md diff --git a/doc/manual/src/SUMMARY.md.in b/doc/manual/src/SUMMARY.md.in index 8d9b061ba..2876be52a 100644 --- a/doc/manual/src/SUMMARY.md.in +++ b/doc/manual/src/SUMMARY.md.in @@ -72,6 +72,7 @@ - [CLI guideline](contributing/cli-guideline.md) - [Release Notes](release-notes/release-notes.md) - [Release X.Y (202?-??-??)](release-notes/rl-next.md) + - [Release 2.5 (2021-12-13)](release-notes/rl-2.5.md) - [Release 2.4 (2021-11-01)](release-notes/rl-2.4.md) - [Release 2.3 (2019-09-04)](release-notes/rl-2.3.md) - [Release 2.2 (2019-01-11)](release-notes/rl-2.2.md) diff --git a/doc/manual/src/release-notes/rl-2.5.md b/doc/manual/src/release-notes/rl-2.5.md new file mode 100644 index 000000000..61c189d22 --- /dev/null +++ b/doc/manual/src/release-notes/rl-2.5.md @@ -0,0 +1,16 @@ +# Release 2.5 (2021-XX-XX) + +* The garbage collector no longer blocks new builds, so the message + `waiting for the big garbage collector lock...` is a thing of the + past. + +* Binary cache stores now have a setting `compression-level`. + +* `nix develop` now has a flag `--unpack` to run `unpackPhase`. + +* Lists can now be compared lexicographically using the `<` operator. + +* New built-in function: `builtins.groupBy`, with the same functionality as + Nixpkgs' `lib.groupBy`, but faster. + +* `nix repl` now has a `:log` command. diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md index 61c189d22..c869b5e2f 100644 --- a/doc/manual/src/release-notes/rl-next.md +++ b/doc/manual/src/release-notes/rl-next.md @@ -1,16 +1 @@ -# Release 2.5 (2021-XX-XX) - -* The garbage collector no longer blocks new builds, so the message - `waiting for the big garbage collector lock...` is a thing of the - past. - -* Binary cache stores now have a setting `compression-level`. - -* `nix develop` now has a flag `--unpack` to run `unpackPhase`. - -* Lists can now be compared lexicographically using the `<` operator. - -* New built-in function: `builtins.groupBy`, with the same functionality as - Nixpkgs' `lib.groupBy`, but faster. - -* `nix repl` now has a `:log` command. +# Release X.Y (202?-??-??) From 6d30f9e6fea7d451033653f8f167aef58f7f5347 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Dec 2021 17:16:46 +0100 Subject: [PATCH 16/23] Explicitly make GC roots client sockets blocking On macOS / BSD, these sockets inherit the non-blocking flag of the server soocket, which is not what we want. https://github.com/dotnet/runtime/issues/25069 https://bugs.python.org/issue7995 https://hydra.nixos.org/build/161439304 --- src/libstore/gc.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 7a414da6b..ee123d84e 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -535,6 +535,12 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) } }); + /* On macOS, accepted sockets inherit the + non-blocking flag from the server socket, so + explicitly make it blocking. */ + if (fcntl(fdServer.get(), F_SETFL, fcntl(fdServer.get(), F_GETFL) & ~O_NONBLOCK) == -1) + abort(); + while (true) { try { auto path = readLine(fdClient.get()); From 05fcc681ac07c4ea04b365e6b03a76f3e6c54c94 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Dec 2021 16:14:57 +0100 Subject: [PATCH 17/23] Retry on ECONNREFUSED https://hydra.nixos.org/build/161439235 --- src/libstore/gc.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index ee123d84e..fa68cd8f3 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -126,7 +126,17 @@ void LocalStore::addTempRoot(const StorePath & path) auto socketPath = stateDir.get() + gcSocketPath; debug("connecting to '%s'", socketPath); state->fdRootsSocket = createUnixDomainSocket(); - nix::connect(state->fdRootsSocket.get(), socketPath); + try { + nix::connect(state->fdRootsSocket.get(), socketPath); + } catch (SysError & e) { + /* The garbage collector may have exited, so we need to + restart. */ + if (e.errNo == ECONNREFUSED) { + debug("GC socket connection refused"); + state->fdRootsSocket.close(); + goto restart; + } + } } try { From df1edd143fcb2532e32bbcb28f774ced1402cda4 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Dec 2021 16:24:25 +0100 Subject: [PATCH 18/23] gc-non-blocking.sh: Don't hang indefinitely if the GC roots server crashes --- tests/gc-non-blocking.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/gc-non-blocking.sh b/tests/gc-non-blocking.sh index 8b21c6f1c..0d781485d 100644 --- a/tests/gc-non-blocking.sh +++ b/tests/gc-non-blocking.sh @@ -19,7 +19,7 @@ pid=$! sleep 2 -outPath=$(nix-build -o "$TEST_ROOT/result" -E " +outPath=$(nix-build --max-silent-time 60 -o "$TEST_ROOT/result" -E " with import ./config.nix; mkDerivation { name = \"non-blocking\"; From d17d46cfc2e38efb63565270a1fba7b03b37de16 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Dec 2021 17:12:32 +0100 Subject: [PATCH 19/23] More debug info --- src/libstore/gc.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index fa68cd8f3..e35199b3d 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -533,6 +533,8 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) AutoCloseFD fdClient = accept(fdServer.get(), nullptr, nullptr); if (!fdClient) continue; + debug("GC roots server accepted new client"); + /* Process the connection in a separate thread. */ auto fdClient_ = fdClient.get(); std::thread clientThread([&, fdClient = std::move(fdClient)]() { @@ -575,7 +577,10 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) } else printError("received garbage instead of a root from client"); writeFull(fdClient.get(), "1", false); - } catch (Error &) { break; } + } catch (Error & e) { + debug("reading GC root from client: %s", e.msg()); + break; + } } }); From 2567b74c66ed52f752578373d4ec81ac2f09d6f0 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Dec 2021 19:14:32 +0100 Subject: [PATCH 20/23] nix run: Tweak docs --- src/nix/run.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/nix/run.md b/src/nix/run.md index 697db9a96..cd3b978c0 100644 --- a/src/nix/run.md +++ b/src/nix/run.md @@ -43,11 +43,15 @@ program specified by the app definition. If *installable* evaluates to a derivation, it will try to execute the program `/bin/`, where *out* is the primary output store -path of the derivation and *name* is the `meta.mainProgram` attribute -of the derivation if it exists, and otherwise the `pname` attribute of -the derivation or the name part of the value of the `name` attribute of -the derivation (e.g. if `name` is set to `hello-1.10`, it will run -`$out/bin/hello`). +path of the derivation, and *name* is the first of the following that +exists: + +* The `meta.mainProgram` attribute of the derivation. +* The `pname` attribute of the derivation. +* The name part of the value of the `name` attribute of the derivation. + +For instance, if `name` is set to `hello-1.10`, `nix run` will run +`$out/bin/hello`. # Flake output attributes From e2e5f3a78f31e4e72170ebfe48cbbb082860cc24 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Dec 2021 19:37:30 +0100 Subject: [PATCH 21/23] Respect /etc/hosts https://hydra.nixos.org/build/161439329 --- src/libmain/shared.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 4404e0195..f605184bb 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -145,10 +145,10 @@ static void preloadNSS() { * * All other platforms are unaffected. */ - if (dlopen (LIBNSS_DNS_SO, RTLD_NOW) == NULL) { - printMsg(Verbosity::lvlWarn, fmt("Unable to load nss_dns backend")); - } - __nss_configure_lookup ("hosts", "dns"); + if (!dlopen(LIBNSS_DNS_SO, RTLD_NOW)) + warn("unable to load nss_dns backend"); + // FIXME: get hosts entry from nsswitch.conf. + __nss_configure_lookup("hosts", "files dns"); #endif }); } From 18cb094aab2e50c9b90e484592212bfce026b640 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Dec 2021 19:57:06 +0100 Subject: [PATCH 22/23] rl-2.5.md: Set date --- doc/manual/src/release-notes/rl-2.5.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/manual/src/release-notes/rl-2.5.md b/doc/manual/src/release-notes/rl-2.5.md index 61c189d22..dd6fd3b0f 100644 --- a/doc/manual/src/release-notes/rl-2.5.md +++ b/doc/manual/src/release-notes/rl-2.5.md @@ -1,4 +1,4 @@ -# Release 2.5 (2021-XX-XX) +# Release 2.5 (2021-12-13) * The garbage collector no longer blocks new builds, so the message `waiting for the big garbage collector lock...` is a thing of the From 46d86e06ba54dc708fa8fd7d0109845fa2ac402e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 13 Dec 2021 20:28:53 +0100 Subject: [PATCH 23/23] Simplify --- src/libstore/build/local-derivation-goal.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc index edfa46052..66d950b42 100644 --- a/src/libstore/build/local-derivation-goal.cc +++ b/src/libstore/build/local-derivation-goal.cc @@ -1779,15 +1779,14 @@ void LocalDerivationGoal::runChild() i686-linux build on an x86_64-linux machine. */ struct utsname utsbuf; uname(&utsbuf); - if (drv->platform == "i686-linux" && - (settings.thisSystem == "x86_64-linux" || - (!strcmp(utsbuf.sysname, "Linux") && !strcmp(utsbuf.machine, "x86_64")))) { + if ((drv->platform == "i686-linux" + && (settings.thisSystem == "x86_64-linux" + || (!strcmp(utsbuf.sysname, "Linux") && !strcmp(utsbuf.machine, "x86_64")))) + || drv->platform == "armv7l-linux" + || drv->platform == "armv6l-linux") + { if (personality(PER_LINUX32) == -1) - throw SysError("cannot set i686-linux personality"); - } - if (drv->platform == "armv7l-linux" || drv->platform == "armv6l-linux") { - if (personality(PER_LINUX32) == -1) - throw SysError("cannot set 32bit linux personality"); + throw SysError("cannot set 32-bit personality"); } /* Impersonate a Linux 2.6 machine to get some determinism in