]>
git.proxmox.com Git - pve-container.git/blob - src/PVE/LXC/CGroup.pm
3 # This package should deal with figuring out the right cgroup path for a
4 # container (via the command socket), reading and writing cgroup values, and
5 # handling cgroup v1 & v2 differences.
7 # Note that the long term plan is to have resource manage functions intead of
8 # dealing with cgroup files on the outside.
10 package PVE
::LXC
::CGroup
;
15 use PVE
::LXC
::Command
;
17 # We don't want to do a command socket round trip for every cgroup read/write,
18 # so any cgroup function needs to have the container's path cached, so this
19 # package has to be instantiated.
21 # LXC keeps separate paths by controller (although they're normally all the
22 # same, in our # case anyway), so we cache them by controller as well.
24 my ($class, $vmid) = @_;
26 my $self = { vmid
=> $vmid };
28 return bless $self, $class;
31 my $CPUSET_BASE = undef;
32 # Find the cpuset cgroup controller.
34 # This is a function, not a method!
35 sub cpuset_controller_path
() {
36 if (!defined($CPUSET_BASE)) {
38 # legacy cpuset cgroup:
39 ['/sys/fs/cgroup/cpuset', 'cpuset.effective_cpus'],
40 # pure cgroupv2 environment:
41 ['/sys/fs/cgroup', 'cpuset.cpus.effective'],
42 # hybrid, with cpuset moved to cgroupv2
43 ['/sys/fs/cgroup/unified', 'cpuset.cpus.effective'],
46 my ($result) = grep { -f
"$_->[0]/$_->[1]" } @$CPUSET_PATHS;
47 die "failed to find cpuset controller\n" if !defined($result);
49 $CPUSET_BASE = $result->[0];
55 my $CGROUP_MODE = undef;
56 # Figure out which cgroup mode we're operating under:
58 # Returns 1 if cgroupv1 controllers exist (hybrid or legacy mode), and 2 in a
59 # cgroupv2-only environment.
61 # This is a function, not a method!
63 if (!defined($CGROUP_MODE)) {
64 my ($v1, $v2) = PVE
::LXC
::get_cgroup_subsystems
();
66 # hybrid or legacy mode
73 die "unknown cgroup mode\n" if !defined($CGROUP_MODE);
77 # Get a subdirectory (without the cgroup mount point) for a controller.
79 # If `$controller` is `undef`, get the unified (cgroupv2) path.
81 # Note that in cgroup v2, lxc uses the activated controller names
82 # (`cgroup.controllers` file) as list of controllers for the unified hierarchy,
83 # so this returns a result when a `controller` is provided even when using
84 # a pure cgroupv2 setup.
86 my ($self, $controller, $limiting) = @_;
88 my $entry_name = $controller || 'unified';
89 my $entry = ($self->{controllers
}->{$entry_name} //= {});
91 my $kind = $limiting ?
'limit' : 'ns';
92 my $path = $entry->{$kind};
94 return $path if defined $path;
96 $path = PVE
::LXC
::Command
::get_cgroup_path
(
103 if ($path =~ /\.\./) {
104 die "lxc returned suspicious path: '$path'\n";
106 ($path) = ($path =~ /^(.*)$/s);
108 $entry->{$kind} = $path;
113 # Get a path for a controller.
115 # `$controller` may be `undef`, see get_subdir above for details.
117 my ($self, $controller) = @_;
119 my $path = get_subdir
($self, $controller)
122 # The main mount point we currenlty assume to be in a standard location.
123 return "/sys/fs/cgroup/$path" if cgroup_mode
() == 2;
124 return "/sys/fs/cgroup/unified/$path" if !defined($controller);
125 return "/sys/fs/cgroup/$controller/$path";