forked from lix-project/lix
Simplify cgroup creation
This commit is contained in:
parent
7bdcf43b40
commit
570c443f56
|
@ -2375,50 +2375,30 @@ void DerivationGoal::startBuilder()
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
if (useChroot) {
|
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
|
// FIXME: do we want to use the parent cgroup? We should
|
||||||
// always use the same cgroup regardless of whether we're the
|
// always use the same cgroup regardless of whether we're the
|
||||||
// daemon or run from a user session via sudo.
|
// daemon or run from a user session via sudo.
|
||||||
std::string msg;
|
auto ourCgroups = getCgroups("/proc/self/cgroup");
|
||||||
std::vector<Path> cgroups;
|
auto systemdCgroup = ourCgroups["systemd"];
|
||||||
for (auto & line : tokenizeString<std::vector<std::string>>(readFile("/proc/self/cgroup"), "\n")) {
|
if (systemdCgroup == "")
|
||||||
static std::regex regex("([0-9]+):([^:]*):(.*)");
|
throw Error("'systemd' cgroup does not exist");
|
||||||
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
|
auto hostCgroup = canonPath("/sys/fs/cgroup/systemd/" + systemdCgroup);
|
||||||
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];
|
if (!pathExists(hostCgroup))
|
||||||
|
throw Error("expected cgroup directory '%s'", hostCgroup);
|
||||||
|
|
||||||
auto hostCgroup = canonPath("/sys/fs/cgroup/" + name + "/" + cgroup);
|
auto childCgroup = fmt("%s/nix-%d", hostCgroup, buildUser->getUID());
|
||||||
|
|
||||||
if (!pathExists(hostCgroup))
|
destroyCgroup(childCgroup);
|
||||||
throw Error("expected cgroup directory '%s'", hostCgroup);
|
|
||||||
|
|
||||||
auto childCgroup = fmt("%s/nix-%d", hostCgroup, buildUser->getUID());
|
if (mkdir(childCgroup.c_str(), 0755) == -1)
|
||||||
|
throw SysError("creating cgroup '%s'", childCgroup);
|
||||||
|
|
||||||
destroyCgroup(childCgroup);
|
chownToBuilder(childCgroup);
|
||||||
|
chownToBuilder(childCgroup + "/cgroup.procs");
|
||||||
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");
|
|
||||||
}
|
|
||||||
|
|
||||||
cgroups.push_back(childCgroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set up private namespaces for the build:
|
/* Set up private namespaces for the build:
|
||||||
|
|
||||||
|
@ -2545,8 +2525,7 @@ void DerivationGoal::startBuilder()
|
||||||
throw SysError("getting sandbox mount namespace");
|
throw SysError("getting sandbox mount namespace");
|
||||||
|
|
||||||
/* Move the child into its own cgroup. */
|
/* 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. */
|
/* Signal the builder that we've updated its user namespace. */
|
||||||
writeFull(userNamespaceSync.writeSide.get(), "1");
|
writeFull(userNamespaceSync.writeSide.get(), "1");
|
||||||
|
|
|
@ -9,6 +9,23 @@
|
||||||
|
|
||||||
namespace nix {
|
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)
|
void destroyCgroup(const Path & cgroup)
|
||||||
{
|
{
|
||||||
for (auto & entry : readDirectory(cgroup)) {
|
for (auto & entry : readDirectory(cgroup)) {
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
std::map<std::string, std::string> getCgroups(const Path & cgroupFile);
|
||||||
|
|
||||||
void destroyCgroup(const Path & cgroup);
|
void destroyCgroup(const Path & cgroup);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue