mirror of
https://github.com/NixOS/nix
synced 2025-06-27 16:51:15 +02:00
Move cgroup support
This commit is contained in:
parent
b27e684ca5
commit
352ca238a9
3 changed files with 83 additions and 77 deletions
|
@ -32,10 +32,6 @@
|
|||
# include <sys/statvfs.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
# include "nix/util/cgroup.hh"
|
||||
#endif
|
||||
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include <iostream>
|
||||
|
@ -88,12 +84,6 @@ protected:
|
|||
*/
|
||||
std::unique_ptr<UserLock> buildUser;
|
||||
|
||||
/**
|
||||
* The cgroup of the builder, if any.
|
||||
*/
|
||||
// FIXME: move
|
||||
std::optional<Path> cgroup;
|
||||
|
||||
/**
|
||||
* The temporary directory used for the build.
|
||||
*/
|
||||
|
@ -236,6 +226,15 @@ protected:
|
|||
return topTmpDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that there are no processes running that conflict with
|
||||
* `buildUser`.
|
||||
*/
|
||||
virtual void prepareUser()
|
||||
{
|
||||
killSandbox(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by prepareBuild() to do any setup in the parent to
|
||||
* prepare for a sandboxed build.
|
||||
|
@ -422,19 +421,7 @@ static LocalStore & getLocalStore(Store & store)
|
|||
|
||||
void DerivationBuilderImpl::killSandbox(bool getStats)
|
||||
{
|
||||
if (cgroup) {
|
||||
#ifdef __linux__
|
||||
auto stats = destroyCgroup(*cgroup);
|
||||
if (getStats) {
|
||||
buildResult.cpuUser = stats.cpuUser;
|
||||
buildResult.cpuSystem = stats.cpuSystem;
|
||||
}
|
||||
#else
|
||||
unreachable();
|
||||
#endif
|
||||
}
|
||||
|
||||
else if (buildUser) {
|
||||
if (buildUser) {
|
||||
auto uid = buildUser->getUID();
|
||||
assert(uid != 0);
|
||||
killUser(uid);
|
||||
|
@ -693,60 +680,10 @@ static void handleChildException(bool sendException)
|
|||
|
||||
void DerivationBuilderImpl::startBuilder()
|
||||
{
|
||||
if ((buildUser && buildUser->getUIDCount() != 1)
|
||||
#ifdef __linux__
|
||||
|| settings.useCgroups
|
||||
#endif
|
||||
)
|
||||
{
|
||||
#ifdef __linux__
|
||||
experimentalFeatureSettings.require(Xp::Cgroups);
|
||||
|
||||
/* If we're running from the daemon, then this will return the
|
||||
root cgroup of the service. Otherwise, it will return the
|
||||
current cgroup. */
|
||||
auto rootCgroup = getRootCgroup();
|
||||
auto cgroupFS = getCgroupFS();
|
||||
if (!cgroupFS)
|
||||
throw Error("cannot determine the cgroups file system");
|
||||
auto rootCgroupPath = canonPath(*cgroupFS + "/" + rootCgroup);
|
||||
if (!pathExists(rootCgroupPath))
|
||||
throw Error("expected cgroup directory '%s'", rootCgroupPath);
|
||||
|
||||
static std::atomic<unsigned int> counter{0};
|
||||
|
||||
cgroup = buildUser
|
||||
? fmt("%s/nix-build-uid-%d", rootCgroupPath, buildUser->getUID())
|
||||
: fmt("%s/nix-build-pid-%d-%d", rootCgroupPath, getpid(), counter++);
|
||||
|
||||
debug("using cgroup '%s'", *cgroup);
|
||||
|
||||
/* When using a build user, record the cgroup we used for that
|
||||
user so that if we got interrupted previously, we can kill
|
||||
any left-over cgroup first. */
|
||||
if (buildUser) {
|
||||
auto cgroupsDir = settings.nixStateDir + "/cgroups";
|
||||
createDirs(cgroupsDir);
|
||||
|
||||
auto cgroupFile = fmt("%s/%d", cgroupsDir, buildUser->getUID());
|
||||
|
||||
if (pathExists(cgroupFile)) {
|
||||
auto prevCgroup = readFile(cgroupFile);
|
||||
destroyCgroup(prevCgroup);
|
||||
}
|
||||
|
||||
writeFile(cgroupFile, *cgroup);
|
||||
}
|
||||
|
||||
#else
|
||||
throw Error("cgroups are not supported on this platform");
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Make sure that no other processes are executing under the
|
||||
sandbox uids. This must be done before any chownToBuilder()
|
||||
calls. */
|
||||
killSandbox(false);
|
||||
prepareUser();
|
||||
|
||||
/* Right platform? */
|
||||
if (!drvOptions.canBuildLocally(store, drv)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue