]> git.proxmox.com Git - pmg-api.git/blame - PMG/CLI/pmgperf.pm
UserConfig: rename verity_entry to verify_entry
[pmg-api.git] / PMG / CLI / pmgperf.pm
CommitLineData
3c08696c
DM
1package PMG::CLI::pmgperf;
2
3use strict;
4use warnings;
5use Data::Dumper;
6use File::Sync;
7use Time::HiRes qw( usleep ualarm gettimeofday tv_interval );
8use Net::DNS::Resolver;
9
10use PVE::SafeSyslog;
11use PVE::Tools qw(extract_param);
12use PVE::INotify;
13use PVE::CLIHandler;
14
80a43e18
DM
15use PMG::RESTEnvironment;
16
17use base qw(PVE::CLIHandler);
18
19sub setup_environment {
20 PMG::RESTEnvironment->setup_default_cli_env();
21}
22
3c08696c
DM
23sub drop_cache {
24
25 # free pagecache,dentries,inode cache
26 if (-f '/proc/sys/vm/drop_caches') {
27 system ("echo 3 > /proc/sys/vm/drop_caches");
28 }
29}
30
31sub test_bogomips {
32 my $bogomips = 0;
33
34 open (TMP, "/proc/cpuinfo");
35
36 while (my $line = <TMP>) {
37 if ($line =~ m/^bogomips\s*:\s*(\d+\.\d+)\s*$/) {
38 $bogomips += $1;
39 }
40 }
41
42 close (TMP);
43
44 printf "CPU BOGOMIPS: %.2f\n", $bogomips;
45}
46
47sub test_regex {
48
49 my $starttime = [gettimeofday];
50
51 my $count = 0;
52 my $elapsed = 0;
53
54 for (;; $count++) {
55
56 my $str = int(rand(1000000)) . time();
57 if ($str =~ m/(.+)123.?123/) {
58 }
59 $elapsed = tv_interval ($starttime);
60
61 last if $elapsed > 3;
62 }
63
64 printf "REGEX/SECOND: %d\n", $count;
65}
66
67sub test_fsync {
68 my $basedir = shift;
69
70 drop_cache ();
71
72 my $dir = "$basedir/ptest.$$";
73
74 eval {
75
76 mkdir $dir;
77
78 my $data = ('A' x 4000) . "\n";
79
80 my $starttime = [gettimeofday];
81
82 my $count;
83 my $elapsed = 0;
84
85 for ($count=1;;$count++) {
86 my $m = $count % 300;
87
88 my $filename = "$dir/tf_$m.dat";
89
90 open (TMP, ">$filename") || die "open failed";
91
92 print TMP $data;
93
94 File::Sync::fsync (\*TMP);
95
96 close (TMP);
97
98 $elapsed = tv_interval ($starttime);
99
100 last if $elapsed > 3;
101 }
102 my $sps = $count /$elapsed; # fsync per second
103
104 printf "FSYNCS/SECOND: %.2f\n", $sps;
105 };
106
107 my $err = $@;
108
109 system ("rm -rf $dir");
110
111 die $err if $err;
112}
113
114sub test_seektime {
115 my ($rootdev, $hdsize) = @_;
116
117 drop_cache ();
118
119 open (ROOTHD, "<$rootdev") || die "unable to open HD";
120
121 my $starttime = [gettimeofday];
122 my $count;
123 my $elapsed = 0;
124 my $readbuf;
125
126 for ($count=1;;$count++) {
127
128 my $pos = int (rand (int($hdsize/512))) * 512;
129
130 sysseek (ROOTHD, $pos, 0);
131
132 (sysread (ROOTHD, $readbuf, 512) == 512) || die "read failed";
133
134 $elapsed = tv_interval ($starttime);
135
136 last if $elapsed > 3;
137 }
138
139 close (ROOTHD);
140
141 my $rps = $count /$elapsed; # blocks per second
142 my $ast = (1000/$rps);
143 printf "AVERAGE SEEK TIME: %.2f ms\n", $ast;
144}
145
146sub test_read {
147 my $rootdev = shift;
148
149 drop_cache ();
150
151 my $starttime = [gettimeofday];
152 my $bytes = 0;
153 my $elapsed = 0;
154 my $readbuf;
155
156
157 open (ROOTHD, "<$rootdev") || die "unable to open HD";
158
159
160 for (;;) {
161
162 my $c = sysread (ROOTHD, $readbuf, 2 * 1024 *1024);
163 die "read failed" if $c < 0;
164
165 $bytes += $c;
166
167 $elapsed = tv_interval ($starttime);
168
169 last if $elapsed > 3;
170 }
171
172 close (ROOTHD);
173
174 my $bps = $bytes /($elapsed * 1024 * 1024); # MB per second
175 printf "BUFFERED READS: %.2f MB/sec\n", $bps;
176}
177
178sub get_address {
179 my ($resolv, $dns) = @_;
180
181 if (my $a = $resolv->send ($dns, 'A')) {
182 foreach my $rra ($a->answer) {
183 if ($rra->type eq 'A') {
184 return $rra->address;
185 }
186 }
187 }
188
189 return undef;
190}
191
192sub test_dns {
193
194 my %dnsargs = (
195 tcp_timeout => 10,
196 udp_timeout => 10,
197 retry => 1,
198 retrans => 0,
199 dnsrch => 0,
200 defnames => 0,
201 debug => 0,
202 );
203
204 #$dnsargs{nameservers} = [ qw (208.67.222.222) ];
205 #$dnsargs{nameservers} = [ qw (127.0.0.1) ];
206
207 my $resolv = Net::DNS::Resolver->new (%dnsargs);
208
209 my $starttime = [gettimeofday];
210
211 my $count;
212 my $elapsed = 0;
213
214 my $uid = time() . int(rand(1000000));
215 my $domain = "nonexistent$uid.com";
216
217 for ($count=1;;$count++) {
218
219 my $hid = int(rand(1000000));
220 my $hname = "test${hid}.$domain";
221 get_address ($resolv, $hname);
222 $elapsed = tv_interval ($starttime);
223
224 last if ($count > 100) || ($elapsed > 3);
225 }
226
227 printf "DNS EXT: %0.2f ms\n", ($elapsed * 1000)/$count;
228
229 my $resolv_conf = `cat /etc/resolv.conf`;
230 ($domain) = $resolv_conf =~ m/^search\s+(\S+)\s*$/mg;
231
232 if ($domain) {
233 $starttime = [gettimeofday];
234 $elapsed = 0;
235
236 for ($count=1;;$count++) {
237
238 my $hid = int(rand(1000000));
239 my $hname = "test${hid}.$domain";
240 get_address ($resolv, $hname);
241 $elapsed = tv_interval ($starttime);
242
243 last if ($count > 100) || ($elapsed > 3);
244 }
245
246 printf "DNS INT: %0.2f ms (%s)\n",
247 ($elapsed * 1000)/ $count, $domain;
248 }
249}
250
251
252
253use base qw(PVE::CLIHandler);
254__PACKAGE__->register_method ({
255 name => 'pmgperf',
256 path => 'pmgperf',
257 method => 'POST',
258 description => "Proxmox benchmark.",
259 parameters => {
260 additionalProperties => 0,
261 properties => {
262 path => {
80a43e18 263 description => "File system location to test.",
3c08696c
DM
264 type => 'string',
265 optional => 1,
266 default => '/',
267 },
268 },
269 },
270 returns => { type => 'null'},
271 code => sub {
272 my ($param) = @_;
273
274 my $path = $param->{path} // '/';
275
276 test_bogomips ();
277 test_regex ();
278
279 my $hd = `df -P '$path'`;
280
281 my ($rootdev, $hdo_total, $hdo_used, $hdo_avail) = $hd =~
282 m/^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+\S+\s+.*$/mg;
283
284 if ($rootdev) {
285 my $hdsize = $hdo_total*1024;
286 printf "HD SIZE: %.2f GB ($rootdev)\n", ($hdsize / (1024*1024*1024));
287
288 if ($rootdev =~ m|^/dev/|) {
289 test_read ($rootdev);
290
291 test_seektime ($rootdev, $hdsize);
292 }
293 }
294
295 test_fsync ($path) if $hdo_avail;
296
297 test_dns ();
298
299 return undef;
300 }});
301
302our $cmddef = [ __PACKAGE__, 'pmgperf', ['path']];
303
3041;