blob: df19ebe61f42eab51ef11073671b3945b7cd0718 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
#pragma once
#include <cstdint>
#include <functional>
#include <optional>
#include <string>
#include <map>
namespace vespalib {
/*
* Class for getting cgroup resource limits (memory and cpu resources).
*
* Cgroups version 1 and version 2 are handled, but a mix of cgroups version 1
* and cgroups version 2 is not handled.
*
* Systemd resource control unit settings applied to cgroups (cf.
* systemd.resource-control(5) manual page on Linux) and
* container resource limit (set by e.g. docker and podman) applied to cgroups
* should be reflected in the sampled resource limits.
*
* The --cpus and --memory options for docker/podman create are reflected
* in cgroup limits that are sampled, but the cgroup limit affected by the
* --cpuset-cpus option is not yet sampled.
*
* For cgroups version 1, "memory.limit_in_bytes", "cpu.cfs_quota_us" and
* "cpu.cfs_period_us" are sampled.
*
* For cgroups version 2, "memory.max" and "cpu.max" are sampled.
*
* This is intended to be used by vespa-proton-bin running on the host
* or in a container, as a systemd service or not, with cgroups
* version 1 or cgroups version 2.
*/
class CGroupResourceLimits {
std::optional<uint64_t> _memory_limit;
std::optional<uint32_t> _cpu_limit;
std::string _base_path; // "/sys/fs/cgroup"
std::string _map_path; // "/proc/self/cgroup"
std::string _cgroup_v2_path; // Same cgroup path for all controllers
std::map<std::string, std::string> _cgroup_v1_paths; // controller -> cgroup path
void apply_memory_limit(uint64_t memory_limit);
void apply_cpu_limit(uint32_t cpu_limit);
void get_cgroup_paths();
void foreach_cgroup_level(const std::string& controller, const std::string& cgroup_path, const std::function<void(const std::string&)>& callback);
void foreach_cgroup_v1_level(const std::string& controller, const std::function<void(const std::string&)>& callback);
void foreach_cgroup_v2_level(const std::function<void(const std::string&)>& callback);
void get_memory_limits_v1(const std::string& dir);
void get_memory_limits_v1();
void get_cpu_limits_v1(const std::string& dir);
void get_cpu_limits_v1();
void get_limits_v1();
void get_memory_limits_v2(const std::string& dir);
void get_cpu_limits_v2(const std::string& dir);
void get_limits_v2(const std::string& dir);
void get_limits_v2();
public:
CGroupResourceLimits();
CGroupResourceLimits(const std::string& base_path, const std::string& map_path);
~CGroupResourceLimits();
const std::optional<uint64_t>& get_memory_limit() const noexcept { return _memory_limit; }
const std::optional<uint32_t>& get_cpu_limit() const noexcept { return _cpu_limit; }
};
}
|