Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MB-49632: Add functionality to get limits from linux cgroup
Use /proc/mounts to look up the various mount points for the cgroup v1 and v2 and use that information in order to search for the pid in the various cgroup.procs files stored on the system. Control groups V1 use a group per controller type (cpu, memory etc), whereas V2 use a single group. V1: /sys/fs/cgroup/cpu/groupname/cgroup.procs /cpu.cfs_period_us /cpu.cfs_quota_us /sys/fs/cgroup/memory/groupname/cgroup.procs /memory.usage_in_bytes /memory.limit_in_bytes etc V2: /sys/fs/cgroup/groupname/cgroup.procs /cpu.max /memory.current /memory.max Change-Id: I7ca7403092e3df2315c7538d66ce0191691ea175 Reviewed-on: https://review.couchbase.org/c/platform/+/165727 Tested-by: Build Bot <build@couchbase.com> Reviewed-by: Dave Rigby <daver@couchbase.com>
- Loading branch information
Showing
10 changed files
with
979 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
add_library(cgroup STATIC | ||
cgroup_private.cc | ||
cgroup.cc | ||
${Platform_SOURCE_DIR}/include/cgroup/cgroup.h | ||
cgroup_private.h) | ||
target_include_directories(cgroup SYSTEM PRIVATE ${BOOST_INCLUDE_DIR}) | ||
target_include_directories(cgroup SYSTEM PUBLIC ${Platform_SOURCE_DIR}/include) | ||
target_link_libraries(cgroup PRIVATE ${Boost_FILESYSTEM_LIBRARY}) | ||
set_property(TARGET cgroup PROPERTY POSITION_INDEPENDENT_CODE 1) | ||
cb_enable_unity_build(cgroup) | ||
cb_add_test_executable(cgroup_test cgroup_tests.cc) | ||
target_link_libraries(cgroup_test cgroup | ||
platform | ||
Folly::folly | ||
GTest::gtest | ||
GTest::gtest_main) | ||
add_test(cgroup_test cgroup_test) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* Copyright 2021-Present Couchbase, Inc. | ||
* | ||
* Use of this software is governed by the Business Source License included | ||
* in the file licenses/BSL-Couchbase.txt. As of the Change Date specified | ||
* in that file, in accordance with the Business Source License, use of this | ||
* software will be governed by the Apache License, Version 2.0, included in | ||
* the file licenses/APL2.txt. | ||
*/ | ||
|
||
#include "cgroup_private.h" | ||
|
||
#include <cgroup/cgroup.h> | ||
#include <sched.h> | ||
#include <unistd.h> | ||
#include <cstring> | ||
#include <stdexcept> | ||
#include <system_error> | ||
|
||
namespace cb::cgroup { | ||
|
||
size_t ControlGroup::get_available_cpu_count() { | ||
int num = get_available_cpu_count_from_environment(); | ||
if (num != 0) { | ||
return num; | ||
} | ||
|
||
num = get_available_cpu_count_from_quota(); | ||
if (num != 0) { | ||
return num; | ||
} | ||
|
||
// No quota set, check for cpu sets | ||
cpu_set_t set; | ||
if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) { | ||
return CPU_COUNT(&set); | ||
} | ||
|
||
auto ret = sysconf(_SC_NPROCESSORS_ONLN); | ||
if (ret == -1) { | ||
throw std::system_error( | ||
std::error_code(errno, std::system_category()), | ||
"cb::cgroup::get_available_cpu_count(): sysconf failed"); | ||
} | ||
|
||
return size_t(ret); | ||
} | ||
|
||
size_t ControlGroup::get_available_cpu_count_from_environment() { | ||
char* env = getenv("COUCHBASE_CPU_COUNT"); | ||
if (env == nullptr) { | ||
return 0; | ||
} | ||
std::size_t pos; | ||
|
||
// std::stoi allows for leading whitespace, so we should allow for | ||
// trailing whitespace as well | ||
auto count = std::stoi(env, &pos); | ||
if (count > 0 && pos == strlen(env)) { | ||
return count; | ||
} | ||
|
||
// there might be characters after the number... | ||
const char* c = env + pos; | ||
do { | ||
if (!std::isspace(*c)) { | ||
throw std::logic_error( | ||
"cb::cgroup::get_available_cpu_count: Invalid format. " | ||
"COUCHBASE_CPU_COUNT should be a number"); | ||
} | ||
c++; | ||
} while (*c); | ||
|
||
// the string had trailing spaces.. accept it anyway | ||
return count; | ||
} | ||
|
||
ControlGroup& ControlGroup::instance() { | ||
static auto instance = priv::make_control_group(); | ||
return *instance; | ||
} | ||
} // namespace cb::cgroup |
Oops, something went wrong.