-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
allow setting cgroup memory limits via both nix.conf and pre-build hooks #7388
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -154,6 +154,7 @@ void LocalDerivationGoal::killSandbox(bool getStats) | |
| if (getStats) { | ||
| buildResult.cpuUser = stats.cpuUser; | ||
| buildResult.cpuSystem = stats.cpuSystem; | ||
| buildResult.memoryHigh = stats.memoryHigh; | ||
| } | ||
| #else | ||
| abort(); | ||
|
|
@@ -415,6 +416,7 @@ void LocalDerivationGoal::startBuilder() | |
| throw Error("cannot determine cgroup name from /proc/self/cgroup"); | ||
|
|
||
| auto ourCgroupPath = canonPath("/sys/fs/cgroup/" + ourCgroup); | ||
| ourCgroupPath = dirOf(ourCgroupPath); | ||
|
|
||
| if (!pathExists(ourCgroupPath)) | ||
| throw Error("expected cgroup directory '%s'", ourCgroupPath); | ||
|
|
@@ -720,6 +722,15 @@ void LocalDerivationGoal::startBuilder() | |
| chownToBuilder(*cgroup); | ||
| chownToBuilder(*cgroup + "/cgroup.procs"); | ||
| chownToBuilder(*cgroup + "/cgroup.threads"); | ||
| auto parentCgroup = dirOf(*cgroup); | ||
| writeFile(parentCgroup + "/cgroup.subtree_control", "+memory"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will fail if the cgroup does not have It's not clear what the best solution is, but some options:
Whatever the solution, Nix shouldn't fail if writing to |
||
| writeFile(*cgroup + "/memory.oom.group", "1"); | ||
| if (settings.memoryHigh) { | ||
| writeFile(*cgroup + "/memory.high", fmt("%d", settings.memoryHigh)); | ||
| } | ||
| if (settings.memoryMax) { | ||
| writeFile(*cgroup + "/memory.max", fmt("%d", settings.memoryMax)); | ||
| } | ||
| //chownToBuilder(*cgroup + "/cgroup.subtree_control"); | ||
| } | ||
|
|
||
|
|
@@ -751,7 +762,14 @@ void LocalDerivationGoal::startBuilder() | |
| stExtraChrootDirs | ||
| }; | ||
| auto state = stBegin; | ||
| auto lines = runProgram(settings.preBuildHook, false, args); | ||
| auto hookEnv = getEnv(); | ||
| if (cgroup) hookEnv["NIX_CGROUP"] = *cgroup; | ||
| auto res = runProgram(RunOptions {.program = settings.preBuildHook, .searchPath = false, .args = args, .environment = hookEnv, .input = {} }); | ||
|
|
||
| if (!statusOk(res.first)) | ||
| throw ExecError(res.first, "program '%1%' %2%", settings.preBuildHook, statusToString(res.first)); | ||
|
|
||
| auto lines = res.second; | ||
| auto lastPos = std::string::size_type{0}; | ||
| for (auto nlPos = lines.find('\n'); nlPos != std::string::npos; | ||
| nlPos = lines.find('\n', lastPos)) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -113,6 +113,11 @@ static CgroupStats destroyCgroup(const Path & cgroup, bool returnStats) | |
| } | ||
| } | ||
|
|
||
| auto memoryhighPath = cgroup + "/memory.high"; | ||
| if (pathExists(memoryhighPath)) { | ||
| stats.memoryHigh = string2Int<uint64_t>(trim(readFile(memoryhighPath))); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Indentation is off here. |
||
| } | ||
| debug("memory events %s", readFile(cgroup + "/memory.events")); | ||
| } | ||
|
|
||
| if (rmdir(cgroup.c_str()) == -1) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -313,6 +313,22 @@ public: | |
| `uid-range` system feature. | ||
| )" | ||
| }; | ||
|
|
||
| Setting<uint64_t> memoryHigh{ | ||
| this, 0, "memory-high", | ||
| R"( | ||
| sets the cgroup memory.high limit, causing the build to throttle if exceeded | ||
| depends on use-cgroups=true | ||
|
Comment on lines
+320
to
+321
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs proper capitalization/spelling/Markdown formatting. |
||
| )" | ||
| }; | ||
|
|
||
| Setting<uint64_t> memoryMax{ | ||
| this, 0, "memory-max", | ||
| R"( | ||
| sets the cgroup memory.max limit, causing the build to be killed if exceeded | ||
| depends on use-cgroups=true | ||
|
Comment on lines
+320
to
+329
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am missing some documentation here in what relation to each other you should set memory-high and memory-max. I would assume something like memory-high 3GB and memory-max 4GB?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. depends on how much a specific derivation needs, the goal is to keep track of how much memory each derivation is using, and not schedule too many on one machine |
||
| )" | ||
| }; | ||
| #endif | ||
|
|
||
| Setting<bool> impersonateLinux26{this, false, "impersonate-linux-26", | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is very confusing naming. Doing
dirOfmeans it isn't our cgroup, but the parent's. And it's not clear that we want to be putting stuff in the parent cgroup, since it causes nix to break out of whatever resource controls are in place for its own cgroup. It especially wouldn't be nice if Nix builds escape fromsystem.slice/nix-daemon.service.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i had modified things so the daemon runs in
system.slice/nix-daemon.service/actual-daemonthe problem is that you cant certain things on
system.slice/nix-daemon.serviceif it contains any process, everything must be in a child c-groupi'm not sure what the best solution to that is, and this currently needs an extra script around
nix-daemonto move it to a child cgroup