mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 00:30:49 +00:00
Backport #66237 to 24.3: Fix detection of number of CPUs in containers
This commit is contained in:
parent
d9c08c4bbe
commit
cbab31ce7c
@ -3,7 +3,7 @@
|
|||||||
#include <base/defines.h>
|
#include <base/defines.h>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
bool cgroupsV2Enabled()
|
bool cgroupsV2Enabled()
|
||||||
@ -40,7 +40,7 @@ bool cgroupsV2MemoryControllerEnabled()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string cgroupV2OfProcess()
|
std::filesystem::path cgroupV2PathOfProcess()
|
||||||
{
|
{
|
||||||
#if defined(OS_LINUX)
|
#if defined(OS_LINUX)
|
||||||
chassert(cgroupsV2Enabled());
|
chassert(cgroupsV2Enabled());
|
||||||
@ -48,17 +48,18 @@ std::string cgroupV2OfProcess()
|
|||||||
/// A simpler way to get the membership is:
|
/// A simpler way to get the membership is:
|
||||||
std::ifstream cgroup_name_file("/proc/self/cgroup");
|
std::ifstream cgroup_name_file("/proc/self/cgroup");
|
||||||
if (!cgroup_name_file.is_open())
|
if (!cgroup_name_file.is_open())
|
||||||
return "";
|
return {};
|
||||||
/// With cgroups v2, there will be a *single* line with prefix "0::/"
|
/// With cgroups v2, there will be a *single* line with prefix "0::/"
|
||||||
/// (see https://docs.kernel.org/admin-guide/cgroup-v2.html)
|
/// (see https://docs.kernel.org/admin-guide/cgroup-v2.html)
|
||||||
std::string cgroup;
|
std::string cgroup;
|
||||||
std::getline(cgroup_name_file, cgroup);
|
std::getline(cgroup_name_file, cgroup);
|
||||||
static const std::string v2_prefix = "0::/";
|
static const std::string v2_prefix = "0::/";
|
||||||
if (!cgroup.starts_with(v2_prefix))
|
if (!cgroup.starts_with(v2_prefix))
|
||||||
return "";
|
return {};
|
||||||
cgroup = cgroup.substr(v2_prefix.length());
|
cgroup = cgroup.substr(v2_prefix.length());
|
||||||
return cgroup;
|
/// Note: The 'root' cgroup can have an empty cgroup name, this is valid
|
||||||
|
return default_cgroups_mount / cgroup;
|
||||||
#else
|
#else
|
||||||
return "";
|
return {};
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#if defined(OS_LINUX)
|
#if defined(OS_LINUX)
|
||||||
/// I think it is possible to mount the cgroups hierarchy somewhere else (e.g. when in containers).
|
/// I think it is possible to mount the cgroups hierarchy somewhere else (e.g. when in containers).
|
||||||
@ -16,7 +15,7 @@ bool cgroupsV2Enabled();
|
|||||||
/// Assumes that cgroupsV2Enabled() is enabled.
|
/// Assumes that cgroupsV2Enabled() is enabled.
|
||||||
bool cgroupsV2MemoryControllerEnabled();
|
bool cgroupsV2MemoryControllerEnabled();
|
||||||
|
|
||||||
/// Which cgroup does the process belong to?
|
/// Detects which cgroup v2 the process belongs to and returns the filesystem path to the cgroup.
|
||||||
/// Returns an empty string if the cgroup cannot be determined.
|
/// Returns an empty path the cgroup cannot be determined.
|
||||||
/// Assumes that cgroupsV2Enabled() is enabled.
|
/// Assumes that cgroupsV2Enabled() is enabled.
|
||||||
std::string cgroupV2OfProcess();
|
std::filesystem::path cgroupV2PathOfProcess();
|
||||||
|
@ -23,8 +23,9 @@ std::optional<uint64_t> getCgroupsV2MemoryLimit()
|
|||||||
if (!cgroupsV2MemoryControllerEnabled())
|
if (!cgroupsV2MemoryControllerEnabled())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
std::string cgroup = cgroupV2OfProcess();
|
std::filesystem::path current_cgroup = cgroupV2PathOfProcess();
|
||||||
auto current_cgroup = cgroup.empty() ? default_cgroups_mount : (default_cgroups_mount / cgroup);
|
if (current_cgroup.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
/// Open the bottom-most nested memory limit setting file. If there is no such file at the current
|
/// Open the bottom-most nested memory limit setting file. If there is no such file at the current
|
||||||
/// level, try again at the parent level as memory settings are inherited.
|
/// level, try again at the parent level as memory settings are inherited.
|
||||||
|
@ -125,8 +125,9 @@ std::optional<std::string> getCgroupsV2FileName()
|
|||||||
if (!cgroupsV2MemoryControllerEnabled())
|
if (!cgroupsV2MemoryControllerEnabled())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
String cgroup = cgroupV2OfProcess();
|
std::filesystem::path current_cgroup = cgroupV2PathOfProcess();
|
||||||
auto current_cgroup = cgroup.empty() ? default_cgroups_mount : (default_cgroups_mount / cgroup);
|
if (current_cgroup.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
/// Return the bottom-most nested current memory file. If there is no such file at the current
|
/// Return the bottom-most nested current memory file. If there is no such file at the current
|
||||||
/// level, try again at the parent level as memory settings are inherited.
|
/// level, try again at the parent level as memory settings are inherited.
|
||||||
|
@ -37,12 +37,12 @@ uint32_t getCGroupLimitedCPUCores(unsigned default_cpu_count)
|
|||||||
/// cgroupsv2
|
/// cgroupsv2
|
||||||
if (cgroupsV2Enabled())
|
if (cgroupsV2Enabled())
|
||||||
{
|
{
|
||||||
/// First, we identify the cgroup the process belongs
|
/// First, we identify the path of the cgroup the process belongs
|
||||||
std::string cgroup = cgroupV2OfProcess();
|
std::filesystem::path cgroup_path = cgroupV2PathOfProcess();
|
||||||
if (cgroup.empty())
|
if (cgroup_path.empty())
|
||||||
return default_cpu_count;
|
return default_cpu_count;
|
||||||
|
|
||||||
auto current_cgroup = cgroup.empty() ? default_cgroups_mount : (default_cgroups_mount / cgroup);
|
auto current_cgroup = cgroup_path;
|
||||||
|
|
||||||
// Looking for cpu.max in directories from the current cgroup to the top level
|
// Looking for cpu.max in directories from the current cgroup to the top level
|
||||||
// It does not stop on the first time since the child could have a greater value than parent
|
// It does not stop on the first time since the child could have a greater value than parent
|
||||||
@ -62,7 +62,7 @@ uint32_t getCGroupLimitedCPUCores(unsigned default_cpu_count)
|
|||||||
}
|
}
|
||||||
current_cgroup = current_cgroup.parent_path();
|
current_cgroup = current_cgroup.parent_path();
|
||||||
}
|
}
|
||||||
current_cgroup = default_cgroups_mount / cgroup;
|
current_cgroup = cgroup_path;
|
||||||
// Looking for cpuset.cpus.effective in directories from the current cgroup to the top level
|
// Looking for cpuset.cpus.effective in directories from the current cgroup to the top level
|
||||||
while (current_cgroup != default_cgroups_mount.parent_path())
|
while (current_cgroup != default_cgroups_mount.parent_path())
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user