]>
git.proxmox.com Git - pve-common.git/blob - data/PVE/ProcFSTools.pm
1 package PVE
::ProcFSTools
;
5 use Time
::HiRes qw
(gettimeofday
);
9 my $clock_ticks = POSIX
::sysconf
(&POSIX
::_SC_CLK_TCK
);
14 my $fn = '/proc/cpuinfo';
16 return $cpuinfo if $cpuinfo;
19 user_hz
=> $clock_ticks,
26 my $fh = IO
::File-
>new ($fn, "r");
30 while (defined(my $line = <$fh>)) {
31 if ($line =~ m/^processor\s*:\s*\d+\s*$/i) {
33 } elsif ($line =~ m/^model\s+name\s*:\s*(.*)\s*$/i) {
34 $res->{model
} = $1 if $res->{model
} eq 'unknown';
35 } elsif ($line =~ m/^cpu\s+MHz\s*:\s*(\d+\.\d+)\s*$/i) {
36 $res->{mhz
} = $1 if !$res->{mhz
};
37 } elsif ($line =~ m/^flags\s*:.*(vmx|svm)/) {
38 $res->{hvm
} = 1; # Hardware Virtual Machine (Intel VT / AMD-V)
39 } elsif ($line =~ m/^physical id\s*:\s*(\d+)\s*$/i) {
41 $res->{sockets
} = $sid if $sid > $res->{sockets
};
46 $res->{cpus
} = $count;
55 sub read_proc_uptime
{
58 my $line = PVE
::Tools
::file_read_firstline
("/proc/uptime");
59 if ($line && $line =~ m
|^(\d
+\
.\d
+)\s
+(\d
+\
.\d
+)\s
*$|) {
61 return (int($1*$clock_ticks), int($2*$clock_ticks));
63 return (int($1), int($2));
72 my $line = PVE
::Tools
::file_read_firstline
('/proc/loadavg');
74 if ($line =~ m
|^(\d
+\
.\d
+)\s
+(\d
+\
.\d
+)\s
+(\d
+\
.\d
+)\s
+\d
+/\d
+\s
+\d
+\s
*$|) {
75 return wantarray ?
($1, $2, $3) : $1;
78 return wantarray ?
(0, 0, 0) : 0;
84 my $res = { user
=> 0, nice
=> 0, system => 0, idle
=> 0 , sum
=> 0};
88 if (my $fh = IO
::File-
>new ("/proc/stat", "r")) {
89 while (defined (my $line = <$fh>)) {
90 if ($line =~ m
|^cpu\s
+(\d
+)\s
+(\d
+)\s
+(\d
+)\s
+(\d
+)\s
+(\d
+)\s
|) {
95 $res->{used
} = $1+$2+$3;
97 } elsif ($line =~ m
|^cpu\d
+\s
|) {
104 $cpucount = 1 if !$cpucount;
106 my $ctime = gettimeofday
; # floating point time in seconds
108 $res->{ctime
} = $ctime;
112 $last_proc_stat = $res if !$last_proc_stat;
114 my $diff = ($ctime - $last_proc_stat->{ctime
}) * $clock_ticks * $cpucount;
116 if ($diff > 1000) { # don't update too often
117 my $useddiff = $res->{used
} - $last_proc_stat->{used
};
118 $useddiff = $diff if $useddiff > $diff;
119 $res->{cpu
} = $useddiff/$diff;
120 my $waitdiff = $res->{iowait
} - $last_proc_stat->{iowait
};
121 $waitdiff = $diff if $waitdiff > $diff;
122 $res->{wait} = $waitdiff/$diff;
123 $last_proc_stat = $res;
125 $res->{cpu
} = $last_proc_stat->{cpu
};
126 $res->{wait} = $last_proc_stat->{wait};
132 sub read_proc_pid_stat
{
135 my $statstr = PVE
::Tools
::file_read_firstline
("/proc/$pid/stat");
137 if ($statstr && $statstr =~ m/^$pid \(.*\) (\S) (-?\d+) -?\d+ -?\d+ -?\d+ -?\d+ \d+ \d+ \d+ \d+ \d+ (\d+) (\d+) (-?\d+) (-?\d+) -?\d+ -?\d+ -?\d+ 0 (\d+) (\d+) (-?\d+) \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ -?\d+ -?\d+ \d+ \d+ \d+/) {
151 sub check_process_running
{
152 my ($pid, $pstart) = @_;
154 # note: waitpid only work for child processes, but not
155 # for processes spanned by other processes.
156 # kill(0, pid) return succes for zombies.
157 # So we read the status form /proc/$pid/stat instead
159 my $info = read_proc_pid_stat
($pid);
161 return $info && (!$pstart || ($info->{starttime
} eq $pstart)) && ($info->{status
} ne 'Z') ?
$info : undef;
164 sub read_proc_starttime
{
167 my $info = read_proc_pid_stat
($pid);
168 return $info ?
$info->{starttime
} : 0;
182 my $fh = IO
::File-
>new ("/proc/meminfo", "r");
186 while (my $line = <$fh>) {
187 if ($line =~ m/^(\S+):\s+(\d+)\s*kB/i) {
188 $d->{lc ($1)} = $2 * 1024;
193 $res->{memtotal
} = $d->{memtotal
};
194 $res->{memfree
} = $d->{memfree
} + $d->{buffers
} + $d->{cached
};
195 $res->{memused
} = $res->{memtotal
} - $res->{memfree
};
197 $res->{swaptotal
} = $d->{swaptotal
};
198 $res->{swapfree
} = $d->{swapfree
};
199 $res->{swapused
} = $res->{swaptotal
} - $res->{swapfree
};
204 # memory usage of current process
205 sub read_memory_usage
{
207 my $res = { size
=> 0, resident
=> 0, shared
=> 0 };
211 my $line = PVE
::Tools
::file_read_firstline
("/proc/$$/statm");
213 if ($line =~ m/^(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s*/) {
214 $res->{size
} = $1*$ps;
215 $res->{resident
} = $2*$ps;
216 $res->{shared
} = $3*$ps;
222 sub read_proc_net_dev
{
226 my $fh = IO
::File-
>new ("/proc/net/dev", "r");
229 while (defined (my $line = <$fh>)) {
230 if ($line =~ m/^\s*(.*):\s*(\d+)\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+(\d+)\s+/) {