[PATCH pve-manager 2/3] Fix #5708: Add CPU raw counters

Sascha Westermann sascha.westermann at hl-services.de
Tue Sep 17 07:50:19 CEST 2024


Add a map containing raw values from /proc/stat and "uptime_ticks" which
can be used in combination with cpuinfo.user_hz to calculate CPU usage
from two samples. "uptime_ticks" is only defined at the top level, as
/proc/stat is read once, so that core-specific raw values match this
value.

Signed-off-by: Sascha Westermann <sascha.westermann at hl-services.de>
---
 PVE/API2/Nodes.pm | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/PVE/API2/Nodes.pm b/PVE/API2/Nodes.pm
index 9920e977..1943ec56 100644
--- a/PVE/API2/Nodes.pm
+++ b/PVE/API2/Nodes.pm
@@ -5,6 +5,7 @@ use warnings;
 
 use Digest::MD5;
 use Digest::SHA;
+use IO::File;
 use Filesys::Df;
 use HTTP::Status qw(:constants);
 use JSON;
@@ -466,6 +467,37 @@ __PACKAGE__->register_method({
 	$res->{cpu} = $stat->{cpu};
 	$res->{wait} = $stat->{wait};
 
+	if (my $fh = IO::File->new ("/proc/stat", "r")) {
+	    my ($uptime_ticks) = PVE::ProcFSTools::read_proc_uptime(1);
+	    while (defined (my $line = <$fh>)) {
+		if ($line =~ m|^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)(?:\s+(\d+)\s+(\d+))?|) {
+		    $res->{cpustat}->{user} = int($1);
+		    $res->{cpustat}->{nice} = int($2);
+		    $res->{cpustat}->{system} = int($3);
+		    $res->{cpustat}->{idle} = int($4);
+		    $res->{cpustat}->{iowait} = int($5);
+		    $res->{cpustat}->{irq} = int($6);
+		    $res->{cpustat}->{softirq} = int($7);
+		    $res->{cpustat}->{steal} = int($8);
+		    $res->{cpustat}->{guest} = int($9);
+		    $res->{cpustat}->{guest_nice} = int($10);
+		    $res->{cpustat}->{uptime_ticks} = $uptime_ticks;
+		} elsif ($line =~ m|^cpu(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)(?:\s+(\d+)\s+(\d+))?|) {
+		    $res->{cpustat}->{"cpu" . $1}->{user} = int($2);
+		    $res->{cpustat}->{"cpu" . $1}->{nice} = int($3);
+		    $res->{cpustat}->{"cpu" . $1}->{system} = int($4);
+		    $res->{cpustat}->{"cpu" . $1}->{idle} = int($5);
+		    $res->{cpustat}->{"cpu" . $1}->{iowait} = int($6);
+		    $res->{cpustat}->{"cpu" . $1}->{irq} = int($7);
+		    $res->{cpustat}->{"cpu" . $1}->{softirq} = int($8);
+		    $res->{cpustat}->{"cpu" . $1}->{steal} = int($9);
+		    $res->{cpustat}->{"cpu" . $1}->{guest} = int($10);
+		    $res->{cpustat}->{"cpu" . $1}->{guest_nice} = int($11);
+		}
+	    }
+	    $fh->close;
+	}
+
 	my $meminfo = PVE::ProcFSTools::read_meminfo();
 	$res->{memory} = {
 	    free => $meminfo->{memfree},
-- 
2.46.0




More information about the pve-devel mailing list