[pve-devel] [PATCH container 05/20] cgroup: add get_io_stats and parse_nested_keyed_file
w.bumiller at proxmox.com
w.bumiller at proxmox.com
Fri Apr 3 16:37:25 CEST 2020
From: Wolfgang Bumiller <w.bumiller at proxmox.com>
Signed-off-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
---
src/PVE/LXC/CGroup.pm | 71 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 71 insertions(+)
diff --git a/src/PVE/LXC/CGroup.pm b/src/PVE/LXC/CGroup.pm
index 7561fb2..207c0c1 100644
--- a/src/PVE/LXC/CGroup.pm
+++ b/src/PVE/LXC/CGroup.pm
@@ -12,6 +12,11 @@ package PVE::LXC::CGroup;
use strict;
use warnings;
+use PVE::Tools qw(
+ file_get_contents
+ file_read_firstline
+);
+
use PVE::LXC::Command;
# We don't want to do a command socket round trip for every cgroup read/write,
@@ -125,4 +130,70 @@ sub get_path {
return "/sys/fs/cgroup/$controller/$path";
}
+# Parse a 'Nested keyed' file:
+#
+# See kernel documentation `admin-guide/cgroup-v2.rst` 4.1.
+my sub parse_nested_keyed_file($) {
+ my ($data) = @_;
+ my $res = {};
+ foreach my $line (split(/\n/, $data)) {
+ my ($key, @values) = split(/\s+/, $line);
+
+ my $d = ($res->{$key} = {});
+
+ foreach my $value (@values) {
+ if (my ($key, $value) = ($value =~ /^([^=]+)=(.*)$/)) {
+ $d->{$key} = $value;
+ } else {
+ warn "bad key=value pair in nested keyed file\n";
+ }
+ }
+ }
+}
+
+# Get I/O stats for a container.
+sub get_io_stats {
+ my ($self) = @_;
+
+ my $res = {
+ diskread => 0,
+ diskwrite => 0,
+ };
+
+ if (cgroup_mode() == 2) {
+ if (defined(my $path = $self->get_path('io'))) {
+ # cgroupv2 environment, io controller enabled
+ my $io_stat = file_get_contents("$path/io.stat");
+
+ my $data = parse_nested_keyed_file($io_stat);
+ foreach my $dev (keys %$data) {
+ my $dev = $data->{$dev};
+ if (my $b = $dev->{rbytes}) {
+ $res->{diskread} += $b;
+ }
+ if (my $b = $dev->{wbytes}) {
+ $res->{diskread} += $b;
+ }
+ }
+ } else {
+ # io controller not enabled or container not running
+ return undef;
+ }
+ } elsif (defined(my $path = $self->get_path('blkio'))) {
+ # cgroupv1 environment:
+ my $io = file_get_contents("$path/blkio.throttle.io_service_bytes_recursive");
+ foreach my $line (split(/\n/, $io)) {
+ if (my ($type, $bytes) = ($line =~ /^\d+:\d+\s+(Read|Write)\s+(\d+)$/)) {
+ $res->{diskread} += $bytes if $type eq 'Read';
+ $res->{diskwrite} += $bytes if $type eq 'Write';
+ }
+ }
+ } else {
+ # container not running
+ return undef;
+ }
+
+ return $res;
+}
+
1;
--
2.20.1
More information about the pve-devel
mailing list