Skip to content

Commit

Permalink
Simplify cgroup creation
Browse files Browse the repository at this point in the history
  • Loading branch information
edolstra committed May 18, 2020
1 parent fa49bfa commit 192e3ef
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 42 deletions.
63 changes: 21 additions & 42 deletions src/libstore/build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2347,50 +2347,30 @@ void DerivationGoal::startBuilder()

#if __linux__
if (useChroot) {
/* Create a cgroup. */
/* Create a systemd cgroup since that's the minimum required
by systemd-nspawn. */
// FIXME: do we want to use the parent cgroup? We should
// always use the same cgroup regardless of whether we're the
// daemon or run from a user session via sudo.
std::string msg;
std::vector<Path> cgroups;
for (auto & line : tokenizeString<std::vector<std::string>>(readFile("/proc/self/cgroup"), "\n")) {
static std::regex regex("([0-9]+):([^:]*):(.*)");
std::smatch match;
if (!std::regex_match(line, match, regex))
throw Error("invalid line '%s' in '/proc/self/cgroup'", line);

/* We only create a systemd cgroup, since that's enough
for running systemd-nspawn. */
std::string name;
if (match[2] == "name=systemd")
name = "systemd";
//else if (match[2] == "")
// name = "unified";
else continue;

std::string cgroup = match[3];

auto hostCgroup = canonPath("/sys/fs/cgroup/" + name + "/" + cgroup);

if (!pathExists(hostCgroup))
throw Error("expected cgroup directory '%s'", hostCgroup);

auto childCgroup = fmt("%s/nix-%d", hostCgroup, buildUser->getUID());

destroyCgroup(childCgroup);

if (mkdir(childCgroup.c_str(), 0755) == -1)
throw SysError("creating cgroup '%s'", childCgroup);

chownToBuilder(childCgroup);
chownToBuilder(childCgroup + "/cgroup.procs");
if (name == "unified") {
chownToBuilder(childCgroup + "/cgroup.threads");
chownToBuilder(childCgroup + "/cgroup.subtree_control");
}
auto ourCgroups = getCgroups("/proc/self/cgroup");
auto systemdCgroup = ourCgroups["systemd"];
if (systemdCgroup == "")
throw Error("'systemd' cgroup does not exist");

cgroups.push_back(childCgroup);
}
auto hostCgroup = canonPath("/sys/fs/cgroup/systemd/" + systemdCgroup);

if (!pathExists(hostCgroup))
throw Error("expected cgroup directory '%s'", hostCgroup);

auto childCgroup = fmt("%s/nix-%d", hostCgroup, buildUser->getUID());

destroyCgroup(childCgroup);

if (mkdir(childCgroup.c_str(), 0755) == -1)
throw SysError("creating cgroup '%s'", childCgroup);

chownToBuilder(childCgroup);
chownToBuilder(childCgroup + "/cgroup.procs");

/* Set up private namespaces for the build:
Expand Down Expand Up @@ -2517,8 +2497,7 @@ void DerivationGoal::startBuilder()
throw SysError("getting sandbox mount namespace");

/* Move the child into its own cgroup. */
for (auto & childCgroup : cgroups)
writeFile(childCgroup + "/cgroup.procs", fmt("%d", (pid_t) pid));
writeFile(childCgroup + "/cgroup.procs", fmt("%d", (pid_t) pid));

/* Signal the builder that we've updated its user namespace. */
writeFull(userNamespaceSync.writeSide.get(), "1");
Expand Down
17 changes: 17 additions & 0 deletions src/libstore/cgroup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@

namespace nix {

std::map<std::string, std::string> getCgroups(const Path & cgroupFile)
{
std::map<std::string, std::string> cgroups;

for (auto & line : tokenizeString<std::vector<std::string>>(readFile(cgroupFile), "\n")) {
static std::regex regex("([0-9]+):([^:]*):(.*)");
std::smatch match;
if (!std::regex_match(line, match, regex))
throw Error("invalid line '%s' in '%s'", line, cgroupFile);

std::string name = hasPrefix(match[2], "name=") ? std::string(match[2], 5) : match[2];
cgroups.insert_or_assign(name, match[3]);
}

return cgroups;
}

void destroyCgroup(const Path & cgroup)
{
for (auto & entry : readDirectory(cgroup)) {
Expand Down
2 changes: 2 additions & 0 deletions src/libstore/cgroup.hh
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

namespace nix {

std::map<std::string, std::string> getCgroups(const Path & cgroupFile);

void destroyCgroup(const Path & cgroup);

}
Expand Down

0 comments on commit 192e3ef

Please sign in to comment.