Skip to content

Commit

Permalink
2
Browse files Browse the repository at this point in the history
  • Loading branch information
xinyiZzz committed Aug 13, 2024
1 parent 2e8c877 commit fe0e303
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 73 deletions.
36 changes: 0 additions & 36 deletions be/src/agent/cgroup_cpu_ctl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,40 +242,4 @@ Status CgroupV1CpuCtl::delete_unused_cgroup_path(std::set<uint64_t>& used_wg_ids
return Status::OK();
}

Status CgroupV1CpuCtl::find_cgroup_cpu_limit(float* cpu_count) {
if (!CGroupUtil::cgroupsv1_enable()) {
return Status::InvalidArgument("cgroup is not enabled!");
}
int64_t quota;
int64_t period;
std::string cgroup_path;
if (!CGroupUtil::find_abs_cgroupv1_path("cpu", &cgroup_path).ok()) {
RETURN_IF_ERROR(CGroupUtil::find_abs_cgroupv1_path("cpuacct", &cgroup_path));
}
std::filesystem::path cfs_quota_filename = cgroup_path + "/cpu.cfs_quota_us";
RETURN_IF_ERROR(CGroupUtil::read_int_line_from_cgroup_file(cfs_quota_filename, &quota));
if (quota <= 0) {
*cpu_count = -1;
return Status::OK();
}
std::filesystem::path cfs_period_filename = cgroup_path + "/cpu.cfs_period_us";
RETURN_IF_ERROR(CGroupUtil::read_int_line_from_cgroup_file(cfs_period_filename, &period));
if (quota <= period) {
return Status::InvalidArgument("quota <= period");
}
*cpu_count = float(quota) / float(period);
if (*cpu_count >= FLT_MAX) {
return Status::InvalidArgument("unknown");
}
return Status::OK();
}

