]> git.proxmox.com Git - pve-manager.git/blob - bin/pveperf
imported from svn 'pve-manager/pve2'
[pve-manager.git] / bin / pveperf
1 #!/usr/bin/perl -w
2
3 use strict;
4 use File::Sync;
5 use Time::HiRes qw( usleep ualarm gettimeofday tv_interval );
6 use Net::DNS::Resolver;
7
8 if ($#ARGV >= 1) {
9 print STDERR "usage: $0 [PATH]\n";
10 exit -1;
11 }
12
13 my $path = $ARGV[0] || '/';
14
15 sub drop_cache {
16
17 # free pagecache,dentries,inode cache
18 if (-f '/proc/sys/vm/drop_caches') {
19 system ("echo 3 > /proc/sys/vm/drop_caches");
20 }
21 }
22
23 sub test_bogomips {
24 my $bogomips = 0;
25
26 open (TMP, "/proc/cpuinfo");
27
28 while (my $line = <TMP>) {
29 if ($line =~ m/^bogomips\s*:\s*(\d+\.\d+)\s*$/) {
30 $bogomips += $1;
31 }
32 }
33
34 close (TMP);
35
36 printf "CPU BOGOMIPS: %.2f\n", $bogomips;
37 }
38
39 sub test_regex {
40
41 my $starttime = [gettimeofday];
42
43 my $count = 0;
44 my $elapsed = 0;
45
46 for (;; $count++) {
47
48 my $str = int(rand(1000000)) . time();
49 if ($str =~ m/(.+)123.?123/) {
50 }
51 $elapsed = tv_interval ($starttime);
52
53 last if $elapsed > 3;
54 }
55
56 printf "REGEX/SECOND: %d\n", $count;
57 }
58
59 sub test_fsync {
60 my $basedir = shift;
61
62 drop_cache ();
63
64 my $dir = "$basedir/ptest.$$";
65
66 eval {
67
68 mkdir $dir;
69
70 my $data = ('A' x 4000) . "\n";
71
72 my $starttime = [gettimeofday];
73
74 my $count;
75 my $elapsed = 0;
76
77 for ($count=1;;$count++) {
78 my $m = $count % 300;
79
80 my $filename = "$dir/tf_$m.dat";
81
82 open (TMP, ">$filename") || die "open failed";
83
84 print TMP $data;
85
86 File::Sync::fsync (\*TMP);
87
88 close (TMP);
89
90 $elapsed = tv_interval ($starttime);
91
92 last if $elapsed > 3;
93 }
94 my $sps = $count /$elapsed; # fsync per second
95
96 printf "FSYNCS/SECOND: %.2f\n", $sps;
97 };
98
99 my $err = $@;
100
101 system ("rm -rf $dir");
102
103 die $err if $err;
104 }
105
106 sub test_seektime {
107 my ($rootdev, $hdsize) = @_;
108
109 drop_cache ();
110
111 open (ROOTHD, "<$rootdev") || die "unable to open HD";
112
113 my $starttime = [gettimeofday];
114 my $count;
115 my $elapsed = 0;
116 my $readbuf;
117
118 for ($count=1;;$count++) {
119
120 my $pos = int (rand (int($hdsize/512))) * 512;
121
122 sysseek (ROOTHD, $pos, 0);
123
124 (sysread (ROOTHD, $readbuf, 512) == 512) || die "read failed";
125
126 $elapsed = tv_interval ($starttime);
127
128 last if $elapsed > 3;
129 }
130
131 close (ROOTHD);
132
133 my $rps = $count /$elapsed; # blocks per second
134 my $ast = (1000/$rps);
135 printf "AVERAGE SEEK TIME: %.2f ms\n", $ast;
136 }
137
138 sub test_read {
139 my $rootdev = shift;
140
141 drop_cache ();
142
143 my $starttime = [gettimeofday];
144 my $bytes = 0;
145 my $elapsed = 0;
146 my $readbuf;
147
148
149 open (ROOTHD, "<$rootdev") || die "unable to open HD";
150
151
152 for (;;) {
153
154 my $c = sysread (ROOTHD, $readbuf, 2 * 1024 *1024);
155 die "read failed" if $c < 0;
156
157 $bytes += $c;
158
159 $elapsed = tv_interval ($starttime);
160
161 last if $elapsed > 3;
162 }
163
164 close (ROOTHD);
165
166 my $bps = $bytes /($elapsed * 1024 * 1024); # MB per second
167 printf "BUFFERED READS: %.2f MB/sec\n", $bps;
168 }
169
170 sub get_address {
171 my ($resolv, $dns) = @_;
172
173 if (my $a = $resolv->send ($dns, 'A')) {
174 foreach my $rra ($a->answer) {
175 if ($rra->type eq 'A') {
176 return $rra->address;
177 }
178 }
179 }
180
181 return undef;
182 }
183
184 sub test_dns {
185
186 my %dnsargs = (
187 tcp_timeout => 10,
188 udp_timeout => 10,
189 retry => 1,
190 retrans => 0,
191 dnsrch => 0,
192 defnames => 0,
193 debug => 0,
194 );
195
196 #$dnsargs{nameservers} = [ qw (208.67.222.222) ];
197 #$dnsargs{nameservers} = [ qw (127.0.0.1) ];
198
199 my $resolv = Net::DNS::Resolver->new (%dnsargs);
200
201 my $starttime = [gettimeofday];
202
203 my $count;
204 my $elapsed = 0;
205
206 my $uid = time() . int(rand(1000000));
207 my $domain = "nonexistent$uid.com";
208
209 for ($count=1;;$count++) {
210
211 my $hid = int(rand(1000000));
212 my $hname = "test${hid}.$domain";
213 get_address ($resolv, $hname);
214 $elapsed = tv_interval ($starttime);
215
216 last if ($count > 100) || ($elapsed > 3);
217 }
218
219 printf "DNS EXT: %0.2f ms\n", ($elapsed * 1000)/$count;
220
221 my $resolv_conf = `cat /etc/resolv.conf`;
222 ($domain) = $resolv_conf =~ m/^search\s+(\S+)\s*$/mg;
223
224 if ($domain) {
225 $starttime = [gettimeofday];
226 $elapsed = 0;
227
228 for ($count=1;;$count++) {
229
230 my $hid = int(rand(1000000));
231 my $hname = "test${hid}.$domain";
232 get_address ($resolv, $hname);
233 $elapsed = tv_interval ($starttime);
234
235 last if ($count > 100) || ($elapsed > 3);
236 }
237
238 printf "DNS INT: %0.2f ms (%s)\n",
239 ($elapsed * 1000)/ $count, $domain;
240 }
241 }
242
243 test_bogomips ();
244 test_regex ();
245
246 my $hd = `df -P '$path'`;
247
248 my ($rootdev, $hdo_total, $hdo_used, $hdo_avail) = $hd =~
249 m/^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+\S+\s+.*$/mg;
250
251 if ($rootdev) {
252 my $hdsize = $hdo_total*1024;
253 printf "HD SIZE: %.2f GB ($rootdev)\n", ($hdsize / (1024*1024*1024));
254
255 if ($rootdev =~ m|^/dev/|) {
256 test_read ($rootdev);
257
258 test_seektime ($rootdev, $hdsize);
259
260 }
261 }
262
263 test_fsync ($path) if $hdo_avail;
264
265 test_dns ();
266
267 exit (0);
268
269 __END__
270
271 =head1 NAME
272
273 pveperf - the Proxmox benchmark
274
275 =head1 SYNOPSIS
276
277 pveperf [PATH]
278
279 =head1 DESCRIPTION
280
281 Tries to gather some CPU/Hardisk performance data on the hardisk
282 mounted at PATH (/ is used as default)
283
284 * CPU BOGOMIPS: bogomips sum of all CPUs
285
286 * REGEX/SECOND: regular expressions per second (perl performance test), should be above 300000
287
288 * HD SIZE: harddisk size
289
290 * BUFFERED READS: simple HD read test. Modern HDs should reach
291 at least 40 MB/sec
292
293 * AVERAGE SEEK TIME: tests average seek time. Fast SCSI HDs reach values < 8 milliseconds. Common IDE/SATA disks get values from 15 to 20 ms.
294
295 * FSYNCS/SECOND: value should be greater than 200 (you should
296 enable 'write back' cache mode on you RAID controller - needs a battery
297 backed cache (BBWC)).
298
299 * DNS EXT: average time to resolve an external DNS name
300
301 * DNS INT: average time to resolve a local DNS name