]>
Commit | Line | Data |
---|---|---|
aff192e6 DM |
1 | package PVE::OpenVZ; |
2 | ||
3 | use strict; | |
4 | use IO::Dir; | |
5 | use IO::File; | |
6 | use PVE::Config; | |
7 | ||
8 | my $confdir = "/etc/vz/conf"; | |
9 | ||
10 | my $last_proc_vestat = {}; | |
11 | ||
12 | $ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin'; | |
13 | ||
14 | my $kernel_version = `uname -r`; | |
15 | ||
16 | sub vmlist { | |
17 | ||
18 | my $res = {}; | |
19 | ||
20 | my $fd = IO::Dir->new ($confdir) || | |
21 | die "unable to open dir '$confdir' - $!"; | |
22 | ||
23 | while (defined(my $de = $fd->read)) { | |
24 | if ($de =~ m/^(\d+)\.conf$/) { | |
25 | my $veid = $1; | |
26 | next if !$veid; # skip VE0 | |
27 | my $d = { | |
28 | status => 'stopped', | |
29 | type => 'openvz', | |
30 | }; | |
31 | ||
32 | if (my $conf = PVE::Config::read_file ("$confdir/$de")) { | |
33 | $d->{name} = $conf->{hostname}->{value} || "VM$veid"; | |
34 | $d->{name} =~ s/[\s]//g; | |
35 | ||
36 | $d->{cpus} = $conf->{cpus}->{value} || 1; | |
37 | ||
38 | $d->{disk} = 0; | |
39 | $d->{maxdisk} = int ($conf->{diskspace}->{bar} / 1024); | |
40 | ||
41 | $d->{mem} = 0; | |
42 | $d->{maxmem} = int (($conf->{vmguarpages}->{bar} * 4) / 1024); | |
43 | $d->{nproc} = 0; | |
44 | ||
45 | $d->{uptime} = 0; | |
46 | $d->{pctcpu} = 0; | |
47 | $d->{relcpu} = 0; | |
48 | ||
49 | if (my $ip = $conf->{ip_address}->{value}) { | |
50 | $ip =~ s/,;/ /g; | |
51 | $d->{ip} = (split(/\s+/, $ip))[0]; | |
52 | } else { | |
53 | $d->{ip} = '-'; | |
54 | } | |
55 | $res->{"VEID_$veid"} = $d; | |
56 | } | |
57 | } | |
58 | } | |
59 | ||
60 | my $fh; | |
61 | ||
62 | if ($fh = IO::File->new ("/proc/mounts", "r")) { | |
63 | while (defined (my $line = <$fh>)) { | |
64 | if ($line =~ m|^/var/lib/vz/private/(\d+)\s+/var/lib/vz/root/|) { | |
65 | $res->{"VEID_$1"}->{status} = 'mounted'; | |
66 | } | |
67 | } | |
68 | } | |
69 | ||
70 | if ($fh = IO::File->new ("/proc/user_beancounters", "r")) { | |
71 | my $veid; | |
72 | while (defined (my $line = <$fh>)) { | |
73 | if ($line =~ m|\s*((\d+):\s*)?([a-z]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$|) { | |
74 | $veid = $2 if defined($2); | |
75 | next if !$veid; | |
76 | my ($name, $held, $maxheld, $bar, $lim, $failcnt) = ($3, $4, $5, $6, $7, $8); | |
77 | if (my $d = $res->{"VEID_$veid"}) { | |
78 | if ($name eq 'privvmpages') { | |
79 | $d->{mem} = int (($held *4) / 1024); | |
80 | $d->{maxmem} = int (($bar *4) / 1024); | |
81 | } elsif ($name eq 'numproc') { | |
82 | $d->{nproc} = $held; | |
83 | } | |
84 | } | |
85 | } | |
86 | } | |
87 | } | |
88 | ||
89 | if ($fh = IO::File->new ("/proc/vz/vzquota", "r")) { | |
90 | while (defined (my $line = <$fh>)) { | |
91 | if ($line =~ m|^(\d+):\s+/var/lib/vz/private/\d+$|) { | |
92 | if (my $d = $res->{"VEID_$1"}) { | |
93 | $line = <$fh>; | |
94 | if ($line =~ m|^\s*1k-blocks\s+(\d+)\s+(\d+)\s|) { | |
95 | $d->{disk} = int ($1/1024); | |
96 | $d->{maxdisk} = int ($2/1024); | |
97 | } | |
98 | } | |
99 | } | |
100 | } | |
101 | } | |
102 | ||
103 | my $cpuinfo = PVE::Utils::get_cpu_info(); | |
104 | my $cpus = $cpuinfo->{cpus} || 1; | |
105 | ||
106 | # see http://wiki.openvz.org/Vestat | |
107 | if ($fh = new IO::File ("/proc/vz/vestat", "r")) { | |
108 | while (defined (my $line = <$fh>)) { | |
109 | if ($line =~ m/^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+/) { | |
110 | my $veid = $1; | |
111 | my $user = $2; | |
112 | my $nice = $3; | |
113 | my $system = $4; | |
114 | my $ut = $5; | |
115 | my $sum = $8*$cpus; # uptime in jiffies * cpus = available jiffies | |
116 | my $used = $9; # used time in jiffies | |
117 | ||
118 | # HZ is 250 in our kernel 2.6.24 kernel | |
119 | # but HZ is 1000 in our kernel 2.6.18 kernel | |
120 | my $hz = 250; | |
121 | $hz = 1000 if $kernel_version && $kernel_version =~ m/^2.6.18/; | |
122 | my $uptime = int ($ut / $hz); # HZ is 250 in our kernel | |
123 | ||
124 | my $d = $res->{"VEID_$veid"}; | |
125 | next if !$d; | |
126 | ||
127 | $d->{status} = 'running'; | |
128 | $d->{uptime} = $uptime; | |
129 | ||
130 | if (!defined ($last_proc_vestat->{$veid}) || | |
131 | ($last_proc_vestat->{$veid}->{sum} > $sum)) { | |
132 | $last_proc_vestat->{$veid} = { used => 0, sum => 0, pctcpu => 0, relcpu => 0}; | |
133 | } | |
134 | ||
135 | my $diff = $sum - $last_proc_vestat->{$veid}->{sum}; | |
136 | ||
137 | if ($diff > 1000) { # don't update too often | |
138 | my $useddiff = $used - $last_proc_vestat->{$veid}->{used}; | |
139 | my $pctcpu = int ($useddiff*100/$diff); | |
140 | $last_proc_vestat->{$veid}->{sum} = $sum; | |
141 | $last_proc_vestat->{$veid}->{used} = $used; | |
142 | $last_proc_vestat->{$veid}->{pctcpu} = $d->{pctcpu} = $pctcpu; | |
143 | ||
144 | # fixme: openvz --cpus does not work currently | |
145 | my $relcpu = $pctcpu; | |
146 | $last_proc_vestat->{$veid}->{relcpu} = $d->{relcpu} = $relcpu; | |
147 | ||
148 | } else { | |
149 | $d->{pctcpu} = $last_proc_vestat->{$veid}->{pctcpu}; | |
150 | $d->{relcpu} = $last_proc_vestat->{$veid}->{relcpu}; | |
151 | } | |
152 | } | |
153 | } | |
154 | } | |
155 | ||
156 | return $res; | |
157 | ||
158 | } |