libstore: downsize hook pipes
don't keep fds open we're not using. currently this does not cause any problems, but it does increase the size of our fd table needlessly and in the future, when we have proper async processing, having builderOut open in the daemon once the hook has been fully started is problematic Change-Id: I6e7fb773b280b042873103638d3e04272ca1e4fc
This commit is contained in:
parent
e513cd2beb
commit
5e9db09761
3 changed files with 29 additions and 25 deletions
|
@ -822,8 +822,8 @@ int DerivationGoal::getChildStatus()
|
||||||
|
|
||||||
void DerivationGoal::closeReadPipes()
|
void DerivationGoal::closeReadPipes()
|
||||||
{
|
{
|
||||||
hook->builderOut.readSide.reset();
|
hook->builderOut.reset();
|
||||||
hook->fromHook.readSide.reset();
|
hook->fromHook.reset();
|
||||||
builderOutFD = nullptr;
|
builderOutFD = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1135,7 +1135,7 @@ HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
|
||||||
while (true) {
|
while (true) {
|
||||||
auto s = [&]() {
|
auto s = [&]() {
|
||||||
try {
|
try {
|
||||||
return readLine(worker.hook.instance->fromHook.readSide.get());
|
return readLine(worker.hook.instance->fromHook.get());
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace({}, "while reading the response from the build hook");
|
e.addTrace({}, "while reading the response from the build hook");
|
||||||
throw;
|
throw;
|
||||||
|
@ -1171,7 +1171,7 @@ HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
|
||||||
if (e.errNo == EPIPE) {
|
if (e.errNo == EPIPE) {
|
||||||
printError(
|
printError(
|
||||||
"build hook died unexpectedly: %s",
|
"build hook died unexpectedly: %s",
|
||||||
chomp(drainFD(worker.hook.instance->fromHook.readSide.get())));
|
chomp(drainFD(worker.hook.instance->fromHook.get())));
|
||||||
worker.hook.instance.reset();
|
worker.hook.instance.reset();
|
||||||
return rpDecline;
|
return rpDecline;
|
||||||
} else
|
} else
|
||||||
|
@ -1181,7 +1181,7 @@ HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
|
||||||
hook = std::move(worker.hook.instance);
|
hook = std::move(worker.hook.instance);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
machineName = readLine(hook->fromHook.readSide.get());
|
machineName = readLine(hook->fromHook.get());
|
||||||
} catch (Error & e) {
|
} catch (Error & e) {
|
||||||
e.addTrace({}, "while reading the machine name from the build hook");
|
e.addTrace({}, "while reading the machine name from the build hook");
|
||||||
throw;
|
throw;
|
||||||
|
@ -1204,15 +1204,15 @@ HookReply DerivationGoal::tryBuildHook(bool inBuildSlot)
|
||||||
}
|
}
|
||||||
|
|
||||||
hook->sink = FdSink();
|
hook->sink = FdSink();
|
||||||
hook->toHook.writeSide.reset();
|
hook->toHook.reset();
|
||||||
|
|
||||||
/* Create the log file and pipe. */
|
/* Create the log file and pipe. */
|
||||||
Path logFile = openLogFile();
|
Path logFile = openLogFile();
|
||||||
|
|
||||||
std::set<int> fds;
|
std::set<int> fds;
|
||||||
fds.insert(hook->fromHook.readSide.get());
|
fds.insert(hook->fromHook.get());
|
||||||
fds.insert(hook->builderOut.readSide.get());
|
fds.insert(hook->builderOut.get());
|
||||||
builderOutFD = &hook->builderOut.readSide;
|
builderOutFD = &hook->builderOut;
|
||||||
worker.childStarted(shared_from_this(), fds, false);
|
worker.childStarted(shared_from_this(), fds, false);
|
||||||
|
|
||||||
return rpAccept;
|
return rpAccept;
|
||||||
|
@ -1309,7 +1309,7 @@ Goal::WorkResult DerivationGoal::handleChildOutput(int fd, std::string_view data
|
||||||
return StillAlive{};
|
return StillAlive{};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hook && fd == hook->fromHook.readSide.get()) {
|
if (hook && fd == hook->fromHook.get()) {
|
||||||
for (auto c : data)
|
for (auto c : data)
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
auto json = parseJSONMessage(currentHookLine);
|
auto json = parseJSONMessage(currentHookLine);
|
||||||
|
|
|
@ -26,18 +26,21 @@ HookInstance::HookInstance()
|
||||||
args.push_back(std::to_string(verbosity));
|
args.push_back(std::to_string(verbosity));
|
||||||
|
|
||||||
/* Create a pipe to get the output of the child. */
|
/* Create a pipe to get the output of the child. */
|
||||||
fromHook.create();
|
Pipe fromHook_;
|
||||||
|
fromHook_.create();
|
||||||
|
|
||||||
/* Create the communication pipes. */
|
/* Create the communication pipes. */
|
||||||
toHook.create();
|
Pipe toHook_;
|
||||||
|
toHook_.create();
|
||||||
|
|
||||||
/* Create a pipe to get the output of the builder. */
|
/* Create a pipe to get the output of the builder. */
|
||||||
builderOut.create();
|
Pipe builderOut_;
|
||||||
|
builderOut_.create();
|
||||||
|
|
||||||
/* Fork the hook. */
|
/* Fork the hook. */
|
||||||
pid = startProcess([&]() {
|
pid = startProcess([&]() {
|
||||||
|
|
||||||
if (dup2(fromHook.writeSide.get(), STDERR_FILENO) == -1)
|
if (dup2(fromHook_.writeSide.get(), STDERR_FILENO) == -1)
|
||||||
throw SysError("cannot pipe standard error into log file");
|
throw SysError("cannot pipe standard error into log file");
|
||||||
|
|
||||||
commonChildInit();
|
commonChildInit();
|
||||||
|
@ -45,16 +48,16 @@ HookInstance::HookInstance()
|
||||||
if (chdir("/") == -1) throw SysError("changing into /");
|
if (chdir("/") == -1) throw SysError("changing into /");
|
||||||
|
|
||||||
/* Dup the communication pipes. */
|
/* Dup the communication pipes. */
|
||||||
if (dup2(toHook.readSide.get(), STDIN_FILENO) == -1)
|
if (dup2(toHook_.readSide.get(), STDIN_FILENO) == -1)
|
||||||
throw SysError("dupping to-hook read side");
|
throw SysError("dupping to-hook read side");
|
||||||
|
|
||||||
/* Use fd 4 for the builder's stdout/stderr. */
|
/* Use fd 4 for the builder's stdout/stderr. */
|
||||||
if (dup2(builderOut.writeSide.get(), 4) == -1)
|
if (dup2(builderOut_.writeSide.get(), 4) == -1)
|
||||||
throw SysError("dupping builder's stdout/stderr");
|
throw SysError("dupping builder's stdout/stderr");
|
||||||
|
|
||||||
/* Hack: pass the read side of that fd to allow build-remote
|
/* Hack: pass the read side of that fd to allow build-remote
|
||||||
to read SSH error messages. */
|
to read SSH error messages. */
|
||||||
if (dup2(builderOut.readSide.get(), 5) == -1)
|
if (dup2(builderOut_.readSide.get(), 5) == -1)
|
||||||
throw SysError("dupping builder's stdout/stderr");
|
throw SysError("dupping builder's stdout/stderr");
|
||||||
|
|
||||||
execv(buildHook.c_str(), stringsToCharPtrs(args).data());
|
execv(buildHook.c_str(), stringsToCharPtrs(args).data());
|
||||||
|
@ -63,10 +66,11 @@ HookInstance::HookInstance()
|
||||||
});
|
});
|
||||||
|
|
||||||
pid.setSeparatePG(true);
|
pid.setSeparatePG(true);
|
||||||
fromHook.writeSide.reset();
|
fromHook = std::move(fromHook_.readSide);
|
||||||
toHook.readSide.reset();
|
toHook = std::move(toHook_.writeSide);
|
||||||
|
builderOut = std::move(builderOut_.readSide);
|
||||||
|
|
||||||
sink = FdSink(toHook.writeSide.get());
|
sink = FdSink(toHook.get());
|
||||||
std::map<std::string, Config::SettingInfo> settings;
|
std::map<std::string, Config::SettingInfo> settings;
|
||||||
globalConfig.getSettings(settings);
|
globalConfig.getSettings(settings);
|
||||||
for (auto & setting : settings)
|
for (auto & setting : settings)
|
||||||
|
@ -78,7 +82,7 @@ HookInstance::HookInstance()
|
||||||
HookInstance::~HookInstance()
|
HookInstance::~HookInstance()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
toHook.writeSide.reset();
|
toHook.reset();
|
||||||
if (pid) pid.kill();
|
if (pid) pid.kill();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
ignoreException();
|
ignoreException();
|
||||||
|
|
|
@ -10,19 +10,19 @@ namespace nix {
|
||||||
struct HookInstance
|
struct HookInstance
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Pipes for talking to the build hook.
|
* Pipe for talking to the build hook.
|
||||||
*/
|
*/
|
||||||
Pipe toHook;
|
AutoCloseFD toHook;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pipe for the hook's standard output/error.
|
* Pipe for the hook's standard output/error.
|
||||||
*/
|
*/
|
||||||
Pipe fromHook;
|
AutoCloseFD fromHook;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pipe for the builder's standard output/error.
|
* Pipe for the builder's standard output/error.
|
||||||
*/
|
*/
|
||||||
Pipe builderOut;
|
AutoCloseFD builderOut;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The process ID of the hook.
|
* The process ID of the hook.
|
||||||
|
|
Loading…
Reference in a new issue