diff options
author | jade <lix@jade.fyi> | 2024-05-30 02:33:05 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@lix-systems> | 2024-05-30 02:33:05 +0000 |
commit | 562ff516ab27b8e98490646dd30ac96e7e2c36bb (patch) | |
tree | 1798a20b33da0101bd91acf7da26c891f0cda620 /src/libutil/current-process.cc | |
parent | c71f21da3ac4d95ef9a42a26416ccee71639dbd6 (diff) | |
parent | a39ba22ff7112cd3984bbf28d8610d84dd525a0f (diff) |
Merge changes from topic "libutil-split" into main
* changes:
util.hh: Delete remaining file and clean up headers
util.hh: Move nativeSystem to local-derivation-goal.cc
util.hh: Move stuff to types.hh
util.cc: Delete remaining file
util.{hh,cc}: Move ignoreException to error.{hh,cc}
util.{hh,cc}: Split out namespaces.{hh,cc}
util.{hh,cc}: Split out users.{hh,cc}
util.{hh,cc}: Split out strings.{hh,cc}
util.{hh,cc}: Split out unix-domain-socket.{hh,cc}
util.{hh,cc}: Split out child.{hh,cc}
util.{hh,cc}: Split out current-process.{hh,cc}
util.{hh,cc}: Split out processes.{hh,cc}
util.{hh,cc}: Split out file-descriptor.{hh,cc}
util.{hh,cc}: Split out file-system.{hh,cc}
util.{hh,cc}: Split out terminal.{hh,cc}
util.{hh,cc}: Split out environment-variables.{hh,cc}
Diffstat (limited to 'src/libutil/current-process.cc')
-rw-r--r-- | src/libutil/current-process.cc | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/libutil/current-process.cc b/src/libutil/current-process.cc new file mode 100644 index 000000000..c64dd1e0d --- /dev/null +++ b/src/libutil/current-process.cc @@ -0,0 +1,111 @@ +#include "current-process.hh" +#include "error.hh" +#include "file-system.hh" +#include "logging.hh" +#include "namespaces.hh" +#include "signals.hh" +#include "strings.hh" + +#ifdef __APPLE__ +# include <mach-o/dyld.h> +#endif + +#if __linux__ +# include <sys/resource.h> +#endif + +#include <sys/mount.h> +#include <cgroup.hh> + +namespace nix { + +unsigned int getMaxCPU() +{ + #if __linux__ + try { + auto cgroupFS = getCgroupFS(); + if (!cgroupFS) return 0; + + auto cgroups = getCgroups("/proc/self/cgroup"); + auto cgroup = cgroups[""]; + if (cgroup == "") return 0; + + auto cpuFile = *cgroupFS + "/" + cgroup + "/cpu.max"; + + auto cpuMax = readFile(cpuFile); + auto cpuMaxParts = tokenizeString<std::vector<std::string>>(cpuMax, " \n"); + + if (cpuMaxParts.size() != 2) { + return 0; + } + + auto quota = cpuMaxParts[0]; + auto period = cpuMaxParts[1]; + if (quota != "max") + return std::ceil(std::stoi(quota) / std::stof(period)); + } catch (Error &) { ignoreException(lvlDebug); } + #endif + + return 0; +} + +rlim_t savedStackSize = 0; + +void setStackSize(rlim_t stackSize) +{ + struct rlimit limit; + if (getrlimit(RLIMIT_STACK, &limit) == 0 && limit.rlim_cur < stackSize) { + savedStackSize = limit.rlim_cur; + limit.rlim_cur = std::min(stackSize, limit.rlim_max); + if (setrlimit(RLIMIT_STACK, &limit) != 0) { + logger->log( + lvlError, + HintFmt( + "Failed to increase stack size from %1% to %2% (maximum allowed stack size: %3%): %4%", + savedStackSize, + stackSize, + limit.rlim_max, + std::strerror(errno) + ).str() + ); + } + } +} + +void restoreProcessContext(bool restoreMounts) +{ + restoreSignals(); + if (restoreMounts) { + restoreMountNamespace(); + } + + if (savedStackSize) { + struct rlimit limit; + if (getrlimit(RLIMIT_STACK, &limit) == 0) { + limit.rlim_cur = savedStackSize; + setrlimit(RLIMIT_STACK, &limit); + } + } +} + +std::optional<Path> getSelfExe() +{ + static auto cached = []() -> std::optional<Path> + { + #if __linux__ + return readLink("/proc/self/exe"); + #elif __APPLE__ + char buf[1024]; + uint32_t size = sizeof(buf); + if (_NSGetExecutablePath(buf, &size) == 0) + return buf; + else + return std::nullopt; + #else + return std::nullopt; + #endif + }(); + return cached; +} + +} |