mirror of
https://github.com/NixOS/nix.git
synced 2025-11-16 23:42:43 +01:00
Create DerivationBuilder::killChild
Then the derivation building goal doesn't need to snoop around as much.
This commit is contained in:
parent
49da508f46
commit
4388e3dcb5
3 changed files with 31 additions and 19 deletions
|
|
@ -84,22 +84,8 @@ void DerivationBuildingGoal::killChild()
|
||||||
hook.reset();
|
hook.reset();
|
||||||
#endif
|
#endif
|
||||||
#ifndef _WIN32 // TODO enable `DerivationBuilder` on Windows
|
#ifndef _WIN32 // TODO enable `DerivationBuilder` on Windows
|
||||||
if (builder && builder->pid != -1) {
|
if (builder && builder->killChild())
|
||||||
worker.childTerminated(this);
|
worker.childTerminated(this);
|
||||||
|
|
||||||
// FIXME: move this into DerivationBuilder.
|
|
||||||
|
|
||||||
/* If we're using a build user, then there is a tricky race
|
|
||||||
condition: if we kill the build user before the child has
|
|
||||||
done its setuid() to the build user uid, then it won't be
|
|
||||||
killed, and we'll potentially lock up in pid.wait(). So
|
|
||||||
also send a conventional kill to the child. */
|
|
||||||
::kill(-builder->pid, SIGKILL); /* ignore the result */
|
|
||||||
|
|
||||||
builder->killSandbox(true);
|
|
||||||
|
|
||||||
builder->pid.wait();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -193,10 +193,12 @@ struct DerivationBuilder : RestrictionContext
|
||||||
virtual SingleDrvOutputs unprepareBuild() = 0;
|
virtual SingleDrvOutputs unprepareBuild() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Kill any processes running under the build user UID or in the
|
* Forcibly kill the child process, if any.
|
||||||
* cgroup of the build.
|
*
|
||||||
|
* @returns whether the child was still alive and needed to be
|
||||||
|
* killed.
|
||||||
*/
|
*/
|
||||||
virtual void killSandbox(bool getStats) = 0;
|
virtual bool killChild() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef _WIN32 // TODO enable `DerivationBuilder` on Windows
|
#ifndef _WIN32 // TODO enable `DerivationBuilder` on Windows
|
||||||
|
|
|
||||||
|
|
@ -370,9 +370,15 @@ protected:
|
||||||
*/
|
*/
|
||||||
virtual void cleanupBuild(bool force);
|
virtual void cleanupBuild(bool force);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kill any processes running under the build user UID or in the
|
||||||
|
* cgroup of the build.
|
||||||
|
*/
|
||||||
|
virtual void killSandbox(bool getStats);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void killSandbox(bool getStats) override;
|
bool killChild() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
@ -435,6 +441,24 @@ void DerivationBuilderImpl::killSandbox(bool getStats)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DerivationBuilderImpl::killChild()
|
||||||
|
{
|
||||||
|
bool ret = pid != -1;
|
||||||
|
if (ret) {
|
||||||
|
/* If we're using a build user, then there is a tricky race
|
||||||
|
condition: if we kill the build user before the child has
|
||||||
|
done its setuid() to the build user uid, then it won't be
|
||||||
|
killed, and we'll potentially lock up in pid.wait(). So
|
||||||
|
also send a conventional kill to the child. */
|
||||||
|
::kill(-pid, SIGKILL); /* ignore the result */
|
||||||
|
|
||||||
|
killSandbox(true);
|
||||||
|
|
||||||
|
pid.wait();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
bool DerivationBuilderImpl::prepareBuild()
|
bool DerivationBuilderImpl::prepareBuild()
|
||||||
{
|
{
|
||||||
if (useBuildUsers()) {
|
if (useBuildUsers()) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue