Skip to content

Commit 20883ef

Browse files
server: simplify CgroupCpuUtil API and remove dead code
- Simplified API by removing CpuLimitResult struct wrapper - Changed return type from absl::optional<CpuLimitResult> to absl::optional<double> - Removed 4 unused functions and 40+ unused test cases - Added missing words to spelling dictionary - Fixed formatting issues - Net reduction: 334 lines of cleaner code Signed-off-by: premnath.nenavath <premnath.nenavath@gomotive.com>
1 parent cc31763 commit 20883ef

File tree

4 files changed

+37
-475
lines changed

4 files changed

+37
-475
lines changed

source/server/cgroup_cpu_util.cc

Lines changed: 14 additions & 210 deletions
Original file line numberDiff line numberDiff line change
@@ -49,199 +49,14 @@ absl::optional<uint32_t> CgroupCpuUtil::getCpuLimit(Filesystem::Instance& fs) {
4949
const CpuFiles& cpu_files = cpu_files_opt.value();
5050

5151
// Step 5: Read Actual Limits using cached file paths
52-
absl::optional<CpuLimitResult> limit_result_opt = readActualLimits(cpu_files, fs);
53-
if (!limit_result_opt.has_value()) {
52+
absl::optional<double> cpu_ratio = readActualLimits(cpu_files, fs);
53+
if (!cpu_ratio.has_value()) {
5454
// No valid limit found or unlimited
5555
return absl::nullopt;
5656
}
5757

5858
// Convert float64 ratio to uint32_t CPU count (rounded up)
59-
const uint32_t cpu_limit = static_cast<uint32_t>(std::ceil(limit_result_opt.value().cpu_ratio));
60-
return cpu_limit;
61-
}
62-
63-
// Reads CPU limits from cgroup v2 unified hierarchy.
64-
// Constructs the full path directly using mount point and relative path.
65-
absl::optional<uint32_t> CgroupCpuUtil::getCgroupV2CpuLimit(const std::string& mount_point,
66-
Filesystem::Instance& fs) {
67-
68-
// Get relative path and version
69-
absl::optional<CgroupPathInfo> path_info_opt = getCurrentCgroupPath(fs);
70-
if (!path_info_opt.has_value()) {
71-
return absl::nullopt;
72-
}
73-
const CgroupPathInfo& path_info = path_info_opt.value();
74-
75-
// Only proceed if this is actually a v2 cgroup
76-
if (path_info.version != "v2") {
77-
return absl::nullopt;
78-
}
79-
80-
// Construct full path: mount_point + relative_path + filename
81-
const std::string& cgroup_path = path_info.relative_path;
82-
std::string cpu_max_path = absl::StrCat(mount_point, cgroup_path, CGROUP_V2_CPU_MAX_FILE);
83-
return readCgroupV2CpuLimit(fs, cpu_max_path);
84-
}
85-
86-
// Reads CPU limits from cgroup v1 legacy hierarchy.
87-
// Constructs the full path directly using mount point and relative path.
88-
absl::optional<uint32_t> CgroupCpuUtil::getCgroupV1CpuLimit(const std::string& mount_point,
89-
Filesystem::Instance& fs) {
90-
91-
// Get relative path and version
92-
absl::optional<CgroupPathInfo> path_info_opt = getCurrentCgroupPath(fs);
93-
if (!path_info_opt.has_value()) {
94-
return absl::nullopt;
95-
}
96-
const CgroupPathInfo& path_info = path_info_opt.value();
97-
98-
// Only proceed if this is actually a v1 cgroup
99-
if (path_info.version != "v1") {
100-
return absl::nullopt;
101-
}
102-
103-
// Construct full paths: mount_point + relative_path + filename
104-
const std::string& cgroup_path = path_info.relative_path;
105-
std::string quota_path = absl::StrCat(mount_point, cgroup_path, CGROUP_V1_QUOTA_FILE);
106-
std::string period_path = absl::StrCat(mount_point, cgroup_path, CGROUP_V1_PERIOD_FILE);
107-
return readCgroupV1CpuLimit(fs, quota_path, period_path);
108-
}
109-
110-
// Parses cgroup v2 cpu.max file to extract CPU limit.
111-
// File format: "<quota> <period>" or "max <period>" for unlimited
112-
//
113-
// Examples:
114-
// "150000 100000" = 1.5 CPUs (150ms quota per 100ms period)
115-
// "max 100000" = unlimited
116-
// "200000 100000" = 2.0 CPUs (200ms quota per 100ms period)
117-
//
118-
// Returns absl::nullopt for unlimited or parsing errors, valid value for actual limit (rounded up).
119-
absl::optional<uint32_t> CgroupCpuUtil::readCgroupV2CpuLimit(Filesystem::Instance& fs,
120-
const std::string& cpu_max_path) {
121-
const auto result = fs.fileReadToEnd(cpu_max_path);
122-
if (!result.ok()) {
123-
// File doesn't exist or can't be read
124-
ENVOY_LOG_MISC(warn, "Cannot read cgroup v2 cpu.max file {}: file doesn't exist or read failed",
125-
cpu_max_path);
126-
return absl::nullopt;
127-
}
128-
129-
const std::string& content = result.value();
130-
131-
// Validate file content using strict requirements
132-
absl::optional<absl::string_view> content_view_opt =
133-
validateCgroupFileContent(content, cpu_max_path);
134-
if (!content_view_opt.has_value()) {
135-
return absl::nullopt;
136-
}
137-
absl::string_view content_view = content_view_opt.value();
138-
139-
// Find space separator
140-
size_t space_pos = content_view.find(' ');
141-
if (space_pos == absl::string_view::npos) {
142-
ENVOY_LOG_MISC(warn, "Malformed cgroup v2 cpu.max file {}: no space separator", cpu_max_path);
143-
return absl::nullopt;
144-
}
145-
146-
absl::string_view quota_str = content_view.substr(0, space_pos);
147-
absl::string_view period_str = content_view.substr(space_pos + 1);
148-
149-
// Check if quota is "max" (unlimited CPU)
150-
if (quota_str == "max") {
151-
return absl::nullopt; // Unlimited
152-
}
153-
154-
uint64_t quota, period;
155-
if (!absl::SimpleAtoi(quota_str, &quota) || !absl::SimpleAtoi(period_str, &period)) {
156-
// Parse failure - log warning and return nullopt
157-
ENVOY_LOG_MISC(warn, "Failed to parse cgroup v2 cpu.max file {}: quota='{}' period='{}'",
158-
cpu_max_path, quota_str, period_str);
159-
return absl::nullopt;
160-
}
161-
162-
if (period == 0) {
163-
// Division by zero protection
164-
ENVOY_LOG_MISC(warn, "Invalid cgroup v2 cpu.max file {}: period cannot be zero", cpu_max_path);
165-
return absl::nullopt;
166-
}
167-
168-
// Calculate CPU limit as quota/period ratio, rounded up to next integer
169-
// 1.5 CPUs becomes 2 CPUs for worker threads
170-
const uint32_t cpu_limit = static_cast<uint32_t>(std::ceil(static_cast<double>(quota) / period));
171-
return cpu_limit;
172-
}
173-
174-
// Parses cgroup v1 CPU quota and period files to extract CPU limit.
175-
// Uses separate files: cpu.cfs_quota_us and cpu.cfs_period_us
176-
//
177-
// Examples:
178-
// quota=150000, period=100000 = 1.5 CPUs
179-
// quota=-1, period=100000 = unlimited
180-
// quota=200000, period=100000 = 2.0 CPUs
181-
//
182-
// Returns absl::nullopt for unlimited or parsing errors, valid value for actual limit (rounded up).
183-
absl::optional<uint32_t> CgroupCpuUtil::readCgroupV1CpuLimit(Filesystem::Instance& fs,
184-
const std::string& quota_path,
185-
const std::string& period_path) {
186-
// Read the quota file (cpu.cfs_quota_us)
187-
const auto quota_result = fs.fileReadToEnd(quota_path);
188-
if (!quota_result.ok()) {
189-
// File doesn't exist or can't be read
190-
ENVOY_LOG_MISC(warn, "Cannot read cgroup v1 quota file {}: file doesn't exist or read failed",
191-
quota_path);
192-
return absl::nullopt;
193-
}
194-
195-
// Read the period file (cpu.cfs_period_us)
196-
const auto period_result = fs.fileReadToEnd(period_path);
197-
if (!period_result.ok()) {
198-
// File doesn't exist or can't be read
199-
ENVOY_LOG_MISC(warn, "Cannot read cgroup v1 period file {}: file doesn't exist or read failed",
200-
period_path);
201-
return absl::nullopt;
202-
}
203-
204-
const std::string& quota_content = quota_result.value();
205-
const std::string& period_content = period_result.value();
206-
207-
// Validate both files using strict requirements
208-
absl::optional<absl::string_view> quota_str_opt =
209-
validateCgroupFileContent(quota_content, quota_path);
210-
if (!quota_str_opt.has_value()) {
211-
return absl::nullopt;
212-
}
213-
214-
absl::optional<absl::string_view> period_str_opt =
215-
validateCgroupFileContent(period_content, period_path);
216-
if (!period_str_opt.has_value()) {
217-
return absl::nullopt;
218-
}
219-
220-
absl::string_view quota_str = quota_str_opt.value();
221-
absl::string_view period_str = period_str_opt.value();
222-
223-
int64_t quota, period;
224-
if (!absl::SimpleAtoi(quota_str, &quota) || !absl::SimpleAtoi(period_str, &period)) {
225-
// Parse failure - log warning and return nullopt
226-
ENVOY_LOG_MISC(warn, "Failed to parse cgroup v1 CPU files: quota='{}' period='{}'", quota_str,
227-
period_str);
228-
return absl::nullopt;
229-
}
230-
231-
// Check if quota is -1 (standard cgroup v1 unlimited indicator)
232-
if (quota == -1) {
233-
return absl::nullopt; // Unlimited
234-
}
235-
236-
if (period <= 0 || quota <= 0) {
237-
// Invalid values - log warning and return nullopt
238-
ENVOY_LOG_MISC(warn, "Invalid cgroup v1 CPU values: quota={} period={}", quota, period);
239-
return absl::nullopt;
240-
}
241-
242-
// Calculate CPU limit as quota/period ratio, rounded up to next integer
243-
// 1.5 CPUs becomes 2 CPUs for worker threads
244-
const uint32_t cpu_limit = static_cast<uint32_t>(std::ceil(static_cast<double>(quota) / period));
59+
const uint32_t cpu_limit = static_cast<uint32_t>(std::ceil(cpu_ratio.value()));
24560
return cpu_limit;
24661
}
24762

@@ -338,13 +153,6 @@ absl::optional<CgroupPathInfo> CgroupCpuUtil::getCurrentCgroupPath(Filesystem::I
338153
}
339154

340155
// Constructs complete cgroup path by combining mount point and process assignment.
341-
//
342-
// Logic:
343-
// 1. Use provided mount point (already discovered)
344-
// 2. Call process assignment → Get relative path
345-
// 3. Path construction: Combine mount point and relative path
346-
// 4. Version determination: Use version from process assignment
347-
// 5. Result: Combined path + cgroup version
348156
absl::optional<CgroupInfo> CgroupCpuUtil::constructCgroupPath(const std::string& mount_point,
349157
Filesystem::Instance& fs) {
350158

@@ -449,7 +257,7 @@ absl::optional<CpuFiles> CgroupCpuUtil::accessCgroupFiles(const CgroupInfo& cgro
449257
}
450258

451259
// Reads actual CPU limits from cgroup v1 files with quota/period parsing.
452-
absl::optional<CpuLimitResult> CgroupCpuUtil::readActualLimitsV1(const CpuFiles& cpu_files) {
260+
absl::optional<double> CgroupCpuUtil::readActualLimitsV1(const CpuFiles& cpu_files) {
453261
// v1: Use cached quota and period content (no re-reading)
454262
const std::string quota_str = std::string(absl::StripAsciiWhitespace(cpu_files.quota_content));
455263
const std::string period_str = std::string(absl::StripAsciiWhitespace(cpu_files.period_content));
@@ -474,17 +282,15 @@ absl::optional<CpuLimitResult> CgroupCpuUtil::readActualLimitsV1(const CpuFiles&
474282
}
475283

476284
// Calculate CPU ratio as float64
477-
CpuLimitResult result;
478-
result.cpu_ratio = static_cast<double>(quota) / static_cast<double>(period);
285+
double cpu_ratio = static_cast<double>(quota) / static_cast<double>(period);
479286

480-
ENVOY_LOG_MISC(debug, "cgroup v1 CPU ratio: {} (quota={}, period={})", result.cpu_ratio, quota,
481-
period);
287+
ENVOY_LOG_MISC(debug, "cgroup v1 CPU ratio: {} (quota={}, period={})", cpu_ratio, quota, period);
482288

483-
return result;
289+
return cpu_ratio;
484290
}
485291

486292
// Reads actual CPU limits from cgroup v2 files with "quota period" parsing.
487-
absl::optional<CpuLimitResult> CgroupCpuUtil::readActualLimitsV2(const CpuFiles& cpu_files) {
293+
absl::optional<double> CgroupCpuUtil::readActualLimitsV2(const CpuFiles& cpu_files) {
488294
// v2: Use cached cpu.max content (no re-reading)
489295
const std::string content = std::string(absl::StripAsciiWhitespace(cpu_files.quota_content));
490296

@@ -516,13 +322,11 @@ absl::optional<CpuLimitResult> CgroupCpuUtil::readActualLimitsV2(const CpuFiles&
516322
}
517323

518324
// Calculate CPU ratio as float64
519-
CpuLimitResult result;
520-
result.cpu_ratio = static_cast<double>(quota) / static_cast<double>(period);
325+
double cpu_ratio = static_cast<double>(quota) / static_cast<double>(period);
521326

522-
ENVOY_LOG_MISC(debug, "cgroup v2 CPU ratio: {} (quota={}, period={})", result.cpu_ratio, quota,
523-
period);
327+
ENVOY_LOG_MISC(debug, "cgroup v2 CPU ratio: {} (quota={}, period={})", cpu_ratio, quota, period);
524328

525-
return result;
329+
return cpu_ratio;
526330
}
527331

528332
// Reads actual CPU limits from cgroup files with version-specific parsing.
@@ -537,8 +341,8 @@ absl::optional<CpuLimitResult> CgroupCpuUtil::readActualLimitsV2(const CpuFiles&
537341
// - v1: quota = -1 means no limit
538342
// - v2: quota = "max" means no limit
539343
// 5. Result: CPU limit as float64 ratio
540-
absl::optional<CpuLimitResult> CgroupCpuUtil::readActualLimits(const CpuFiles& cpu_files,
541-
Filesystem::Instance& /* fs */) {
344+
absl::optional<double> CgroupCpuUtil::readActualLimits(const CpuFiles& cpu_files,
345+
Filesystem::Instance& /* fs */) {
542346
if (cpu_files.version == "v1") {
543347
return readActualLimitsV1(cpu_files);
544348
} else if (cpu_files.version == "v2") {
@@ -753,7 +557,7 @@ std::string CgroupCpuUtil::unescapePath(const std::string& path) {
753557
// 25 21 0:21 / /sys/fs/cgroup/cpu rw,relatime - cgroup cgroup rw,cpu
754558
// 26 21 0:22 / /sys/fs/cgroup cgroup2 rw,relatime - cgroup2 cgroup2 rw
755559
//
756-
// We extract field 5 (mount point) for cgroup/cgroup2 filesystems only.
560+
// We extract field 5 (mount point) for cgroup/cgroup2 filesystem only.
757561
//
758562
// NOTE: Mount points may contain escaped characters (\040 for space, \134 for backslash, etc.)
759563
// and must be unescaped before use.

0 commit comments

Comments
 (0)