aboutsummaryrefslogtreecommitdiff
path: root/src/libstore/build
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstore/build')
-rw-r--r--src/libstore/build/derivation-goal.cc18
-rw-r--r--src/libstore/build/derivation-goal.hh9
-rw-r--r--src/libstore/build/local-derivation-goal.cc30
-rw-r--r--src/libstore/build/local-derivation-goal.hh4
4 files changed, 30 insertions, 31 deletions
diff --git a/src/libstore/build/derivation-goal.cc b/src/libstore/build/derivation-goal.cc
index 17b6afbb2..cc445a0a4 100644
--- a/src/libstore/build/derivation-goal.cc
+++ b/src/libstore/build/derivation-goal.cc
@@ -119,6 +119,7 @@ std::string DerivationGoal::key()
void DerivationGoal::killChild()
{
hook.reset();
+ builderOutFD = nullptr;
}
@@ -814,6 +815,7 @@ void replaceValidPath(const Path & storePath, const Path & tmpPath)
int DerivationGoal::getChildStatus()
{
+ builderOutFD = nullptr;
return hook->pid.kill();
}
@@ -822,6 +824,7 @@ void DerivationGoal::closeReadPipes()
{
hook->builderOut.readSide.reset();
hook->fromHook.readSide.reset();
+ builderOutFD = nullptr;
}
@@ -1209,6 +1212,7 @@ HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
std::set<int> fds;
fds.insert(hook->fromHook.readSide.get());
fds.insert(hook->builderOut.readSide.get());
+ builderOutFD = &hook->builderOut.readSide;
worker.childStarted(shared_from_this(), fds, false, false);
return rpAccept;
@@ -1271,13 +1275,10 @@ void DerivationGoal::closeLogFile()
}
-bool DerivationGoal::isReadDesc(int fd)
-{
- return fd == hook->builderOut.readSide.get();
-}
-
Goal::WorkResult DerivationGoal::handleChildOutput(int fd, std::string_view data)
{
+ assert(builderOutFD);
+
auto tooMuchLogs = [&] {
killChild();
return done(
@@ -1287,9 +1288,7 @@ Goal::WorkResult DerivationGoal::handleChildOutput(int fd, std::string_view data
};
// local & `ssh://`-builds are dealt with here.
- auto isWrittenToLog = isReadDesc(fd);
- if (isWrittenToLog)
- {
+ if (fd == builderOutFD->get()) {
logSize += data.size();
if (settings.maxLogSize && logSize > settings.maxLogSize) {
return tooMuchLogs();
@@ -1307,6 +1306,7 @@ Goal::WorkResult DerivationGoal::handleChildOutput(int fd, std::string_view data
}
if (logSink) (*logSink)(data);
+ return StillAlive{};
}
if (hook && fd == hook->fromHook.readSide.get()) {
@@ -1317,7 +1317,7 @@ Goal::WorkResult DerivationGoal::handleChildOutput(int fd, std::string_view data
auto s = handleJSONLogMessage(*json, worker.act, hook->activities, true);
// ensure that logs from a builder using `ssh-ng://` as protocol
// are also available to `nix log`.
- if (s && !isWrittenToLog && logSink) {
+ if (s && logSink) {
const auto type = (*json)["type"];
const auto fields = (*json)["fields"];
if (type == resBuildLogLine) {
diff --git a/src/libstore/build/derivation-goal.hh b/src/libstore/build/derivation-goal.hh
index 250b437da..da935ceb5 100644
--- a/src/libstore/build/derivation-goal.hh
+++ b/src/libstore/build/derivation-goal.hh
@@ -187,6 +187,13 @@ struct DerivationGoal : public Goal
std::unique_ptr<HookInstance> hook;
/**
+ * Builder output is pulled from this file descriptor when not null.
+ * Owned by the derivation goal or subclass, must not be reset until
+ * the build has finished and no more output must be processed by us
+ */
+ AutoCloseFD * builderOutFD = nullptr;
+
+ /**
* The sort of derivation we are building.
*/
std::optional<DerivationType> derivationType;
@@ -290,8 +297,6 @@ struct DerivationGoal : public Goal
virtual void cleanupPostOutputsRegisteredModeCheck();
virtual void cleanupPostOutputsRegisteredModeNonCheck();
- virtual bool isReadDesc(int fd);
-
/**
* Callback used by the worker to write to the log.
*/
diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc
index 841d1f2f6..116fa0ae5 100644
--- a/src/libstore/build/local-derivation-goal.cc
+++ b/src/libstore/build/local-derivation-goal.cc
@@ -279,8 +279,10 @@ void LocalDerivationGoal::closeReadPipes()
{
if (hook) {
DerivationGoal::closeReadPipes();
- } else
- builderOut.close();
+ } else {
+ builderOutPTY.close();
+ builderOutFD = nullptr;
+ }
}
@@ -671,12 +673,13 @@ void LocalDerivationGoal::startBuilder()
Path logFile = openLogFile();
/* Create a pseudoterminal to get the output of the builder. */
- builderOut = AutoCloseFD{posix_openpt(O_RDWR | O_NOCTTY)};
- if (!builderOut)
+ builderOutPTY = AutoCloseFD{posix_openpt(O_RDWR | O_NOCTTY)};
+ if (!builderOutPTY)
throw SysError("opening pseudoterminal master");
+ builderOutFD = &builderOutPTY;
// FIXME: not thread-safe, use ptsname_r
- std::string slaveName = ptsname(builderOut.get());
+ std::string slaveName = ptsname(builderOutPTY.get());
if (buildUser) {
if (chmod(slaveName.c_str(), 0600))
@@ -687,12 +690,12 @@ void LocalDerivationGoal::startBuilder()
}
#if __APPLE__
else {
- if (grantpt(builderOut.get()))
+ if (grantpt(builderOutPTY.get()))
throw SysError("granting access to pseudoterminal slave");
}
#endif
- if (unlockpt(builderOut.get()))
+ if (unlockpt(builderOutPTY.get()))
throw SysError("unlocking pseudoterminal");
/* Open the slave side of the pseudoterminal and use it as stderr. */
@@ -723,14 +726,14 @@ void LocalDerivationGoal::startBuilder()
/* parent */
pid.setSeparatePG(true);
- worker.childStarted(shared_from_this(), {builderOut.get()}, true, true);
+ worker.childStarted(shared_from_this(), {builderOutPTY.get()}, true, true);
/* Check if setting up the build environment failed. */
std::vector<std::string> msgs;
while (true) {
std::string msg = [&]() {
try {
- return readLine(builderOut.get());
+ return readLine(builderOutPTY.get());
} catch (Error & e) {
auto status = pid.wait();
e.addTrace({}, "while waiting for the build environment for '%s' to initialize (%s, previous messages: %s)",
@@ -742,7 +745,7 @@ void LocalDerivationGoal::startBuilder()
}();
if (msg.substr(0, 1) == "\2") break;
if (msg.substr(0, 1) == "\1") {
- FdSource source(builderOut.get());
+ FdSource source(builderOutPTY.get());
auto ex = readError(source);
ex.addTrace({}, "while setting up the build environment");
throw ex;
@@ -2563,13 +2566,6 @@ void LocalDerivationGoal::deleteTmpDir(bool force)
}
-bool LocalDerivationGoal::isReadDesc(int fd)
-{
- return (hook && DerivationGoal::isReadDesc(fd)) ||
- (!hook && fd == builderOut.get());
-}
-
-
StorePath LocalDerivationGoal::makeFallbackPath(OutputNameView outputName)
{
return worker.store.makeStorePath(
diff --git a/src/libstore/build/local-derivation-goal.hh b/src/libstore/build/local-derivation-goal.hh
index 7617760a5..128e6fd36 100644
--- a/src/libstore/build/local-derivation-goal.hh
+++ b/src/libstore/build/local-derivation-goal.hh
@@ -40,7 +40,7 @@ struct LocalDerivationGoal : public DerivationGoal
* Master side of the pseudoterminal used for the builder's
* standard output/error.
*/
- AutoCloseFD builderOut;
+ AutoCloseFD builderOutPTY;
/**
* Pipe for synchronising updates to the builder namespaces.
@@ -285,8 +285,6 @@ struct LocalDerivationGoal : public DerivationGoal
void cleanupPostOutputsRegisteredModeCheck() override;
void cleanupPostOutputsRegisteredModeNonCheck() override;
- bool isReadDesc(int fd) override;
-
/**
* Delete the temporary directory, if we have one.
*/