forked from lix-project/lix
Destroy the cgroup prior to building
This commit is contained in:
parent
ca2f64bcda
commit
7bdcf43b40
|
@ -16,6 +16,7 @@
|
|||
#include "machines.hh"
|
||||
#include "daemon.hh"
|
||||
#include "worker-protocol.hh"
|
||||
#include "cgroup.hh"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
@ -2400,14 +2401,13 @@ void DerivationGoal::startBuilder()
|
|||
auto hostCgroup = canonPath("/sys/fs/cgroup/" + name + "/" + cgroup);
|
||||
|
||||
if (!pathExists(hostCgroup))
|
||||
throw Error("expected unified cgroup directory '%s'", hostCgroup);
|
||||
throw Error("expected cgroup directory '%s'", hostCgroup);
|
||||
|
||||
auto childCgroup = fmt("%s/nix-%d", hostCgroup, buildUser->getUID());
|
||||
|
||||
// FIXME: if the cgroup already exists, kill all processes
|
||||
// in it and destroy it.
|
||||
destroyCgroup(childCgroup);
|
||||
|
||||
if (mkdir(childCgroup.c_str(), 0755) == -1 && errno != EEXIST)
|
||||
if (mkdir(childCgroup.c_str(), 0755) == -1)
|
||||
throw SysError("creating cgroup '%s'", childCgroup);
|
||||
|
||||
chownToBuilder(childCgroup);
|
||||
|
|
49
src/libstore/cgroup.cc
Normal file
49
src/libstore/cgroup.cc
Normal file
|
@ -0,0 +1,49 @@
|
|||
#if __linux__
|
||||
|
||||
#include "cgroup.hh"
|
||||
#include "util.hh"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
namespace nix {
|
||||
|
||||
void destroyCgroup(const Path & cgroup)
|
||||
{
|
||||
for (auto & entry : readDirectory(cgroup)) {
|
||||
if (entry.type != DT_DIR) continue;
|
||||
destroyCgroup(cgroup + "/" + entry.name);
|
||||
}
|
||||
|
||||
int round = 1;
|
||||
|
||||
while (true) {
|
||||
auto pids = tokenizeString<std::vector<std::string>>(readFile(cgroup + "/cgroup.procs"));
|
||||
|
||||
if (pids.empty()) break;
|
||||
|
||||
if (round > 20)
|
||||
throw Error("cannot kill cgroup '%s'", cgroup);
|
||||
|
||||
for (auto & pid_s : pids) {
|
||||
pid_t pid;
|
||||
if (!string2Int(pid_s, pid)) throw Error("invalid pid '%s'", pid);
|
||||
// FIXME: pid wraparound
|
||||
if (kill(pid, SIGKILL) == -1 && errno != ESRCH)
|
||||
throw SysError("killing member %d of cgroup '%s'", pid, cgroup);
|
||||
}
|
||||
|
||||
auto sleep = std::chrono::milliseconds((int) std::pow(2.0, std::min(round, 10)));
|
||||
printError("waiting for %d ms for cgroup '%s' to become empty", sleep.count(), cgroup);
|
||||
std::this_thread::sleep_for(sleep);
|
||||
round++;
|
||||
}
|
||||
|
||||
if (rmdir(cgroup.c_str()) == -1)
|
||||
throw SysError("deleting cgroup '%s'", cgroup);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
13
src/libstore/cgroup.hh
Normal file
13
src/libstore/cgroup.hh
Normal file
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#if __linux__
|
||||
|
||||
#include "types.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
void destroyCgroup(const Path & cgroup);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue