diff options
author | Tom Hubrecht <github@mail.hubrecht.ovh> | 2024-05-28 13:36:02 +0200 |
---|---|---|
committer | Tom Hubrecht <github@mail.hubrecht.ovh> | 2024-05-29 11:01:34 +0200 |
commit | 2473e1253d37d4bbd3f7aad2ff269ad84747d527 (patch) | |
tree | d81cd79de634171914b978a265ae59ef91295f22 /src/libutil | |
parent | 9a52e4688ca265155817817f373938428f023966 (diff) |
util.{hh,cc}: Split out current-process.{hh,cc}
Change-Id: I77095b9d37e85310075bada7a076ccd482c28e47
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/current-process.cc | 109 | ||||
-rw-r--r-- | src/libutil/current-process.hh | 37 | ||||
-rw-r--r-- | src/libutil/meson.build | 2 | ||||
-rw-r--r-- | src/libutil/processes.cc | 1 | ||||
-rw-r--r-- | src/libutil/util.cc | 87 | ||||
-rw-r--r-- | src/libutil/util.hh | 26 |
6 files changed, 150 insertions, 112 deletions
diff --git a/src/libutil/current-process.cc b/src/libutil/current-process.cc new file mode 100644 index 000000000..826e25547 --- /dev/null +++ b/src/libutil/current-process.cc @@ -0,0 +1,109 @@ +#include "current-process.hh" +#include "file-system.hh" +#include "logging.hh" +#include "signals.hh" +#include "util.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; +} + +} diff --git a/src/libutil/current-process.hh b/src/libutil/current-process.hh new file mode 100644 index 000000000..8d5a2791d --- /dev/null +++ b/src/libutil/current-process.hh @@ -0,0 +1,37 @@ +#pragma once +///@file + +#include <optional> +#include <sys/resource.h> + +#include "types.hh" + +namespace nix { + +/** + * If cgroups are active, attempt to calculate the number of CPUs available. + * If cgroups are unavailable or if cpu.max is set to "max", return 0. + */ +unsigned int getMaxCPU(); + + +/** + * Change the stack size. + */ +void setStackSize(rlim_t stackSize); + + +/** + * Restore the original inherited Unix process context (such as signal + * masks, stack size). + + * See startSignalHandlerThread(), saveSignalMask(). + */ +void restoreProcessContext(bool restoreMounts = true); + +/** + * @return the path of the current executable. + */ +std::optional<Path> getSelfExe(); + +} diff --git a/src/libutil/meson.build b/src/libutil/meson.build index 34715b25e..ef4270066 100644 --- a/src/libutil/meson.build +++ b/src/libutil/meson.build @@ -6,6 +6,7 @@ libutil_sources = files( 'compression.cc', 'compute-levels.cc', 'config.cc', + 'current-process.cc', 'english.cc', 'environment-variables.cc', 'error.cc', @@ -56,6 +57,7 @@ libutil_headers = files( 'compute-levels.hh', 'config-impl.hh', 'config.hh', + 'current-process.hh', 'english.hh', 'environment-variables.hh', 'error.hh', diff --git a/src/libutil/processes.cc b/src/libutil/processes.cc index 8d1b119b0..8639a77f8 100644 --- a/src/libutil/processes.cc +++ b/src/libutil/processes.cc @@ -1,3 +1,4 @@ +#include "current-process.hh" #include "environment-variables.hh" #include "finally.hh" #include "logging.hh" diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 702db2afb..7f9413f8d 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1,5 +1,6 @@ #include "util.hh" #include "processes.hh" +#include "current-process.hh" #include "sync.hh" #include "finally.hh" @@ -148,59 +149,11 @@ Path createNixStateDir() } -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; -} ////////////////////////////////////////////////////////////////////// -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; -} ////////////////////////////////////////////////////////////////////// @@ -454,28 +407,6 @@ std::pair<std::string_view, std::string_view> getLine(std::string_view s) ////////////////////////////////////////////////////////////////////// -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() - ); - } - } -} #if __linux__ static AutoCloseFD fdSavedMountNamespace; @@ -528,22 +459,6 @@ void unshareFilesystem() #endif } -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); - } - } -} - AutoCloseFD createUnixDomainSocket() { AutoCloseFD fdSocket{socket(PF_UNIX, SOCK_STREAM diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 8d1900131..de5f0a2ee 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -72,11 +72,6 @@ std::vector<Path> getConfigDirs(); Path getDataDir(); /** - * @return the path of the current executable. - */ -std::optional<Path> getSelfExe(); - -/** * @return $XDG_STATE_HOME or $HOME/.local/state. * * @note Not to be confused with settings.nixStateDir. @@ -92,27 +87,6 @@ Path createNixStateDir(); /** - * If cgroups are active, attempt to calculate the number of CPUs available. - * If cgroups are unavailable or if cpu.max is set to "max", return 0. - */ -unsigned int getMaxCPU(); - - -/** - * Change the stack size. - */ -void setStackSize(rlim_t stackSize); - - -/** - * Restore the original inherited Unix process context (such as signal - * masks, stack size). - - * See startSignalHandlerThread(), saveSignalMask(). - */ -void restoreProcessContext(bool restoreMounts = true); - -/** * Save the current mount namespace. Ignored if called more than * once. */ |