std::string CgroupV1CpuCtl::debug_string() {
float cpu_limit;
auto cpu_limit_st = find_cgroup_cpu_limit(&cpu_limit);
return fmt::format("Process CGroup Memory Info: memory limit: {}, memory usage: {}",
cpu_limit_st.ok() ? (cpu_limit > 0 ? std::to_string(cpu_limit) : "unlimited")
: cpu_limit_st.to_string());
}

} // namespace doris
6 changes: 0 additions & 6 deletions be/src/agent/cgroup_cpu_ctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,6 @@ class CgroupV1CpuCtl : public CgroupCpuCtl {

Status delete_unused_cgroup_path(std::set<uint64_t>& used_wg_ids) override;

// Determines the CGroup cpu cores limit from the current processes' cgroup.
static Status find_cgroup_cpu_limit(float* cpu_count);

// Returns a human-readable string with information about CGroups.
static std::string debug_string();

private:
std::string _cgroup_v1_cpu_query_path;
std::string _cgroup_v1_cpu_tg_path; // workload group path
Expand Down
35 changes: 19 additions & 16 deletions be/src/common/cgroup_memory_ctl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,17 @@ bool cgroupsv2_memory_controller_enabled() {
#endif
}

struct CgroupsV1Reader : CGroupUtil::ICgroupsReader {
struct CgroupsV1Reader : CGroupMemoryCtl::ICgroupsReader {
explicit CgroupsV1Reader(std::filesystem::path mount_file_dir)
: _mount_file_dir(std::move(mount_file_dir)) {}

uint64_t read_memory_limit() override {
int64_t value;
auto st = CGroupUtil::read_int_line_from_cgroup_file(
(_mount_file_dir / "memory.limit_in_bytes"), &value);
if (st.ok()) {
if (!st.ok()) {
throw doris::Exception(doris::ErrorCode::END_OF_FILE,
"Cannot read cgroupv1 memory.limit_in_bytes");
"Cannot read cgroupv1 memory.limit_in_bytes, " + st.to_string());
}
return value;
}
Expand All @@ -79,18 +79,19 @@ struct CgroupsV1Reader : CGroupUtil::ICgroupsReader {
std::filesystem::path _mount_file_dir;
};

struct CgroupsV2Reader : CGroupUtil::ICgroupsReader {
struct CgroupsV2Reader : CGroupMemoryCtl::ICgroupsReader {
explicit CgroupsV2Reader(std::filesystem::path mount_file_dir)
: _mount_file_dir(std::move(mount_file_dir)) {}

uint64_t read_memory_limit() override {
// int64_t value;
// auto st = CGroupUtil::read_int_line_from_cgroup_file((_mount_file_dir / "memory.limit_in_bytes"), &value);
// if (st.ok()) {
// throw doris::Exception(doris::ErrorCode::END_OF_FILE, "Cannot read cgroupv1 memory.limit_in_bytes");
// }
// return value;
return 0;
int64_t value;
auto st = CGroupUtil::read_int_line_from_cgroup_file((_mount_file_dir / "memory.max"),
&value);
if (!st.ok()) {
throw doris::Exception(doris::ErrorCode::END_OF_FILE,
"Cannot read cgroupv2 memory.max, " + st.to_string());
}
return value;
}

uint64_t read_memory_usage() override {
Expand All @@ -99,9 +100,9 @@ struct CgroupsV2Reader : CGroupUtil::ICgroupsReader {
// the reason why we subtract it described here: https://github.com/ClickHouse/ClickHouse/issues/64652#issuecomment-2149630667
auto st = CGroupUtil::read_int_line_from_cgroup_file((_mount_file_dir / "memory.current"),
&mem_usage);
if (st.ok()) {
if (!st.ok()) {
throw doris::Exception(doris::ErrorCode::END_OF_FILE,
"Cannot read cgroupv2 memory.current");
"Cannot read cgroupv2 memory.current, " + st.to_string());
}
std::unordered_map<std::string, int64_t> metrics_map;
CGroupUtil::read_int_metric_from_cgroup_file((_mount_file_dir / "memory.stat"),
Expand Down Expand Up @@ -135,7 +136,7 @@ std::pair<std::string, CGroupUtil::CgroupsVersion> get_cgroups_path() {
"Cannot find cgroups v1 or v2 current memory file");
}

std::shared_ptr<CGroupUtil::ICgroupsReader> get_cgroups_reader() {
std::shared_ptr<CGroupMemoryCtl::ICgroupsReader> get_cgroups_reader() {
const auto [cgroup_path, version] = get_cgroups_path();

if (version == CGroupUtil::CgroupsVersion::V2) {
Expand All @@ -150,7 +151,8 @@ Status CGroupMemoryCtl::find_cgroup_mem_limit(int64_t* bytes) {
*bytes = get_cgroups_reader()->read_memory_limit();
return Status::OK();
} catch (const doris::Exception& e) {
return Status::IOError(e.to_string());
LOG(WARNING) << "Cgroup find_cgroup_mem_limit failed, " << e.to_string();
return Status::EndOfFile(e.to_string());
}
}

Expand All @@ -159,7 +161,8 @@ Status CGroupMemoryCtl::find_cgroup_mem_usage(int64_t* bytes) {
*bytes = get_cgroups_reader()->read_memory_usage();
return Status::OK();
} catch (const doris::Exception& e) {
return Status::IOError(e.to_string());
LOG(WARNING) << "Cgroup find_cgroup_mem_usage failed, " << e.to_string();
return Status::EndOfFile(e.to_string());
}
}

Expand Down
9 changes: 9 additions & 0 deletions be/src/common/cgroup_memory_ctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ namespace doris {

class CGroupMemoryCtl {
public:
// Inherited by cgroup v1 and v2
struct ICgroupsReader {
virtual ~ICgroupsReader() = default;

virtual uint64_t read_memory_limit() = 0;

virtual uint64_t read_memory_usage() = 0;
};

// Determines the CGroup memory limit from the current processes' cgroup.
// If the limit is more than INT64_MAX, INT64_MAX is returned (since that is
// effectively unlimited anyway). Does not take into account memory limits
Expand Down
12 changes: 6 additions & 6 deletions be/src/util/cgroup_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ Status CGroupUtil::find_global_cgroupv1(const string& subsystem, string* path) {
string line;
while (true) {
if (proc_cgroups.fail()) {
return Status::IOError("Error reading /proc/self/cgroup: {}", get_str_err_msg());
return Status::EndOfFile("Error reading /proc/self/cgroup: {}", get_str_err_msg());
} else if (proc_cgroups.peek() == std::ifstream::traits_type::eof()) {
return Status::NotFound("Could not find subsystem {} in /proc/self/cgroup", subsystem);
return Status::EndOfFile("Could not find subsystem {} in /proc/self/cgroup", subsystem);
}
// The line format looks like this:
// 4:memory:/user.slice
Expand Down Expand Up @@ -102,10 +102,10 @@ Status CGroupUtil::find_cgroupv1_mounts(const string& subsystem, pair<string, st
string line;
while (true) {
if (mountinfo.fail() || mountinfo.bad()) {
return Status::IOError("Error reading /proc/self/mountinfo: {}", get_str_err_msg());
return Status::EndOfFile("Error reading /proc/self/mountinfo: {}", get_str_err_msg());
} else if (mountinfo.eof()) {
return Status::NotFound("Could not find subsystem {} in /proc/self/mountinfo",
subsystem);
return Status::EndOfFile("Could not find subsystem {} in /proc/self/mountinfo",
subsystem);
}
// The relevant lines look like below (see proc manpage for full documentation). The
// first example is running outside of a container, the second example is running
Expand Down Expand Up @@ -214,7 +214,7 @@ Status CGroupUtil::read_int_line_from_cgroup_file(const std::filesystem::path& f
string line;
getline(file_stream, line);
if (file_stream.fail() || file_stream.bad()) {
return Status::IOError("Error reading {}: {}", file_path.string(), get_str_err_msg());
return Status::EndOfFile("Error reading {}: {}", file_path.string(), get_str_err_msg());
}
StringParser::ParseResult pr;
// Parse into an int64_t If it overflows, returning the max value of int64_t is ok because that
Expand Down
15 changes: 6 additions & 9 deletions be/src/util/cgroup_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,6 @@ class CGroupUtil {
public:
enum class CgroupsVersion : uint8_t { V1, V2 };

// Inherited by cgroup v1 and v2
struct ICgroupsReader {
virtual ~ICgroupsReader() = default;

virtual uint64_t read_memory_limit() = 0;

virtual uint64_t read_memory_usage() = 0;
};

// detect if cgroup is enabled
static bool cgroupsv1_enable();
static bool cgroupsv2_enable();
Expand Down Expand Up @@ -82,8 +73,14 @@ class CGroupUtil {
// systems existed only for a short transition period.
static std::optional<std::string> get_cgroupsv2_path(const std::string& subsystem);

// Cgroup file with only one line of numbers.
static Status read_int_line_from_cgroup_file(const std::filesystem::path& file_path,
int64_t* val);

// Multi-line Cgroup files, format is
// kernel 5
// rss 15
// [...]
static void read_int_metric_from_cgroup_file(
const std::filesystem::path& file_path,
std::unordered_map<std::string, int64_t>& metrics_map);
Expand Down

0 comments on commit fe0e303

Please sign in to comment.